feat(ui): improve key handling
- handle add-destination input in own handler func - handle CTRL-C when modal is visible - fix destination wraparound on key-up
This commit is contained in:
parent
af4410c4cf
commit
2fbf2176cf
@ -40,9 +40,11 @@ const (
|
||||
|
||||
// UI is responsible for managing the terminal user interface.
|
||||
type UI struct {
|
||||
commandCh chan Command
|
||||
buildInfo domain.BuildInfo
|
||||
logger *slog.Logger
|
||||
commandCh chan Command
|
||||
clipboardAvailable bool
|
||||
configFilePath string
|
||||
buildInfo domain.BuildInfo
|
||||
logger *slog.Logger
|
||||
|
||||
// tview state
|
||||
|
||||
@ -214,14 +216,16 @@ func StartUI(ctx context.Context, params StartParams) (*UI, error) {
|
||||
app.EnableMouse(false)
|
||||
|
||||
ui := &UI{
|
||||
commandCh: commandCh,
|
||||
buildInfo: params.BuildInfo,
|
||||
logger: params.Logger,
|
||||
app: app,
|
||||
screen: screen,
|
||||
screenCaptureC: screenCaptureC,
|
||||
pages: pages,
|
||||
container: container,
|
||||
commandCh: commandCh,
|
||||
clipboardAvailable: params.ClipboardAvailable,
|
||||
configFilePath: params.ConfigFilePath,
|
||||
buildInfo: params.BuildInfo,
|
||||
logger: params.Logger,
|
||||
app: app,
|
||||
screen: screen,
|
||||
screenCaptureC: screenCaptureC,
|
||||
pages: pages,
|
||||
container: container,
|
||||
sourceViews: sourceViews{
|
||||
url: urlTextView,
|
||||
status: statusTextView,
|
||||
@ -237,45 +241,7 @@ func StartUI(ctx context.Context, params StartParams) (*UI, error) {
|
||||
urlsToStartState: make(map[string]startState),
|
||||
}
|
||||
|
||||
app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
||||
// Special case: allow all keys except Escape to be passed to the add
|
||||
// destination modal.
|
||||
//
|
||||
// TODO: catch Ctrl-c
|
||||
if pageName, _ := pages.GetFrontPage(); pageName == pageNameAddDestination {
|
||||
if event.Key() == tcell.KeyEscape {
|
||||
ui.closeAddDestinationForm()
|
||||
return nil
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
||||
|
||||
switch event.Key() {
|
||||
case tcell.KeyRune:
|
||||
switch event.Rune() {
|
||||
case 'a', 'A':
|
||||
ui.addDestination()
|
||||
return nil
|
||||
case 'r', 'R':
|
||||
ui.removeDestination()
|
||||
return nil
|
||||
case ' ':
|
||||
ui.toggleDestination()
|
||||
case 'u', 'U':
|
||||
ui.copySourceURLToClipboard(params.ClipboardAvailable)
|
||||
case 'c', 'C':
|
||||
ui.copyConfigFilePathToClipboard(params.ClipboardAvailable, params.ConfigFilePath)
|
||||
case '?':
|
||||
ui.showAbout()
|
||||
}
|
||||
case tcell.KeyCtrlC:
|
||||
ui.confirmQuit()
|
||||
return nil
|
||||
}
|
||||
|
||||
return event
|
||||
})
|
||||
app.SetInputCapture(ui.handleInputCapture)
|
||||
|
||||
if ui.screenCaptureC != nil {
|
||||
app.SetAfterDrawFunc(ui.captureScreen)
|
||||
@ -315,6 +281,45 @@ func (ui *UI) run(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func (ui *UI) handleInputCapture(event *tcell.EventKey) *tcell.EventKey {
|
||||
// Special case: handle CTRL-C even when a modal is visible.
|
||||
if event.Key() == tcell.KeyCtrlC {
|
||||
ui.confirmQuit()
|
||||
return nil
|
||||
}
|
||||
|
||||
if ui.modalVisible() {
|
||||
return event
|
||||
}
|
||||
|
||||
switch event.Key() {
|
||||
case tcell.KeyRune:
|
||||
switch event.Rune() {
|
||||
case 'a', 'A':
|
||||
ui.addDestination()
|
||||
return nil
|
||||
case 'r', 'R':
|
||||
ui.removeDestination()
|
||||
return nil
|
||||
case ' ':
|
||||
ui.toggleDestination()
|
||||
case 'u', 'U':
|
||||
ui.copySourceURLToClipboard(ui.clipboardAvailable)
|
||||
case 'c', 'C':
|
||||
ui.copyConfigFilePathToClipboard(ui.clipboardAvailable, ui.configFilePath)
|
||||
case '?':
|
||||
ui.showAbout()
|
||||
}
|
||||
case tcell.KeyUp:
|
||||
row, _ := ui.destView.GetSelection()
|
||||
if row == 1 {
|
||||
ui.destView.Select(ui.destView.GetRowCount(), 0)
|
||||
}
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
||||
|
||||
func (ui *UI) ShowSourceNotLiveModal() {
|
||||
ui.app.QueueUpdateDraw(func() {
|
||||
ui.showModal(
|
||||
@ -508,6 +513,11 @@ func (ui *UI) resetFocus() {
|
||||
}
|
||||
}
|
||||
|
||||
func (ui *UI) modalVisible() bool {
|
||||
pageName, _ := ui.pages.GetFrontPage()
|
||||
return pageName != pageNameMain && pageName != pageNameNoDestinations
|
||||
}
|
||||
|
||||
func (ui *UI) showModal(pageName string, text string, buttons []string, doneFunc func(int, string)) {
|
||||
if ui.pages.HasPage(pageName) {
|
||||
return
|
||||
@ -520,6 +530,11 @@ func (ui *UI) showModal(pageName string, text string, buttons []string, doneFunc
|
||||
SetTextColor(tcell.ColorWhite).
|
||||
SetDoneFunc(func(buttonIndex int, buttonLabel string) {
|
||||
ui.pages.RemovePage(pageName)
|
||||
|
||||
if !ui.modalVisible() {
|
||||
ui.app.SetInputCapture(ui.handleInputCapture)
|
||||
}
|
||||
|
||||
ui.resetFocus()
|
||||
|
||||
if doneFunc != nil {
|
||||
@ -753,6 +768,13 @@ func (ui *UI) addDestination() {
|
||||
SetBorder(true).
|
||||
SetTitle("Add a new destination").
|
||||
SetTitleAlign(tview.AlignLeft).
|
||||
SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
||||
if event.Key() == tcell.KeyEscape {
|
||||
ui.closeAddDestinationForm()
|
||||
return nil
|
||||
}
|
||||
return event
|
||||
}).
|
||||
SetRect((currWidth-formWidth)/2, (currHeight-formHeight)/2, formWidth, formHeight)
|
||||
|
||||
ui.mu.Lock()
|
||||
|
Loading…
x
Reference in New Issue
Block a user