Initial Implementation of Views

This commit is contained in:
aditya-K2 2022-08-31 23:42:15 +05:30
parent e86ceaca6a
commit ff74bf02ba
11 changed files with 488 additions and 333 deletions

Binary file not shown.

View File

@ -18,14 +18,14 @@ var (
WHITE_AND_BOLD string = "[white::b]" WHITE_AND_BOLD string = "[white::b]"
) )
func SetConnection(c *mpd.Client) {
CONN = c
}
func SetNotificationServer(n interface{ Send(string) }) { func SetNotificationServer(n interface{ Send(string) }) {
NotificationServer = n NotificationServer = n
} }
func SetConnection(c *mpd.Client) {
CONN = c
}
func TogglePlayBack() error { func TogglePlayBack() error {
status, err := CONN.Status() status, err := CONN.Status()
if status["state"] == "play" && err == nil { if status["state"] == "play" && err == nil {

View File

@ -1,140 +0,0 @@
package client
import (
"strings"
"github.com/aditya-K2/fuzzy"
"github.com/aditya-K2/gomp/utils"
"github.com/aditya-K2/tview"
"github.com/gdamore/tcell/v2"
)
func GetCell(text string, foreground tcell.Color, bold bool) *tview.TableCell {
return tview.NewTableCell(text).
SetAlign(tview.AlignLeft).
SetStyle(tcell.StyleDefault.
Foreground(foreground).
Background(tcell.ColorBlack).
Bold(bold))
}
func UpdateBuffSearchView(inputTable *tview.Table, m fuzzy.Matches, f []FileNode) {
inputTable.Clear()
if m == nil || len(m) == 0 {
Update(f, inputTable)
} else {
for k, v := range m {
if len(f[v.Index].Children) != 0 {
inputTable.SetCell(k, 0,
GetCell(
utils.GetMatchedString(
utils.Unique(v.MatchedIndexes), f[v.Index].Path, "[blue:-:bi]"),
tcell.ColorYellow, true))
} else {
inputTable.SetCell(k, 0,
GetCell(
utils.GetMatchedString(
utils.Unique(v.MatchedIndexes), f[v.Index].Title, "[yellow:-:bi]"),
tcell.ColorGreen, true))
}
if k == 15 {
break
}
}
}
}
func UpdatePlaylist(inputTable *tview.Table) {
_playlistAttr, _ := CONN.PlaylistInfo(-1, -1)
inputTable.Clear()
for i, j := range _playlistAttr {
_, _, w, _ := inputTable.GetInnerRect()
if j["Title"] == "" || j["Artist"] == "" || j["Album"] == "" {
inputTable.SetCell(i, 0,
GetCell(
utils.GetFormattedString(j["file"], w/3), tcell.ColorBlue, true))
} else {
inputTable.SetCell(i, 0,
GetCell(
utils.GetFormattedString(j["Title"], w/3), tcell.ColorGreen, false))
inputTable.SetCell(i, 1,
GetCell(
utils.GetFormattedString(j["Artist"], w/3), tcell.ColorPurple, false))
inputTable.SetCell(i, 2,
GetCell(j["Album"], tcell.ColorYellow, false))
}
}
}
// UpdateSearchView as the name suggests Updates the Search View the idea is to basically keep a fourth option called
// Search in the Navigation bar which will render things from a global ContentSlice at least in the context of the main
// function this will also help in persisting the Search Results.
func UpdateSearchView(inputTable *tview.Table, c []interface{}) {
inputTable.Clear()
_, _, width, _ := inputTable.GetInnerRect()
for i, content := range c {
switch content.(type) {
case [3]string:
{
inputTable.SetCell(i, 0,
GetCell(
utils.GetFormattedString(content.([3]string)[0], width/3), tcell.ColorGreen, false))
inputTable.SetCell(i, 1,
GetCell(
utils.GetFormattedString(content.([3]string)[1], width/3), tcell.ColorPurple, false))
inputTable.SetCell(i, 2,
GetCell(content.([3]string)[2], tcell.ColorYellow, false))
}
case [2]string:
{
inputTable.SetCell(i, 0,
GetCell(
utils.GetFormattedString(content.([2]string)[0], width/3), tcell.ColorYellow, false))
inputTable.SetCell(i, 1,
GetCell(
utils.GetFormattedString(content.([2]string)[1], width/3), tcell.ColorPurple, false))
}
case string:
{
b := content.(string)
if !strings.HasPrefix(b, WHITE_AND_BOLD) {
inputTable.SetCell(i, 0,
GetCell(content.(string), tcell.ColorPurple, false))
} else {
inputTable.SetCell(i, 0,
GetCell(content.(string), tcell.ColorWhite, true).SetSelectable(false))
}
}
}
}
}
func Update(f []FileNode, inputTable *tview.Table) {
inputTable.Clear()
for i, j := range f {
if len(j.Children) == 0 {
_songAttributes, err := CONN.ListAllInfo(j.AbsolutePath)
if err == nil && _songAttributes[0]["Title"] != "" {
_, _, w, _ := inputTable.GetInnerRect()
inputTable.SetCell(i, 0,
GetCell(
utils.GetFormattedString(_songAttributes[0]["Title"], w/3), tcell.ColorGreen, false))
inputTable.SetCell(i, 1,
GetCell(
utils.GetFormattedString(_songAttributes[0]["Artist"], w/3), tcell.ColorPurple, false))
inputTable.SetCell(i, 2,
GetCell(_songAttributes[0]["Album"], tcell.ColorYellow, false))
} else if _songAttributes[0]["Title"] == "" {
inputTable.SetCell(i, 0,
GetCell(j.Path, tcell.ColorBlue, true))
}
} else {
inputTable.SetCell(i, 0,
GetCell(j.Path, tcell.ColorYellow, true))
}
}
}

20
globals/globals.go Normal file
View File

@ -0,0 +1,20 @@
package globals
import (
"github.com/aditya-K2/fuzzy"
"github.com/aditya-K2/gomp/client"
"github.com/aditya-K2/gomp/notify"
"github.com/aditya-K2/gomp/render"
"github.com/aditya-K2/gomp/ui"
"github.com/fhs/gompd/mpd"
)
var (
Conn *mpd.Client
Notify *notify.NotificationServer
Renderer *render.Renderer
Ui *ui.Application
DirTree *client.FileNode
SearchContentSlice []interface{}
Matches fuzzy.Matches
)

230
main.go
View File

@ -1,17 +1,18 @@
package main package main
import ( import (
"fmt"
"strconv" "strconv"
"time" "time"
"github.com/aditya-K2/gomp/cache" "github.com/aditya-K2/gomp/cache"
"github.com/aditya-K2/gomp/client" "github.com/aditya-K2/gomp/client"
"github.com/aditya-K2/gomp/config" "github.com/aditya-K2/gomp/config"
"github.com/aditya-K2/gomp/globals"
"github.com/aditya-K2/gomp/notify" "github.com/aditya-K2/gomp/notify"
"github.com/aditya-K2/gomp/render" "github.com/aditya-K2/gomp/render"
"github.com/aditya-K2/gomp/ui" "github.com/aditya-K2/gomp/ui"
"github.com/aditya-K2/gomp/utils" "github.com/aditya-K2/gomp/utils"
"github.com/aditya-K2/gomp/views"
"github.com/aditya-K2/fuzzy" "github.com/aditya-K2/fuzzy"
"github.com/fhs/gompd/mpd" "github.com/fhs/gompd/mpd"
@ -30,31 +31,30 @@ func main() {
} else if nt == "unix" && port != "" { } else if nt == "unix" && port != "" {
port = "" port = ""
} }
CONN, mpdConnectionError := mpd.Dial(nt, globals.Conn, mpdConnectionError = mpd.Dial(nt,
viper.GetString("NETWORK_ADDRESS")+del+port) viper.GetString("NETWORK_ADDRESS")+del+port)
if mpdConnectionError != nil { if mpdConnectionError != nil {
utils.Print("RED", "Could Not Connect to MPD Server\n") utils.Print("RED", "Could Not Connect to MPD Server\n")
utils.Print("GREEN", "Make Sure You Mention the Correct MPD Port in the config file.\n") utils.Print("GREEN", "Make Sure You Mention the Correct MPD Port in the config file.\n")
panic(mpdConnectionError) panic(mpdConnectionError)
} }
CONN := globals.Conn
defer CONN.Close() defer CONN.Close()
ui.GenerateFocusMap()
client.SetConnection(CONN) client.SetConnection(CONN)
ui.SetConnection(CONN) ui.SetConnection(CONN)
render.SetConnection(CONN) render.SetConnection(CONN)
cache.SetCacheDir(viper.GetString("CACHE_DIR")) cache.SetCacheDir(viper.GetString("CACHE_DIR"))
Renderer := render.NewRenderer() globals.Renderer = render.NewRenderer()
// Connecting the Renderer to the Main UI // Connecting the Renderer to the Main UI
ui.ConnectRenderer(Renderer) ui.ConnectRenderer(globals.Renderer)
UI := ui.NewApplication() globals.Ui = ui.NewApplication()
// Connecting the Notification Server to the Main UI // Connecting the Notification Server to the Main UI
notify.ConnectUI(UI) notify.ConnectUI(globals.Ui)
fileMap, err := CONN.ListAllInfo("/") fileMap, err := CONN.ListAllInfo("/")
if err != nil { if err != nil {
@ -64,10 +64,10 @@ func main() {
} }
// Generating the Directory Tree for File Navigation. // Generating the Directory Tree for File Navigation.
dirTree := client.GenerateDirectoryTree(fileMap) globals.DirTree = client.GenerateDirectoryTree(fileMap)
// Default View upon Opening is of Playlist. // Default View upon Opening is of Playlist.
client.UpdatePlaylist(UI.ExpandedView) views.PView.Update(globals.Ui.ExpandedView)
var Volume int64 var Volume int64
var Random, Repeat bool var Random, Repeat bool
@ -100,9 +100,9 @@ func main() {
panic(err) panic(err)
} else { } else {
if len(c) != 0 { if len(c) != 0 {
Renderer.Start(c["file"]) globals.Renderer.Start(c["file"])
} else { } else {
Renderer.Start("stop") globals.Renderer.Start("stop")
} }
} }
@ -110,23 +110,12 @@ func main() {
client.SetNotificationServer(Notify) client.SetNotificationServer(Notify)
render.SetNotificationServer(Notify) render.SetNotificationServer(Notify)
// This is the Slice that is used to Display Content in the SearchView
var SearchContentSlice []interface{}
var Matches fuzzy.Matches
// This Function Is Responsible for Changing the Focus it uses the Focus Map and Based on it Chooses // This Function Is Responsible for Changing the Focus it uses the Focus Map and Based on it Chooses
// the Draw Function // the Draw Function
UI.ExpandedView.SetDrawFunc(func(s tcell.Screen, x, y, width, height int) (int, int, int, int) { views.SetCurrentView(views.PView)
if ui.HasFocus("Playlist") { globals.Ui.ExpandedView.SetDrawFunc(func(s tcell.Screen, x, y, width, height int) (int, int, int, int) {
client.UpdatePlaylist(UI.ExpandedView) views.GetCurrentView().Update(globals.Ui.ExpandedView)
} else if ui.HasFocus("SearchView") { return globals.Ui.ExpandedView.GetInnerRect()
client.UpdateSearchView(UI.ExpandedView, SearchContentSlice)
} else if ui.HasFocus("FileBrowser") {
client.Update(dirTree.Children, UI.ExpandedView)
} else if ui.HasFocus("BuffSearchView") {
client.UpdateBuffSearchView(UI.ExpandedView, Matches, dirTree.Children)
}
return UI.ExpandedView.GetInnerRect()
}) })
// Function Maps is used For Mapping Keys According to the Value mapped to the Key the respective Function is called // Function Maps is used For Mapping Keys According to the Value mapped to the Key the respective Function is called
@ -134,52 +123,7 @@ func main() {
// the respective function in this case togglePlayBack is called. // the respective function in this case togglePlayBack is called.
var FuncMap = map[string]func(){ var FuncMap = map[string]func(){
"showChildrenContent": func() { "showChildrenContent": func() {
if ui.HasFocus("FileBrowser") { views.GetCurrentView().ShowChildrenContent()
r, _ := UI.ExpandedView.GetSelection()
ui.SetFocus("FileBrowser")
if len(dirTree.Children[r].Children) == 0 {
if id, err := CONN.AddId(dirTree.Children[r].AbsolutePath, -1); err != nil {
Notify.Send(fmt.Sprintf("Could not Add Song %s",
dirTree.Children[r].Path))
} else {
if err := CONN.PlayId(id); err != nil {
Notify.Send(fmt.Sprintf("Could Not Play Song %s",
dirTree.Children[r].Path))
}
}
} else {
client.Update(dirTree.Children[r].Children, UI.ExpandedView)
dirTree = &dirTree.Children[r]
UI.ExpandedView.Select(0, 0)
}
} else if ui.HasFocus("Playlist") {
r, _ := UI.ExpandedView.GetSelection()
if err := CONN.Play(r); err != nil {
Notify.Send("Could Not Play the Song")
}
} else if ui.HasFocus("SearchView") {
r, _ := UI.ExpandedView.GetSelection()
client.AddToPlaylist(SearchContentSlice[r], true)
} else if ui.HasFocus("BuffSearchView") {
r, _ := UI.ExpandedView.GetSelection()
ui.SetFocus("FileBrowser")
if len(dirTree.Children[r].Children) == 0 {
if id, err := CONN.AddId(dirTree.Children[Matches[r].Index].AbsolutePath, -1); err != nil {
Notify.Send(fmt.Sprintf("Could Not add the Song %s to the Playlist",
dirTree.Children[Matches[r].Index].AbsolutePath))
} else {
if err := CONN.PlayId(id); err != nil {
Notify.Send("Could not Play the Song")
}
}
} else {
client.Update(dirTree.Children[Matches[r].Index].Children, UI.ExpandedView)
dirTree = &dirTree.Children[Matches[r].Index]
}
UI.SearchBar.SetText("")
// Resetting Matches
Matches = nil
}
}, },
"togglePlayBack": func() { "togglePlayBack": func() {
if err := client.TogglePlayBack(); err != nil { if err := client.TogglePlayBack(); err != nil {
@ -187,15 +131,7 @@ func main() {
} }
}, },
"showParentContent": func() { "showParentContent": func() {
if ui.HasFocus("FileBrowser") { views.GetCurrentView().ShowParentContent()
if dirTree.Parent != nil {
client.Update(dirTree.Parent.Children, UI.ExpandedView)
dirTree = dirTree.Parent
}
} else {
Notify.Send("Not Allowed in this View")
return
}
}, },
"nextSong": func() { "nextSong": func() {
if err := CONN.Next(); err != nil { if err := CONN.Next(); err != nil {
@ -215,27 +151,7 @@ func main() {
} }
}, },
"addToPlaylist": func() { "addToPlaylist": func() {
if ui.HasFocus("FileBrowser") { views.GetCurrentView().AddToPlaylist()
r, _ := UI.ExpandedView.GetSelection()
if err := CONN.Add(dirTree.Children[r].AbsolutePath); err != nil {
Notify.Send(fmt.Sprintf("Could not add %s to the Playlist",
dirTree.Children[r].Path))
}
} else if ui.HasFocus("SearchView") {
r, _ := UI.ExpandedView.GetSelection()
client.AddToPlaylist(SearchContentSlice[r], false)
} else if ui.HasFocus("BuffSearchView") {
r, _ := UI.ExpandedView.GetSelection()
if err := CONN.Add(dirTree.Children[Matches[r].Index].AbsolutePath); err != nil {
Notify.Send(fmt.Sprintf("Could Not Add URI %s to the Playlist",
dirTree.Children[Matches[r].Index].Path))
} else {
ui.SetFocus("FileBrowser")
Notify.Send(fmt.Sprintf("URI Added %s to the Playlist",
dirTree.Children[Matches[r].Index].Path))
ui.SetFocus("BuffSearchView")
}
}
}, },
"toggleRandom": func() { "toggleRandom": func() {
if err := CONN.Random(!Random); err == nil { if err := CONN.Random(!Random); err == nil {
@ -268,30 +184,25 @@ func main() {
} }
}, },
"navigateToFiles": func() { "navigateToFiles": func() {
ui.SetFocus("FileBrowser") views.SetCurrentView(views.FView)
UI.Navbar.Select(1, 0) globals.Ui.Navbar.Select(1, 0)
client.Update(dirTree.Children, UI.ExpandedView) views.FView.Update(globals.Ui.ExpandedView)
}, },
"navigateToPlaylist": func() { "navigateToPlaylist": func() {
ui.SetFocus("Playlist") views.SetCurrentView(views.PView)
UI.Navbar.Select(0, 0) globals.Ui.Navbar.Select(0, 0)
client.UpdatePlaylist(UI.ExpandedView) views.PView.Update(globals.Ui.ExpandedView)
}, },
"navigateToMostPlayed": func() { "navigateToMostPlayed": func() {
UI.Navbar.Select(2, 0) globals.Ui.Navbar.Select(2, 0)
}, },
"navigateToSearch": func() { "navigateToSearch": func() {
ui.SetFocus("SearchView") views.SetCurrentView(views.SView)
UI.Navbar.Select(3, 0) globals.Ui.Navbar.Select(3, 0)
views.SView.Update(globals.Ui.ExpandedView)
}, },
"quit": func() { "quit": func() {
if ui.HasFocus("BuffSearchView") { views.GetCurrentView().Quit()
ui.SetFocus("FileBrowser")
UI.SearchBar.SetText("")
Matches = nil
} else {
UI.App.Stop()
}
}, },
"stop": func() { "stop": func() {
if err := CONN.Stop(); err != nil { if err := CONN.Stop(); err != nil {
@ -309,21 +220,13 @@ func main() {
} }
}, },
"deleteSongFromPlaylist": func() { "deleteSongFromPlaylist": func() {
if ui.HasFocus("Playlist") { views.GetCurrentView().DeleteSongFromPlaylist()
r, _ := UI.ExpandedView.GetSelection()
if err := CONN.Delete(r, -1); err != nil {
Notify.Send("Could not Remove the Song from Playlist")
}
}
}, },
"FocusSearch": func() { "FocusSearch": func() {
UI.App.SetFocus(UI.SearchBar) globals.Ui.App.SetFocus(globals.Ui.SearchBar)
}, },
"FocusBuffSearch": func() { "FocusBuffSearch": func() {
if ui.HasFocus("FileBrowser") || ui.HasFocus("BuffSearchView") { views.GetCurrentView().FocusBuffSearchView()
ui.SetFocus("BuffSearchView")
UI.App.SetFocus(UI.SearchBar)
}
}, },
} }
@ -332,12 +235,12 @@ func main() {
// for each event T, P, SPACE mapped to the same function togglePlayBack // for each event T, P, SPACE mapped to the same function togglePlayBack
config.GenerateKeyMap(FuncMap) config.GenerateKeyMap(FuncMap)
UI.SearchBar.SetAutocompleteFunc(func(c string) []string { globals.Ui.SearchBar.SetAutocompleteFunc(func(c string) []string {
if ui.HasFocus("BuffSearchView") { if views.GetCurrentView().GetViewName() == "BuffSearchView" {
return nil return nil
} else { } else {
if c != "" && c != " " && c != " " { if c != "" && c != " " && c != " " {
_, _, w, _ := UI.SearchBar.GetRect() _, _, w, _ := globals.Ui.SearchBar.GetRect()
matches := fuzzy.Find(c, ArtistTreeContent) matches := fuzzy.Find(c, ArtistTreeContent)
var suggestions []string var suggestions []string
for i, match := range matches { for i, match := range matches {
@ -354,12 +257,12 @@ func main() {
}) })
// Input Handler // Input Handler
UI.ExpandedView.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey { globals.Ui.ExpandedView.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey {
if val, ok := config.KEY_MAP[int(e.Rune())]; ok { if val, ok := config.KEY_MAP[int(e.Rune())]; ok {
FuncMap[val]() FuncMap[val]()
return nil return nil
} else { } else {
if ui.HasFocus("Playlist") { if views.GetCurrentView().GetViewName() == "PlaylistView" {
if e.Rune() == 'j' || e.Rune() == 'k' { if e.Rune() == 'j' || e.Rune() == 'k' {
if p, err := CONN.PlaylistInfo(-1, -1); err != nil { if p, err := CONN.PlaylistInfo(-1, -1); err != nil {
Notify.Send("Error Getting PlaylistInfo") Notify.Send("Error Getting PlaylistInfo")
@ -375,62 +278,61 @@ func main() {
} }
}) })
UI.SearchBar.SetDoneFunc(func(e tcell.Key) { globals.Ui.SearchBar.SetDoneFunc(func(e tcell.Key) {
if e == tcell.KeyEnter { if e == tcell.KeyEnter {
UI.ExpandedView.Select(0, 0) globals.Ui.ExpandedView.Select(0, 0)
if ui.HasFocus("BuffSearchView") { if views.GetCurrentView().GetViewName() == "BuffSearchView" {
UI.App.SetFocus(UI.ExpandedView) globals.Ui.App.SetFocus(globals.Ui.ExpandedView)
} else { } else {
ui.SetFocus("SearchView") views.SetCurrentView(views.SView)
SearchContentSlice = nil globals.SearchContentSlice = nil
SearchContentSlice, err = client.GenerateContentSlice(UI.SearchBar.GetText()) globals.SearchContentSlice, err = client.GenerateContentSlice(globals.Ui.SearchBar.GetText())
if err != nil { if err != nil {
Notify.Send("Could Not Retrieve the Results") Notify.Send("Could Not Retrieve the Results")
} else { } else {
UI.SearchBar.SetText("") globals.Ui.SearchBar.SetText("")
UI.App.SetFocus(UI.ExpandedView) globals.Ui.App.SetFocus(globals.Ui.ExpandedView)
UI.Navbar.Select(3, 0) globals.Ui.Navbar.Select(3, 0)
} }
} }
} }
if e == tcell.KeyEscape { if e == tcell.KeyEscape {
if ui.HasFocus("SearchView") { if views.GetCurrentView().GetViewName() == "SearchView" {
ui.FocusMap["SearchView"] = false } else if views.GetCurrentView().GetViewName() == "BuffSearchView" {
} else if ui.HasFocus("BuffSearchView") { views.SetCurrentView(views.FView)
ui.SetFocus("FileBrowser") globals.Matches = nil
Matches = nil
} }
UI.SearchBar.SetText("") globals.Ui.SearchBar.SetText("")
UI.App.SetFocus(UI.ExpandedView) globals.Ui.App.SetFocus(globals.Ui.ExpandedView)
} }
}) })
UI.ExpandedView.SetDoneFunc(func(e tcell.Key) { globals.Ui.ExpandedView.SetDoneFunc(func(e tcell.Key) {
if e == tcell.KeyEscape { if e == tcell.KeyEscape {
if ui.HasFocus("BuffSearchView") { if views.GetCurrentView().GetViewName() == "BuffSearchView" {
ui.SetFocus("FileBrowser") views.SetCurrentView(views.FView)
UI.SearchBar.SetText("") globals.Ui.SearchBar.SetText("")
Matches = nil globals.Matches = nil
} }
} }
}) })
UI.SearchBar.SetChangedFunc(func(text string) { globals.Ui.SearchBar.SetChangedFunc(func(text string) {
if ui.HasFocus("BuffSearchView") { if views.GetCurrentView().GetViewName() == "BuffSearchView" {
var f client.FileNodes = dirTree.Children var f client.FileNodes = globals.DirTree.Children
Matches = fuzzy.FindFrom(text, f) globals.Matches = fuzzy.FindFrom(text, f)
client.UpdateBuffSearchView(UI.ExpandedView, Matches, dirTree.Children) views.BuffSView.Update(globals.Ui.ExpandedView)
} }
}) })
go func() { go func() {
for { for {
UI.App.Draw() globals.Ui.App.Draw()
time.Sleep(time.Second) time.Sleep(time.Second)
} }
}() }()
if err := UI.App.Run(); err != nil { if err := globals.Ui.App.Run(); err != nil {
panic(err) panic(err)
} }
} }

View File

@ -1,25 +0,0 @@
package ui
// The Focus Map Helps to keep track of which UI Element Currently Has the Focus It can be queried to get the Current
// UI Element with Focus and also can set UI Focus keep in mind that it isn't Focus Map that is Responsible to change
// the Focus that is Done through the Update Function of UI.ExpandedView */
var FocusMap map[string]bool
func GenerateFocusMap() {
FocusMap = make(map[string]bool)
FocusMap["Playlist"] = true
FocusMap["FileBrowser"] = false
FocusMap["SearchView"] = false
FocusMap["BuffSearchView"] = false
}
func HasFocus(s string) bool {
return FocusMap[s]
}
func SetFocus(s string) {
for k := range FocusMap {
FocusMap[k] = false
}
FocusMap[s] = true
}

103
views/buffsearchview.go Normal file
View File

@ -0,0 +1,103 @@
package views
import (
"fmt"
"github.com/aditya-K2/gomp/globals"
"github.com/aditya-K2/gomp/utils"
"github.com/aditya-K2/tview"
"github.com/gdamore/tcell/v2"
)
type BuffSearchView struct {
}
func (s BuffSearchView) GetViewName() string {
return "BuffSearchView"
}
func (s BuffSearchView) ShowChildrenContent() {
UI := globals.Ui
CONN := globals.Conn
r, _ := UI.ExpandedView.GetSelection()
SetCurrentView(FView)
if len(globals.DirTree.Children[r].Children) == 0 {
if id, err := CONN.AddId(globals.DirTree.Children[globals.Matches[r].Index].AbsolutePath, -1); err != nil {
globals.Notify.Send(fmt.Sprintf("Could Not add the Song %s to the Playlist",
globals.DirTree.Children[globals.Matches[r].Index].AbsolutePath))
} else {
if err := CONN.PlayId(id); err != nil {
globals.Notify.Send("Could not Play the Song")
}
}
} else {
globals.DirTree = &globals.DirTree.Children[globals.Matches[r].Index]
FView.Update(UI.ExpandedView)
}
UI.SearchBar.SetText("")
// Resetting globals.Matches
globals.Matches = nil
}
func (s BuffSearchView) ShowParentContent() {
globals.Notify.Send("Not Allowed in this View")
return
}
func (s BuffSearchView) AddToPlaylist() {
UI := globals.Ui
CONN := globals.Conn
r, _ := UI.ExpandedView.GetSelection()
if err := CONN.Add(globals.DirTree.Children[globals.Matches[r].Index].AbsolutePath); err != nil {
globals.Notify.Send(fmt.Sprintf("Could Not Add URI %s to the Playlist",
globals.DirTree.Children[globals.Matches[r].Index].Path))
} else {
SetCurrentView(FView)
globals.Notify.Send(fmt.Sprintf("URI Added %s to the Playlist",
globals.DirTree.Children[globals.Matches[r].Index].Path))
SetCurrentView(BuffSView)
}
}
func (s BuffSearchView) Quit() {
UI := globals.Ui
SetCurrentView(FView)
UI.SearchBar.SetText("")
globals.Matches = nil
}
func (f BuffSearchView) FocusBuffSearchView() {
UI := globals.Ui
SetCurrentView(BuffSView)
UI.App.SetFocus(UI.SearchBar)
}
func (f BuffSearchView) DeleteSongFromPlaylist() {}
func (s BuffSearchView) Update(inputTable *tview.Table) {
m := globals.Matches
f := globals.DirTree.Children
inputTable.Clear()
if m == nil || len(m) == 0 {
FView.Update(inputTable)
} else {
for k, v := range m {
if len(f[v.Index].Children) != 0 {
inputTable.SetCell(k, 0,
GetCell(
utils.GetMatchedString(
utils.Unique(v.MatchedIndexes), f[v.Index].Path, "[blue:-:bi]"),
tcell.ColorYellow, true))
} else {
inputTable.SetCell(k, 0,
GetCell(
utils.GetMatchedString(
utils.Unique(v.MatchedIndexes), f[v.Index].Title, "[yellow:-:bi]"),
tcell.ColorGreen, true))
}
if k == 15 {
break
}
}
}
}

97
views/fileView.go Normal file
View File

@ -0,0 +1,97 @@
package views
import (
"fmt"
"github.com/aditya-K2/gomp/globals"
"github.com/aditya-K2/gomp/utils"
"github.com/aditya-K2/tview"
"github.com/gdamore/tcell/v2"
)
type FileView struct {
}
func (f FileView) GetViewName() string {
return "FileView"
}
func (f FileView) ShowChildrenContent() {
UI := globals.Ui
CONN := globals.Conn
r, _ := UI.ExpandedView.GetSelection()
SetCurrentView(FView)
if len(globals.DirTree.Children[r].Children) == 0 {
if id, err := CONN.AddId(globals.DirTree.Children[r].AbsolutePath, -1); err != nil {
globals.Notify.Send(fmt.Sprintf("Could not Add Song %s",
globals.DirTree.Children[r].Path))
} else {
if err := CONN.PlayId(id); err != nil {
globals.Notify.Send(fmt.Sprintf("Could Not Play Song %s",
globals.DirTree.Children[r].Path))
}
}
} else {
globals.DirTree = &globals.DirTree.Children[r]
FView.Update(UI.ExpandedView)
UI.ExpandedView.Select(0, 0)
}
}
func (f FileView) ShowParentContent() {
UI := globals.Ui
if globals.DirTree.Parent != nil {
globals.DirTree = globals.DirTree.Parent
FView.Update(UI.ExpandedView)
}
}
func (f FileView) AddToPlaylist() {
UI := globals.Ui
CONN := globals.Conn
r, _ := UI.ExpandedView.GetSelection()
if err := CONN.Add(globals.DirTree.Children[r].AbsolutePath); err != nil {
globals.Notify.Send(fmt.Sprintf("Could not add %s to the Playlist",
globals.DirTree.Children[r].Path))
}
}
func (f FileView) Quit() {
globals.Ui.App.Stop()
}
func (f FileView) FocusBuffSearchView() {
UI := globals.Ui
SetCurrentView(BuffSView)
UI.App.SetFocus(UI.SearchBar)
}
func (f FileView) DeleteSongFromPlaylist() {}
func (f FileView) Update(inputTable *tview.Table) {
inputTable.Clear()
for i, j := range globals.DirTree.Children {
if len(j.Children) == 0 {
_songAttributes, err := globals.Conn.ListAllInfo(j.AbsolutePath)
if err == nil && _songAttributes[0]["Title"] != "" {
_, _, w, _ := inputTable.GetInnerRect()
inputTable.SetCell(i, 0,
GetCell(
utils.GetFormattedString(_songAttributes[0]["Title"], w/3), tcell.ColorGreen, false))
inputTable.SetCell(i, 1,
GetCell(
utils.GetFormattedString(_songAttributes[0]["Artist"], w/3), tcell.ColorPurple, false))
inputTable.SetCell(i, 2,
GetCell(_songAttributes[0]["Album"], tcell.ColorYellow, false))
} else if _songAttributes[0]["Title"] == "" {
inputTable.SetCell(i, 0,
GetCell(j.Path, tcell.ColorBlue, true))
}
} else {
inputTable.SetCell(i, 0,
GetCell(j.Path, tcell.ColorYellow, true))
}
}
}

80
views/playlistview.go Normal file
View File

@ -0,0 +1,80 @@
package views
import (
"github.com/aditya-K2/gomp/globals"
"github.com/aditya-K2/gomp/utils"
"github.com/aditya-K2/tview"
"github.com/gdamore/tcell/v2"
)
type PlaylistView struct {
}
func (s PlaylistView) GetViewName() string {
return "PlaylistView"
}
func GetCell(text string, foreground tcell.Color, bold bool) *tview.TableCell {
return tview.NewTableCell(text).
SetAlign(tview.AlignLeft).
SetStyle(tcell.StyleDefault.
Foreground(foreground).
Background(tcell.ColorBlack).
Bold(bold))
}
func (p PlaylistView) ShowChildrenContent() {
UI := globals.Ui
CONN := globals.Conn
r, _ := UI.ExpandedView.GetSelection()
if err := CONN.Play(r); err != nil {
globals.Notify.Send("Could Not Play the Song")
return
}
}
func (s PlaylistView) ShowParentContent() {
globals.Notify.Send("Not Allowed in this View")
return
}
func (p PlaylistView) AddToPlaylist() {}
func (p PlaylistView) Quit() {
globals.Ui.App.Stop()
}
func (p PlaylistView) FocusBuffSearchView() {}
func (p PlaylistView) DeleteSongFromPlaylist() {
UI := globals.Ui
CONN := globals.Conn
r, _ := UI.ExpandedView.GetSelection()
if err := CONN.Delete(r, -1); err != nil {
globals.Notify.Send("Could not Remove the Song from Playlist")
}
}
func (p PlaylistView) Update(inputTable *tview.Table) {
CONN := globals.Conn
_playlistAttr, _ := CONN.PlaylistInfo(-1, -1)
inputTable.Clear()
for i, j := range _playlistAttr {
_, _, w, _ := inputTable.GetInnerRect()
if j["Title"] == "" || j["Artist"] == "" || j["Album"] == "" {
inputTable.SetCell(i, 0,
GetCell(
utils.GetFormattedString(j["file"], w/3), tcell.ColorBlue, true))
} else {
inputTable.SetCell(i, 0,
GetCell(
utils.GetFormattedString(j["Title"], w/3), tcell.ColorGreen, false))
inputTable.SetCell(i, 1,
GetCell(
utils.GetFormattedString(j["Artist"], w/3), tcell.ColorPurple, false))
inputTable.SetCell(i, 2,
GetCell(j["Album"], tcell.ColorYellow, false))
}
}
}

86
views/searchview.go Normal file
View File

@ -0,0 +1,86 @@
package views
import (
"fmt"
"strings"
"github.com/aditya-K2/gomp/client"
"github.com/aditya-K2/gomp/globals"
"github.com/aditya-K2/gomp/utils"
"github.com/aditya-K2/tview"
"github.com/gdamore/tcell/v2"
)
type SearchView struct {
}
func (s SearchView) GetViewName() string {
return "SearchView"
}
func (s SearchView) ShowChildrenContent() {
UI := globals.Ui
SearchContentSlice := globals.SearchContentSlice
r, _ := UI.ExpandedView.GetSelection()
client.AddToPlaylist(SearchContentSlice[r], true)
}
func (s SearchView) ShowParentContent() {
fmt.Println(s)
globals.Notify.Send("Not Allowed in this View")
return
}
func (s SearchView) AddToPlaylist() {
UI := globals.Ui
SearchContentSlice := globals.SearchContentSlice
r, _ := UI.ExpandedView.GetSelection()
client.AddToPlaylist(SearchContentSlice[r], false)
}
func (p SearchView) Quit() {
globals.Ui.App.Stop()
}
func (s SearchView) FocusBuffSearchView() {}
func (s SearchView) DeleteSongFromPlaylist() {}
func (s SearchView) Update(inputTable *tview.Table) {
inputTable.Clear()
c := globals.SearchContentSlice
_, _, width, _ := inputTable.GetInnerRect()
for i, content := range c {
switch content.(type) {
case [3]string:
{
inputTable.SetCell(i, 0,
GetCell(
utils.GetFormattedString(content.([3]string)[0], width/3), tcell.ColorGreen, false))
inputTable.SetCell(i, 1,
GetCell(
utils.GetFormattedString(content.([3]string)[1], width/3), tcell.ColorPurple, false))
inputTable.SetCell(i, 2,
GetCell(content.([3]string)[2], tcell.ColorYellow, false))
}
case [2]string:
{
inputTable.SetCell(i, 0,
GetCell(
utils.GetFormattedString(content.([2]string)[0], width/3), tcell.ColorYellow, false))
inputTable.SetCell(i, 1,
GetCell(
utils.GetFormattedString(content.([2]string)[1], width/3), tcell.ColorPurple, false))
}
case string:
{
b := content.(string)
if !strings.HasPrefix(b, client.WHITE_AND_BOLD) {
inputTable.SetCell(i, 0,
GetCell(content.(string), tcell.ColorPurple, false))
} else {
inputTable.SetCell(i, 0,
GetCell(content.(string), tcell.ColorWhite, true).SetSelectable(false))
}
}
}
}
}

32
views/views.go Normal file
View File

@ -0,0 +1,32 @@
package views
import (
"github.com/aditya-K2/tview"
)
var (
CurrentView View
BuffSView BuffSearchView
SView SearchView
FView FileView
PView PlaylistView
)
type View interface {
Update(inputTable *tview.Table)
ShowChildrenContent()
ShowParentContent()
AddToPlaylist()
Quit()
FocusBuffSearchView()
DeleteSongFromPlaylist()
GetViewName() string
}
func SetCurrentView(v View) {
CurrentView = v
}
func GetCurrentView() View {
return CurrentView
}