mirror of
https://github.com/issadarkthing/gomu.git
synced 2025-04-26 13:49:21 +08:00
193 lines
3.2 KiB
Go
193 lines
3.2 KiB
Go
// Copyright (C) 2020 Raziman
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/gdamore/tcell"
|
|
"github.com/rivo/tview"
|
|
)
|
|
|
|
const (
|
|
musicDir = "./music"
|
|
textColor = tcell.ColorWhite
|
|
backGroundColor = tcell.ColorDarkCyan
|
|
)
|
|
|
|
type AudioFile struct {
|
|
Name string
|
|
Path string
|
|
IsAudioFile bool
|
|
Parent *tview.TreeNode
|
|
}
|
|
|
|
func Playlist(list *tview.List, playBar *Progress, player *Player) *tview.TreeView {
|
|
|
|
rootDir, err := filepath.Abs(musicDir)
|
|
|
|
if err != nil {
|
|
log(err.Error())
|
|
}
|
|
|
|
root := tview.NewTreeNode(musicDir)
|
|
|
|
tree := tview.NewTreeView().SetRoot(root)
|
|
tree.SetTitle(" Playlist ").SetBorder(true)
|
|
tree.SetGraphicsColor(tcell.ColorWhite)
|
|
|
|
var prevNode *tview.TreeNode
|
|
|
|
go func() {
|
|
|
|
populate(root, rootDir)
|
|
|
|
var firstChild *tview.TreeNode
|
|
|
|
if len(root.GetChildren()) == 0 {
|
|
firstChild = root
|
|
} else {
|
|
firstChild = root.GetChildren()[0]
|
|
}
|
|
|
|
firstChild.SetColor(textColor)
|
|
tree.SetCurrentNode(firstChild)
|
|
// keep track of prev node so we can remove the color of highlight
|
|
prevNode = firstChild.SetColor(backGroundColor)
|
|
|
|
tree.SetChangedFunc(func(node *tview.TreeNode) {
|
|
|
|
prevNode.SetColor(textColor)
|
|
root.SetColor(textColor)
|
|
node.SetColor(backGroundColor)
|
|
prevNode = node
|
|
})
|
|
|
|
}()
|
|
|
|
tree.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey {
|
|
|
|
currNode := tree.GetCurrentNode()
|
|
|
|
if currNode == root {
|
|
return e
|
|
}
|
|
audioFile := currNode.GetReference().(*AudioFile)
|
|
|
|
switch e.Rune() {
|
|
case 'l':
|
|
|
|
if audioFile.IsAudioFile {
|
|
|
|
player.Push(audioFile.Path)
|
|
|
|
if !player.IsRunning {
|
|
|
|
go func () {
|
|
player.Run()
|
|
list.AddItem("", "", 0, nil)
|
|
} ()
|
|
|
|
} else {
|
|
|
|
songLength, err := player.GetLength(len(player.queue) - 1)
|
|
|
|
if err != nil {
|
|
log(err.Error())
|
|
}
|
|
list.AddItem(
|
|
fmt.Sprintf("[ %s ] %s", fmtDuration(songLength), audioFile.Name),
|
|
"", 0, nil)
|
|
}
|
|
}
|
|
|
|
currNode.SetExpanded(true)
|
|
case 'h':
|
|
|
|
// if closing node with no children
|
|
// close the node's parent
|
|
// remove the color of the node
|
|
|
|
if audioFile.IsAudioFile {
|
|
parent := audioFile.Parent
|
|
|
|
currNode.SetColor(textColor)
|
|
parent.SetExpanded(false)
|
|
parent.SetColor(backGroundColor)
|
|
prevNode = parent
|
|
tree.SetCurrentNode(parent)
|
|
}
|
|
|
|
currNode.Collapse()
|
|
|
|
}
|
|
|
|
return e
|
|
})
|
|
|
|
tree.SetSelectedFunc(func(node *tview.TreeNode) {
|
|
node.SetExpanded(!node.IsExpanded())
|
|
})
|
|
|
|
return tree
|
|
|
|
}
|
|
|
|
func populate(root *tview.TreeNode, rootPath string) {
|
|
|
|
files, err := ioutil.ReadDir(rootPath)
|
|
|
|
if err != nil {
|
|
log(err.Error())
|
|
}
|
|
|
|
for _, file := range files {
|
|
|
|
path := filepath.Join(rootPath, file.Name())
|
|
f, err := os.Open(path)
|
|
|
|
if err != nil {
|
|
log(err.Error())
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
if !file.IsDir() {
|
|
|
|
filetype, err := GetFileContentType(f)
|
|
|
|
if err != nil {
|
|
log(err.Error())
|
|
}
|
|
|
|
// skip if not mp3 file
|
|
if filetype != "mpeg" {
|
|
continue
|
|
}
|
|
|
|
}
|
|
|
|
child := tview.NewTreeNode(file.Name())
|
|
root.AddChild(child)
|
|
|
|
audioFile := &AudioFile{
|
|
Name: file.Name(),
|
|
Path: path,
|
|
IsAudioFile: true,
|
|
Parent: root,
|
|
}
|
|
|
|
child.SetReference(audioFile)
|
|
|
|
if file.IsDir() {
|
|
audioFile.IsAudioFile = false
|
|
populate(child, path)
|
|
}
|
|
|
|
}
|
|
|
|
}
|