Implementing Simple Buffer Searching
Searching the Global Database although is enough but I have felt a need to have a quick and fast search option to search the current buffer. Buffer Search is also one of the views It can be only turned on if the File Browser has focus. ( Thinking of making it global ). The Searching is done through the fuzzy module. FileNode now implements the Source Interface. The Changed Function of the Search Bar checks for text changes and then modifies the Matches Variable which is used by the Update Function to Draw the Results. The Results have the Matching Characters Highlighted Differently. Maximum of 15 results are displayed to avoid lag. Upon Selecting the Result through the Search Bar navigation is possible and selection of the item is done the same way it works for file Browser. After Selection the Focus is returned Back to the File Browser. For The Tracks only the title is used for searching.
This commit is contained in:
@@ -7,9 +7,6 @@ import (
|
||||
"github.com/fhs/gompd/mpd"
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/aditya-K2/gomp/utils"
|
||||
"github.com/aditya-K2/tview"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -39,22 +36,6 @@ func TogglePlayBack() error {
|
||||
return err
|
||||
}
|
||||
|
||||
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, tview.NewTableCell(utils.GetFormattedString(j["file"], w/3)))
|
||||
} else {
|
||||
inputTable.SetCell(i, 0, tview.NewTableCell(utils.GetFormattedString("[green]"+j["Title"], w/3)))
|
||||
inputTable.SetCell(i, 1, tview.NewTableCell(utils.GetFormattedString("[magenta]"+j["Artist"], w/3)))
|
||||
inputTable.SetCell(i, 2, tview.NewTableCell("[yellow]"+j["Album"]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The GenerateContentSlice returns a slice of the content to be displayed on the Search View. The Slice is generated
|
||||
// because the random nature of maps as they return values randomly hence the draw function keeps changing the order
|
||||
// in which the results appear.
|
||||
@@ -99,70 +80,6 @@ func GenerateContentSlice(selectedSuggestion string) ([]interface{}, error) {
|
||||
return ContentSlice, nil
|
||||
}
|
||||
|
||||
// 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, tview.NewTableCell(utils.GetFormattedString("[green]"+content.([3]string)[0], width/3)))
|
||||
inputTable.SetCell(i, 1, tview.NewTableCell(utils.GetFormattedString("[magenta]"+content.([3]string)[1], width/3)))
|
||||
inputTable.SetCell(i, 2, tview.NewTableCell(utils.GetFormattedString("[yellow]"+content.([3]string)[2], width/3)))
|
||||
}
|
||||
case [2]string:
|
||||
{
|
||||
inputTable.SetCell(i, 0, tview.NewTableCell(utils.GetFormattedString("[green]"+content.([2]string)[0], width/3)))
|
||||
inputTable.SetCell(i, 1, tview.NewTableCell(utils.GetFormattedString("[magenta]"+content.([2]string)[1], width/3)))
|
||||
}
|
||||
case string:
|
||||
{
|
||||
b := content.(string)
|
||||
if !strings.HasPrefix(b, WHITE_AND_BOLD) {
|
||||
inputTable.SetCell(i, 0, tview.NewTableCell("[green]"+content.(string)))
|
||||
} else {
|
||||
inputTable.SetCell(i, 0, tview.NewTableCell(content.(string)).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,
|
||||
tview.NewTableCell("[green]"+utils.GetFormattedString(_songAttributes[0]["Title"], w/3)).
|
||||
SetAlign(tview.AlignLeft))
|
||||
|
||||
inputTable.SetCell(i, 1,
|
||||
tview.NewTableCell("[magenta]"+utils.GetFormattedString(_songAttributes[0]["Artist"], w/3)).
|
||||
SetAlign(tview.AlignLeft))
|
||||
|
||||
inputTable.SetCell(i, 2,
|
||||
tview.NewTableCell("[yellow]"+_songAttributes[0]["Album"]).
|
||||
SetAlign(tview.AlignLeft))
|
||||
|
||||
} else if _songAttributes[0]["Title"] == "" {
|
||||
inputTable.SetCell(i, 0,
|
||||
tview.NewTableCell("[blue]"+j.Path).
|
||||
SetAlign(tview.AlignLeft))
|
||||
}
|
||||
} else {
|
||||
inputTable.SetCell(i, 0,
|
||||
tview.NewTableCell("[yellow::b]"+j.Path).
|
||||
SetAlign(tview.AlignLeft))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateArtistTree Artist Tree is a map of Artist to their Album Map
|
||||
// Album Tree is a map of the tracks in that particular album.
|
||||
func GenerateArtistTree() (map[string]map[string]map[string]string, error) {
|
||||
|
||||
@@ -6,12 +6,31 @@ import (
|
||||
)
|
||||
|
||||
type FileNode struct {
|
||||
Children []FileNode
|
||||
Children []FileNode
|
||||
Path string
|
||||
Parent *FileNode
|
||||
AbsolutePath string
|
||||
}
|
||||
|
||||
// Source Interface For Fuzzy Searching.
|
||||
type FileNodes []FileNode
|
||||
|
||||
func (f FileNodes) String(i int) string {
|
||||
if len(f[i].Children) == 0 {
|
||||
_s, err := CONN.ListAllInfo(f[i].AbsolutePath)
|
||||
if err != nil {
|
||||
NotificationServer.Send(fmt.Sprintf("Could Not Get Information About the Node %s", f[i].Path))
|
||||
return f[i].Path
|
||||
}
|
||||
return _s[0]["Title"]
|
||||
}
|
||||
return f[i].Path
|
||||
}
|
||||
|
||||
func (f FileNodes) Len() int {
|
||||
return len(f)
|
||||
}
|
||||
|
||||
func (f *FileNode) AddChildren(path string) {
|
||||
if f.Path != "" {
|
||||
f.Children = append(f.Children, FileNode{Children: make([]FileNode, 0), Path: path, Parent: f, AbsolutePath: f.AbsolutePath + "/" + path})
|
||||
|
||||
113
client/updateView.go
Normal file
113
client/updateView.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/aditya-K2/fuzzy"
|
||||
"github.com/aditya-K2/gomp/utils"
|
||||
"github.com/aditya-K2/tview"
|
||||
)
|
||||
|
||||
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.SetCellSimple(k, 0, utils.GetMatchedString(f[v.Index].Path, "#0000ff", "yellow", v.MatchedIndexes))
|
||||
} else {
|
||||
_s, err := CONN.ListAllInfo(f[v.Index].AbsolutePath)
|
||||
if err != nil {
|
||||
NotificationServer.Send(fmt.Sprintf("Could Not Add %s to the Table", f[v.Index].Path))
|
||||
} else {
|
||||
inputTable.SetCellSimple(k, 0, utils.GetMatchedString(_s[0]["Title"], "#fbff00", "green", v.MatchedIndexes))
|
||||
}
|
||||
}
|
||||
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, tview.NewTableCell(utils.GetFormattedString(j["file"], w/3)))
|
||||
} else {
|
||||
inputTable.SetCell(i, 0, tview.NewTableCell(utils.GetFormattedString("[green]"+j["Title"], w/3)))
|
||||
inputTable.SetCell(i, 1, tview.NewTableCell(utils.GetFormattedString("[magenta]"+j["Artist"], w/3)))
|
||||
inputTable.SetCell(i, 2, tview.NewTableCell("[yellow]"+j["Album"]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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, tview.NewTableCell(utils.GetFormattedString("[green]"+content.([3]string)[0], width/3)))
|
||||
inputTable.SetCell(i, 1, tview.NewTableCell(utils.GetFormattedString("[magenta]"+content.([3]string)[1], width/3)))
|
||||
inputTable.SetCell(i, 2, tview.NewTableCell(utils.GetFormattedString("[yellow]"+content.([3]string)[2], width/3)))
|
||||
}
|
||||
case [2]string:
|
||||
{
|
||||
inputTable.SetCell(i, 0, tview.NewTableCell(utils.GetFormattedString("[green]"+content.([2]string)[0], width/3)))
|
||||
inputTable.SetCell(i, 1, tview.NewTableCell(utils.GetFormattedString("[magenta]"+content.([2]string)[1], width/3)))
|
||||
}
|
||||
case string:
|
||||
{
|
||||
b := content.(string)
|
||||
if !strings.HasPrefix(b, WHITE_AND_BOLD) {
|
||||
inputTable.SetCell(i, 0, tview.NewTableCell("[green]"+content.(string)))
|
||||
} else {
|
||||
inputTable.SetCell(i, 0, tview.NewTableCell(content.(string)).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,
|
||||
tview.NewTableCell("[green]"+utils.GetFormattedString(_songAttributes[0]["Title"], w/3)).
|
||||
SetAlign(tview.AlignLeft))
|
||||
|
||||
inputTable.SetCell(i, 1,
|
||||
tview.NewTableCell("[magenta]"+utils.GetFormattedString(_songAttributes[0]["Artist"], w/3)).
|
||||
SetAlign(tview.AlignLeft))
|
||||
|
||||
inputTable.SetCell(i, 2,
|
||||
tview.NewTableCell("[yellow]"+_songAttributes[0]["Album"]).
|
||||
SetAlign(tview.AlignLeft))
|
||||
|
||||
} else if _songAttributes[0]["Title"] == "" {
|
||||
inputTable.SetCell(i, 0,
|
||||
tview.NewTableCell("[blue]"+j.Path).
|
||||
SetAlign(tview.AlignLeft))
|
||||
}
|
||||
} else {
|
||||
inputTable.SetCell(i, 0,
|
||||
tview.NewTableCell("[yellow::b]"+j.Path).
|
||||
SetAlign(tview.AlignLeft))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user