Browse Source

Add option to disable remembering app state

master
Trevor Slocum 5 months ago
parent
commit
fd60e6b054
  1. 1
      CHANGELOG
  2. 5
      CONFIGURATION.md
  3. 7
      README.md
  4. 13
      config.go
  5. 10
      go.mod
  6. 20
      go.sum
  7. 4
      gui.go
  8. 3
      gui_key.go
  9. 17
      gui_list.go
  10. 27
      main.go

1
CHANGELOG

@ -1,5 +1,6 @@
0.1.9:
- Remember working directory, queue, playing file and position
- Add option to clear queue
0.1.8:
- Allow reordering interface elements

5
CONFIGURATION.md

@ -18,6 +18,7 @@ configuration options and their defaults.
* **Pause** Space
* **Queue** Q
* **Delete from queue** D
* **Clear queue** Ctrl+U
* **Toggle focused list** Tab
* **Browse items** J/K, Down/Up and PageDown/PageUp
* **Previous track** P
@ -35,6 +36,8 @@ layout: main,queue,playing
volume: 100
remember: true
input:
select:
- 'Enter'
@ -46,6 +49,8 @@ input:
- 'q'
delete:
- 'd'
clear-queue:
- 'Ctrl+u'
focus-next:
- 'Tab'
hidden-folders:

7
README.md

