gomu/command.go

471 lines
9.3 KiB
Go
Raw Normal View History

package main
import (
2021-02-04 21:27:17 +08:00
"fmt"
"time"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"github.com/ztrue/tracerr"
)
type Command struct {
commands map[string]func()
}
func newCommand() Command {
return Command{
commands: make(map[string]func()),
}
}
func (c *Command) define(name string, callBack func()) {
c.commands[name] = callBack
}
func (c Command) getFn(name string) (func(), error) {
fn, ok := c.commands[name]
if !ok {
return nil, tracerr.New("command not found")
}
return fn, nil
}
func (c Command) defineCommands() {
2021-02-14 13:45:43 +08:00
anko := gomu.anko
/* Playlist */
c.define("create_playlist", func() {
name, _ := gomu.pages.GetFrontPage()
if name != "mkdir-popup" {
createPlaylistPopup()
}
})
c.define("delete_playlist", func() {
audioFile := gomu.playlist.getCurrentFile()
err := gomu.playlist.deletePlaylist(audioFile)
if err != nil {
logError(err)
}
})
c.define("delete_file", func() {
audioFile := gomu.playlist.getCurrentFile()
// prevent from deleting a directory
if !audioFile.isAudioFile {
return
}
err := gomu.playlist.deleteSong(audioFile)
if err != nil {
logError(err)
}
})
2021-02-04 21:27:17 +08:00
c.define("youtube_search", func() {
popupId := "youtube-search-input-popup"
input := newInputPopup(popupId, " Youtube Search ", "search: ", "")
2021-02-04 21:27:17 +08:00
2021-02-05 12:31:07 +08:00
// quick hack to change the autocomplete text color
tview.Styles.PrimitiveBackgroundColor = tcell.ColorBlack
input.SetAutocompleteFunc(func(currentText string) (entries []string) {
if currentText == "" {
return []string{}
}
suggestions, err := getSuggestions(currentText)
if err != nil {
logError(err)
}
return suggestions
})
2021-02-04 21:27:17 +08:00
input.SetDoneFunc(func(key tcell.Key) {
switch key {
case tcell.KeyEnter:
search := input.GetText()
defaultTimedPopup(" Youtube Search ", "Searching for "+search)
2021-02-04 21:27:17 +08:00
gomu.pages.RemovePage(popupId)
gomu.popups.pop()
go func() {
results, err := getSearchResult(search)
if err != nil {
logError(err)
defaultTimedPopup(" Error ", err.Error())
return
}
2021-02-04 21:27:17 +08:00
titles := []string{}
urls := make(map[string]string)
for _, result := range results {
duration, err := time.ParseDuration(fmt.Sprintf("%ds", result.LengthSeconds))
if err != nil {
logError(err)
return
}
durationText := fmt.Sprintf("[ %s ] ", fmtDuration(duration))
title := durationText + result.Title
urls[title] = `https://www.youtube.com/watch?v=` + result.VideoId
titles = append(titles, title)
}
searchPopup(titles, func(title string) {
audioFile := gomu.playlist.getCurrentFile()
var dir *tview.TreeNode
if audioFile.isAudioFile {
dir = audioFile.parent
} else {
dir = audioFile.node
}
go func() {
url := urls[title]
if err := ytdl(url, dir); err != nil {
logError(err)
}
gomu.playlist.refresh()
}()
gomu.app.SetFocus(gomu.prevPanel.(tview.Primitive))
})
gomu.app.Draw()
}()
2021-02-04 21:27:17 +08:00
case tcell.KeyEscape:
gomu.pages.RemovePage(popupId)
gomu.popups.pop()
gomu.app.SetFocus(gomu.prevPanel.(tview.Primitive))
2021-02-05 12:31:07 +08:00
default:
input.Autocomplete()
2021-02-04 21:27:17 +08:00
}
})
})
c.define("download_audio", func() {
audioFile := gomu.playlist.getCurrentFile()
currNode := gomu.playlist.GetCurrentNode()
if gomu.pages.HasPage("download-input-popup") {
gomu.pages.RemovePage("download-input-popup")
gomu.popups.pop()
return
}
// this ensures it downloads to
// the correct dir
if audioFile.isAudioFile {
downloadMusicPopup(audioFile.parent)
} else {
downloadMusicPopup(currNode)
}
})
c.define("add_queue", func() {
audioFile := gomu.playlist.getCurrentFile()
currNode := gomu.playlist.GetCurrentNode()
if audioFile.isAudioFile {
gomu.queue.enqueue(audioFile)
} else {
currNode.SetExpanded(true)
}
})
c.define("close_node", func() {
audioFile := gomu.playlist.getCurrentFile()
currNode := gomu.playlist.GetCurrentNode()
// if closing node with no children
// close the node's parent
// remove the color of the node
if audioFile.isAudioFile {
parent := audioFile.parent
gomu.playlist.setHighlight(parent)
parent.SetExpanded(false)
}
currNode.Collapse()
})
c.define("bulk_add", func() {
currNode := gomu.playlist.GetCurrentNode()
2021-02-14 13:45:43 +08:00
bulkAdd := anko.getBool("confirm_bulk_add")
if !bulkAdd {
gomu.playlist.addAllToQueue(currNode)
return
}
confirmationPopup(
"Are you sure to add this whole directory into queue?",
func(_ int, label string) {
if label == "yes" {
gomu.playlist.addAllToQueue(currNode)
}
})
})
c.define("refresh", func() {
gomu.playlist.refresh()
})
c.define("rename", func() {
audioFile := gomu.playlist.getCurrentFile()
renamePopup(audioFile)
})
c.define("playlist_search", func() {
files := make([]string, len(gomu.playlist.getAudioFiles()))
for i, file := range gomu.playlist.getAudioFiles() {
files[i] = file.name
}
searchPopup(files, func(text string) {
audio, err := gomu.playlist.findAudioFile(sha1Hex(text))
if err != nil {
logError(err)
}
gomu.playlist.setHighlight(audio.node)
gomu.playlist.refresh()
})
})
/* Queue */
c.define("move_down", func() {
gomu.queue.next()
})
c.define("move_up", func() {
gomu.queue.prev()
})
c.define("delete_item", func() {
gomu.queue.deleteItem(gomu.queue.GetCurrentItem())
})
c.define("clear_queue", func() {
confirmationPopup("Are you sure to clear the queue?",
func(_ int, label string) {
if label == "yes" {
gomu.queue.clearQueue()
}
})
})
c.define("play_selected", func() {
2021-02-03 10:50:01 +08:00
if gomu.queue.GetItemCount() != 0 && gomu.queue.GetCurrentItem() != -1 {
a, err := gomu.queue.deleteItem(gomu.queue.GetCurrentItem())
if err != nil {
logError(err)
}
2021-02-03 10:50:01 +08:00
gomu.queue.pushFront(a)
gomu.player.skip()
}
})
c.define("toggle_loop", func() {
gomu.queue.isLoop = gomu.player.toggleLoop()
2021-02-03 10:50:01 +08:00
gomu.queue.updateTitle()
})
c.define("shuffle_queue", func() {
gomu.queue.shuffle()
})
c.define("queue_search", func() {
queue := gomu.queue
audios := make([]string, 0, len(queue.items))
for _, file := range queue.items {
audios = append(audios, file.name)
}
searchPopup(audios, func(selected string) {
index := 0
for i, v := range queue.items {
if v.name == selected {
index = i
}
}
queue.SetCurrentItem(index)
})
})
/* Global */
c.define("quit", func() {
2021-02-14 13:45:43 +08:00
confirmOnExit := anko.getBool("confirm_on_exit")
if !confirmOnExit {
err := gomu.quit(gomu.args)
if err != nil {
logError(err)
}
}
exitConfirmation(gomu.args)
})
c.define("toggle_pause", func() {
gomu.player.togglePause()
})
c.define("volume_up", func() {
v := volToHuman(gomu.player.volume)
if v < 100 {
vol := gomu.player.setVolume(0.5)
volumePopup(vol)
}
})
c.define("volume_down", func() {
v := volToHuman(gomu.player.volume)
if v > 0 {
vol := gomu.player.setVolume(-0.5)
volumePopup(vol)
}
})
c.define("skip", func() {
gomu.player.skip()
})
c.define("toggle_help", func() {
name, _ := gomu.pages.GetFrontPage()
if name == "help-page" {
gomu.pages.RemovePage(name)
gomu.app.SetFocus(gomu.prevPanel.(tview.Primitive))
} else {
helpPopup(gomu.prevPanel)
}
})
c.define("command_search", func() {
names := make([]string, 0, len(c.commands))
for commandName := range c.commands {
names = append(names, commandName)
}
searchPopup(names, func(selected string) {
for name, fn := range c.commands {
if name == selected {
fn()
}
}
})
})
2021-01-27 01:10:48 +08:00
2021-02-03 10:50:01 +08:00
c.define("forward", func() {
if gomu.player.isRunning && !gomu.player.ctrl.Paused {
position := gomu.playingBar._progress + 10
if position < gomu.playingBar.full {
2021-02-08 01:06:21 +08:00
err := gomu.player.seek(position)
if err != nil {
logError(err)
}
2021-02-03 10:50:01 +08:00
gomu.playingBar._progress = position - 1
}
}
})
c.define("rewind", func() {
if gomu.player.isRunning && !gomu.player.ctrl.Paused {
position := gomu.playingBar._progress - 10
if position-1 > 0 {
2021-02-08 01:06:21 +08:00
err := gomu.player.seek(position)
if err != nil {
logError(err)
}
2021-02-03 10:50:01 +08:00
gomu.playingBar._progress = position - 1
} else {
2021-02-08 01:06:21 +08:00
err := gomu.player.seek(0)
if err != nil {
logError(err)
}
2021-02-03 10:50:01 +08:00
gomu.playingBar._progress = 0
}
}
})
c.define("forward_fast", func() {
if gomu.player.isRunning && !gomu.player.ctrl.Paused {
position := gomu.playingBar._progress + 60
if position < gomu.playingBar.full {
2021-02-08 01:06:21 +08:00
err := gomu.player.seek(position)
if err != nil {
logError(err)
}
2021-02-03 10:50:01 +08:00
gomu.playingBar._progress = position - 1
}
}
})
c.define("rewind_fast", func() {
if gomu.player.isRunning && !gomu.player.ctrl.Paused {
position := gomu.playingBar._progress - 60
if position-1 > 0 {
2021-02-08 01:06:21 +08:00
err := gomu.player.seek(position)
if err != nil {
logError(err)
}
2021-02-03 10:50:01 +08:00
gomu.playingBar._progress = position - 1
} else {
2021-02-08 01:06:21 +08:00
err := gomu.player.seek(0)
if err != nil {
logError(err)
}
2021-02-03 10:50:01 +08:00
gomu.playingBar._progress = 0
}
}
})
c.define("yank", func() {
err := gomu.playlist.yank()
if err != nil {
logError(err)
}
2021-02-03 10:50:01 +08:00
})
c.define("paste", func() {
err := gomu.playlist.paste()
if err != nil {
logError(err)
}
})
for name, cmd := range c.commands {
2021-02-14 13:45:43 +08:00
err := gomu.anko.define(name, cmd)
if err != nil {
2021-02-14 13:45:43 +08:00
logError(err)
}
}
}