make autocompletion async

This commit is contained in:
raziman 2021-02-20 16:21:04 +08:00
parent 41d1ed2d15
commit e2a5f1fe99
2 changed files with 118 additions and 96 deletions

View File

@ -1,10 +1,6 @@
package main
import (
"fmt"
"time"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"github.com/ztrue/tracerr"
)
@ -66,98 +62,7 @@ func (c Command) defineCommands() {
})
c.define("youtube_search", func() {
popupId := "youtube-search-input-popup"
input := newInputPopup(popupId, " Youtube Search ", "search: ", "")
// 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
})
input.SetDoneFunc(func(key tcell.Key) {
switch key {
case tcell.KeyEnter:
search := input.GetText()
defaultTimedPopup(" Youtube Search ", "Searching for "+search)
gomu.pages.RemovePage(popupId)
gomu.popups.pop()
go func() {
results, err := getSearchResult(search)
if err != nil {
logError(err)
defaultTimedPopup(" Error ", err.Error())
return
}
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("Youtube Videos", 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()
}()
case tcell.KeyEscape:
gomu.pages.RemovePage(popupId)
gomu.popups.pop()
gomu.app.SetFocus(gomu.prevPanel.(tview.Primitive))
default:
input.Autocomplete()
}
})
ytSearchPopup()
})
c.define("download_audio", func() {

117
popup.go
View File

@ -6,6 +6,7 @@ import (
"fmt"
"regexp"
"strings"
"sync"
"time"
"unicode/utf8"
@ -665,3 +666,119 @@ func replPopup() {
gomu.pages.AddPage(popupId, center(flex, 90, 30), true, true)
gomu.popups.push(flex)
}
func ytSearchPopup() {
popupId := "youtube-search-input-popup"
input := newInputPopup(popupId, " Youtube Search ", "search: ", "")
var mutex sync.Mutex
prefixMap := make(map[string][]string)
// quick hack to change the autocomplete text color
tview.Styles.PrimitiveBackgroundColor = tcell.ColorBlack
input.SetAutocompleteFunc(func(currentText string) []string {
// Ignore empty text.
prefix := strings.TrimSpace(strings.ToLower(currentText))
if prefix == "" {
return nil
}
mutex.Lock()
defer mutex.Unlock()
entries, ok := prefixMap[prefix]
if ok {
return entries
}
go func() {
suggestions, err := getSuggestions(currentText)
if err != nil {
logError(err)
return
}
mutex.Lock()
prefixMap[prefix] = suggestions
mutex.Unlock()
input.Autocomplete()
gomu.app.Draw()
}()
return nil
})
input.SetDoneFunc(func(key tcell.Key) {
switch key {
case tcell.KeyEnter:
search := input.GetText()
defaultTimedPopup(" Youtube Search ", "Searching for "+search)
gomu.pages.RemovePage(popupId)
gomu.popups.pop()
go func() {
results, err := getSearchResult(search)
if err != nil {
logError(err)
defaultTimedPopup(" Error ", err.Error())
return
}
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("Youtube Videos", 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()
}()
case tcell.KeyEscape:
gomu.pages.RemovePage(popupId)
gomu.popups.pop()
gomu.app.SetFocus(gomu.prevPanel.(tview.Primitive))
}
})
}