@ -3,6 +3,13 @@
Audio player
## Features
- Uses a small amount of resources
- Files are read in chunks
- Remembers playing song and queue on exit
- Supports FLAC, MP3, OGG and WAV files
## Screenshot
[![](https://ditty.rocketnine.space/static/screenshot2.png)](https://ditty.rocketnine.space/static/screenshot2.png)

13
config.go

@ -6,6 +6,7 @@ type appConfig struct {
Input map[string][]string // Keybinds
Layout string
Volume int // Starting volume
Remember bool
Dir string
QueueFiles []*LibraryEntry
QueuePlaying int
@ -13,8 +14,16 @@ type appConfig struct {
}
var config = &appConfig{
Layout: defaultLayout,
Volume: defaultVolume,
Layout: defaultLayout,
Volume: defaultVolume,
Remember: true,
}
func clearAppState() {
config.Dir = ""
config.QueueFiles = nil
config.QueuePlaying = 0
config.AudioPosition = 0
}
func saveAppState() {

10
go.mod

@ -7,7 +7,7 @@ replace github.com/faiface/beep => github.com/cswank/beep v0.0.0-20210131195430-
require (
code.rocketnine.space/tslocum/cbind v0.1.5
code.rocketnine.space/tslocum/cview v1.5.4
code.rocketnine.space/tslocum/ez v0.0.0-20210502054046-e1e0d1009c8f
code.rocketnine.space/tslocum/ez v0.0.0-20210506053631-12ed6a7c1375
github.com/dhowden/tag v0.0.0-20201120070457-d52dcb253c63
github.com/faiface/beep v1.0.2
github.com/gdamore/tcell/v2 v2.2.1
@ -16,9 +16,9 @@ require (
github.com/jfreymuth/oggvorbis v1.0.3 // indirect
github.com/mattn/go-runewidth v0.0.12
github.com/mewkiz/pkg v0.0.0-20210112042322-0b163ae15d52 // indirect
golang.org/x/exp v0.0.0-20210430132503-b698a44fee45 // indirect
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb // indirect
golang.org/x/exp v0.0.0-20210503015746-b3083d562e1d // indirect
golang.org/x/image v0.0.0-20210504121937-7319ad40d33e // indirect
golang.org/x/mobile v0.0.0-20210220033013-bdb1ca9a1e08 // indirect
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 // indirect
golang.org/x/term v0.0.0-20210429154555-c04ba851c2a4 // indirect
golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6 // indirect
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 // indirect
)

20
go.sum

@ -2,8 +2,8 @@ code.rocketnine.space/tslocum/cbind v0.1.5 h1:i6NkeLLNPNMS4NWNi3302Ay3zSU6MrqOT+
code.rocketnine.space/tslocum/cbind v0.1.5/go.mod h1:LtfqJTzM7qhg88nAvNhx+VnTjZ0SXBJtxBObbfBWo/M=
code.rocketnine.space/tslocum/cview v1.5.4 h1:zBUFAanViudrAw8ZCqNxaufqrYL6a7F1AkkIClXIzYo=
code.rocketnine.space/tslocum/cview v1.5.4/go.mod h1:JjgoZi3b528SaV923oQq14PGUCTE/g/6iggnDUxsChE=
code.rocketnine.space/tslocum/ez v0.0.0-20210502054046-e1e0d1009c8f h1:zvqqu4UY7lwNo6thsoRYeUZm9qqZ0F66diIEVhN9oDQ=
code.rocketnine.space/tslocum/ez v0.0.0-20210502054046-e1e0d1009c8f/go.mod h1:SQrM+bQ4eZdyAVTxuF2BNnyAnojHP6Kcmm2vMszoFWw=
code.rocketnine.space/tslocum/ez v0.0.0-20210506053631-12ed6a7c1375 h1:GYTFUS0slXVZ78wCAP0qh5u9ENc+5VhvyFGojnwYRA4=
code.rocketnine.space/tslocum/ez v0.0.0-20210506053631-12ed6a7c1375/go.mod h1:SQrM+bQ4eZdyAVTxuF2BNnyAnojHP6Kcmm2vMszoFWw=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@ -93,13 +93,13 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/exp v0.0.0-20210430132503-b698a44fee45 h1:XqRf5+0Xvcb6/S21xhk9fABamGZ7gSWdIPyRv2EEhBc=
golang.org/x/exp v0.0.0-20210430132503-b698a44fee45/go.mod h1:cJRhTyGheUtAt9+V1LK3LYoFneBlmiX5bePSkB17RVE=
golang.org/x/exp v0.0.0-20210503015746-b3083d562e1d h1:GVdk3fETn7OIrVsO9oikNOn5qWu8EcgkTtcDD9IGyQ4=
golang.org/x/exp v0.0.0-20210503015746-b3083d562e1d/go.mod h1:MSdmUWF4ZWBPSUbgUX/gaau5kvnbkSs9pgtY6B9JXDE=
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb h1:fqpd0EBDzlHRCjiphRR5Zo/RSWWQlWv34418dnEixWk=
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210504121937-7319ad40d33e h1:PzJMNfFQx+QO9hrC1GwZ4BoPGeNGhfeQEgcQFArEjPk=
golang.org/x/image v0.0.0-20210504121937-7319ad40d33e/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
@ -130,13 +130,13 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210309040221-94ec62e08169/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6 h1:cdsMqa2nXzqlgs183pHxtvoVwU7CyzaCTAUOg94af4c=
golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210317153231-de623e64d2a6/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210429154555-c04ba851c2a4 h1:UPou2i3GzKgi6igR+/0C5XyHKBngHxBp/CL5CQ0p3Zk=
golang.org/x/term v0.0.0-20210429154555-c04ba851c2a4/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w=
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=

4
gui.go

@ -39,8 +39,8 @@ var (
mainLock = new(sync.Mutex)
queueFiles []*LibraryEntry
queueCursor = -1
queuePlaying int
queueCursor = -1 // Focused entry
queuePlaying int // Playing entry
queueBuffer bytes.Buffer
queueLock = new(sync.Mutex)

3
gui_key.go

@ -14,6 +14,7 @@ const (
actionRefresh = "refresh"
actionQueue = "queue"
actionDelete = "delete"
actionClearQueue = "clear-queue"
actionFocusNext = "focus-next"
actionToggleHidden = "hidden-folders"
actionBrowseParent = "browse-parent"
@ -35,6 +36,7 @@ var actionHandlers = map[string]func(){
actionRefresh: listRefresh,
actionQueue: listQueue,
actionDelete: listDelete,
actionClearQueue: clearQueue,
actionFocusNext: toggleFocusedList,
actionToggleHidden: listToggleHidden,
actionBrowseParent: browseParent,
@ -95,6 +97,7 @@ func setDefaultKeyBinds() {
actionRefresh: {"r"},
actionQueue: {"q"},
actionDelete: {"d"},
actionClearQueue: {"Ctrl+u"},
actionFocusNext: {"Tab"},
actionToggleHidden: {"."},
actionBrowseParent: {"Backspace"},

17
gui_list.go

@ -159,6 +159,23 @@ func listDelete() {
go app.QueueUpdateDraw(updateQueue)
}
func clearQueue() {
queueLock.Lock()
defer queueLock.Unlock()
if len(queueFiles) > queuePlaying {
queueFiles = []*LibraryEntry{queueFiles[queuePlaying]}
} else {
queueFiles = nil
}
queuePlaying = 0
app.QueueUpdateDraw(func() {
queueList.SetCurrentItem(0)
updateQueue()
})
}
func selectedMainEntry() *LibraryEntry {
cursor := mainList.GetCurrentItemIndex()
if cursor < 0 || cursor-1 > len(mainFiles) {

27
main.go

@ -98,8 +98,15 @@ func main() {
defer pprof.StopCPUProfile()
}
ez.SetAppName("ditty")
err := ez.ReadConfig(config, configPath)
if configPath == "" {
var err error
configPath, err = ez.DefaultConfigPath("ditty")
if err != nil {
log.Fatalf("failed to determine default configuration file path: %s", err)
}
}
err := ez.Deserialize(config, configPath)
if err != nil {
log.Fatalf("failed to read configuration file: %s", err)
}
@ -150,10 +157,10 @@ func main() {
startPath := strings.Join(flag.Args(), " ")
if startPath == "" {
if config.Dir != "" {
startPath = config.Dir
} else if restrictLibrary != "" {
if restrictLibrary != "" {
startPath = restrictLibrary
} else if config.Remember && config.Dir != "" {
startPath = config.Dir
} else {
wd, err := os.Getwd()
if err != nil || wd == "" {
@ -190,7 +197,7 @@ func main() {
}
}
if config.QueueFiles != nil {
if config.Remember && config.QueueFiles != nil {
queueFiles = config.QueueFiles
app.QueueUpdateDraw(func() {
updateQueue()
@ -213,8 +220,12 @@ func main() {
for {
select {
case <-done:
saveAppState()
ez.SaveConfig(config, configPath) // Failing isn't an issue, this could be logged though
if config.Remember {
saveAppState()
} else {
clearAppState()
}
ez.Serialize(config, configPath) // Failing isn't an issue, this could be logged though
if streamFd != nil {
streamFd.Close()

Loading…
Cancel
Save