Skip to content

Commit

Permalink
feat: play notification sound when pomodoro ends (#14)
Browse files Browse the repository at this point in the history
* feat: play notification sound when pomodoro ends

* fix(build): add libasound2-dev dep when building

* chore(release): add deb and rpm dependencies

* ci: cancel previous runs of workflow if new one is run

* ci: cancel previous runs of workflow if new one is run (codeql)

* feat: play notification sound on pomodoro end

* doc: add credit for notification sound

* doc: describe how to override the notification sound

* feat: wrap errors instead of log.Fatal
  • Loading branch information
tomsquest authored Apr 22, 2022
1 parent 9e801b9 commit e153c83
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 6 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
name: build
on: push
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Dev dependencies
run: sudo apt-get update && sudo apt-get install gcc libgl1-mesa-dev libegl1-mesa-dev libgles2-mesa-dev libx11-dev xorg-dev
run: sudo apt-get update && sudo apt-get install gcc libgl1-mesa-dev libegl1-mesa-dev libgles2-mesa-dev libx11-dev xorg-dev libasound2-dev
- uses: WillAbides/setup-go-faster@v1.7.0
with:
go-version: '1.17.x'
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/codeql-analysis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ on:
schedule:
- cron: '16 18 * * 3'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
analyze:
name: Analyze
Expand Down
14 changes: 14 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ gomod:
builds:
- targets:
- linux_amd64
env:
# Required by oto (sound library)
- CGO_ENABLED=1
# Reproducible build
# https://goreleaser.com/customization/build/#reproducible-builds
mod_timestamp: '{{ .CommitTimestamp }}'
Expand Down Expand Up @@ -40,6 +43,17 @@ nfpms:
dst: /usr/share/pixmaps/fynodoro.png
- src: assets/fynodoro.desktop
dst: /usr/local/share/applications/fynodoro.desktop
- src: assets/notification.mp3
dst: /usr/share/fynodoro/notification.mp3
overrides:
deb:
dependencies:
# Required by oto (sound library)
- libasound2-dev
rpm:
dependencies:
# Required by oto (sound library)
- alsa-lib-devel
release:
draft: true
footer: |
Expand Down
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
- [Timer](#timer)
- [Settings](#settings)
- [Features](#features)
- [Configuration](#configuration)
- [Changelog](#changelog)
- [Configuration](#configuration)
- [Notification sound](#notification-sound)
- [Install](#install)
- [Install Ubuntu/Debian (.deb)](#install-ubuntudebian-deb)
- [Install Fedora/Redhat (.rpm)](#install-fedoraredhat-rpm)
Expand Down Expand Up @@ -49,6 +50,10 @@
- 🏆 Small download size
- 💼 Releases for Ubuntu/Debian, Fedora/Redhat, and as linux binary

## Changelog

See the [Releases](https://github.com/tomsquest/fynodoro/releases) section on GitHub.

## Configuration

The Pomodoro technique defaults to 4 work rounds of 25 minutes, with a 5 minutes pause ("short break") in-between and a final 15 minutes pause (the "long" break), for a total of 2 hours (4x25m Work + 3x5m Short breaks + 1x15m Long break).
Expand All @@ -66,9 +71,10 @@ You can **disable** Short breaks by setting the duration of Short breaks to `0`.

Tips: you can **disable** both Short and Long breaks by setting them to `0`. The timer will then act as a ticker, notifying you after each Work period.

## Changelog
### Notification sound

See the [Releases](https://github.com/tomsquest/fynodoro/releases) section.
The notification sound is stored in: `/usr/share/fynodoro/notification.mp3`.
You can override it if you wish with another **mp3** file.

## Install

Expand Down Expand Up @@ -125,10 +131,11 @@ TAG=v1.0.0 && git tag $TAG && git push origin $TAG
## TODO

- [ ] Pico/Nano/Normal UI
- [ ] Tons of options (run script on pomodoro end, notification sound, ...)
- [ ] Tons of options (run script on pomodoro end, notification sound on/off, ...)
- [ ] Release Windows, macOS, Android, IOS versions

## Credits

- Icon made by [Freepik](https://www.freepik.com) from [Flaticon](https://www.flaticon.com/free-icon/tomato_877814)
- Screenshot pimped with [PrettySnap](https://prettysnap.app)
- Notification sound from [Zedge](https://www.zedge.net/ringtones)
Binary file added assets/notification.mp3
Binary file not shown.
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ require (
github.com/benbjohnson/clock v1.3.0
github.com/gen2brain/beeep v0.0.0-20210529141713-5586760f0cc1
github.com/godbus/dbus/v5 v5.0.6 // indirect
github.com/hajimehoshi/go-mp3 v0.3.0
github.com/hajimehoshi/oto v0.7.1
github.com/stretchr/testify v1.7.0
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect
golang.org/x/text v0.3.5 // indirect
Expand All @@ -29,6 +31,8 @@ require (
github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9 // indirect
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect
github.com/yuin/goldmark v1.3.8 // indirect
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8 // indirect
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 // indirect
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6 // indirect
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
)
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c h1:16eHWuMGvCjSf
github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherwasm v1.1.0 h1:fA2uLoctU5+T3OhOn2vYP0DVT6pxc7xhTlBB1paATqQ=
github.com/gopherjs/gopherwasm v1.1.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWGR/8nMhyhZSI=
github.com/hajimehoshi/go-mp3 v0.3.0 h1:fTM5DXjp/DL2G74HHAs/aBGiS9Tg7wnp+jkU38bHy4g=
github.com/hajimehoshi/go-mp3 v0.3.0/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
github.com/hajimehoshi/oto v0.7.1 h1:I7maFPz5MBCwiutOrz++DLdbr4rTzBsbBuV2VpgU9kk=
github.com/hajimehoshi/oto v0.7.1/go.mod h1:wovJ8WWMfFKvP587mhHgot/MBr4DnNy9m6EepeVGnos=
github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc=
github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
Expand Down Expand Up @@ -69,8 +74,13 @@ github.com/yuin/goldmark v1.3.8 h1:Nw158Q8QN+CPgTmVRByhVwapp8Mm1e2blinhmx4wx5E=
github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8 h1:idBdZTd9UioThJp8KpM/rTSinK/ChZFBE43/WtIy8zg=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw=
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6 h1:vyLBGJPIl9ZYbcQFM2USFmJBK6KI+t+z6jL0lbwjrnc=
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
Expand All @@ -79,7 +89,9 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
11 changes: 10 additions & 1 deletion ui/notify.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,19 @@ import (
"fmt"
"github.com/gen2brain/beeep"
"github.com/tomsquest/fynodoro/pomodoro"
"log"
)

func notifyPomodoroDone(kind pomodoro.Kind) {
title := fmt.Sprintf("%s done", kind)
message := fmt.Sprintf("You just finished a %s pomodoro.", kind)
_ = beeep.Notify(title, message, "/usr/share/pixmaps/fynodoro.png")
err := beeep.Notify(title, message, "/usr/share/pixmaps/fynodoro.png")
if err != nil {
log.Printf("unable to notify: %v\n", err)
}

err = playNotificationSound()
if err != nil {
log.Printf("unable to play notification sound: %v\n", err)
}
}
47 changes: 47 additions & 0 deletions ui/playback.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package ui

import (
"fmt"
"github.com/hajimehoshi/go-mp3"
"github.com/hajimehoshi/oto"
"io"
"os"
"sync"
)

var once sync.Once
var context *oto.Context

func playNotificationSound() error {
fileName := "/usr/share/fynodoro/notification.mp3"
f, err := os.Open(fileName)
if err != nil {
return fmt.Errorf("unable to read %s: %w", fileName, err)
}

decoder, err := mp3.NewDecoder(f)
if err != nil {
return fmt.Errorf("unable to decode %s: %w", fileName, err)
}

once.Do(func() {
context, err = oto.NewContext(decoder.SampleRate(), 2, 2, 8192)
})
if err != nil {
return fmt.Errorf("unable to create oto context: %w", err)
}

go func() {
player := context.NewPlayer()
defer func() {
err = player.Close()
}()

_, err = io.Copy(player, decoder)
}()
if err != nil {
return fmt.Errorf("unable to play: %w", err)
}

return nil
}

0 comments on commit e153c83

Please sign in to comment.