mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-28 00:53:45 +08:00
ab81464bd1
Add navigation and map matching providers with the vendored map service sources. Co-authored-by: Daniel Koepping <elkoled@gmail.com> Co-authored-by: Danny <dannyirwin31@yahoo.com> Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu> Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com>
150 lines
4.2 KiB
Go
150 lines
4.2 KiB
Go
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/charmbracelet/bubbles/list"
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
"github.com/charmbracelet/lipgloss"
|
|
|
|
"pfeifer.dev/mapd/cereal"
|
|
"pfeifer.dev/mapd/cereal/custom"
|
|
ms "pfeifer.dev/mapd/settings"
|
|
)
|
|
|
|
type mainState int
|
|
|
|
const (
|
|
showMenu mainState = iota
|
|
showSettings
|
|
showDownload
|
|
showOutput
|
|
showDownloadProgress
|
|
)
|
|
|
|
var docStyle = lipgloss.NewStyle().Margin(1, 2)
|
|
|
|
type TickMsg time.Time
|
|
|
|
func tickEvery() tea.Cmd {
|
|
return tea.Every(50*time.Millisecond, func(t time.Time) tea.Msg {
|
|
return TickMsg(t)
|
|
})
|
|
}
|
|
|
|
type uiModel struct {
|
|
list list.Model
|
|
state mainState
|
|
settings settingsModel
|
|
output outputModel
|
|
download downloadModel
|
|
downloadProgress downloadProgressModel
|
|
pub *cereal.Publisher[custom.MapdIn]
|
|
sub *cereal.Subscriber[custom.MapdOut]
|
|
extendedSub *cereal.Subscriber[custom.MapdExtendedOut]
|
|
extendedData custom.MapdExtendedOut
|
|
extendedDataValid bool
|
|
}
|
|
type item struct {
|
|
title, desc string
|
|
state mainState
|
|
}
|
|
|
|
func (i item) Title() string { return i.title }
|
|
func (i item) Description() string { return i.desc }
|
|
func (i item) FilterValue() string { return i.title }
|
|
|
|
func initialModel() uiModel {
|
|
items := []list.Item{
|
|
item{title: "Settings", desc: "Modify settings of an active instance of mapd", state: showSettings},
|
|
item{title: "Download", desc: "Trigger a download of maps in an active instance of mapd", state: showDownload},
|
|
item{title: "Download Progress", desc: "Watch the live download progress from mapd", state: showDownloadProgress},
|
|
item{title: "Watch", desc: "Watch the live output from mapd", state: showOutput},
|
|
}
|
|
|
|
listDelegate := list.NewDefaultDelegate()
|
|
pub := cereal.NewPublisher("mapdCli", cereal.MapdInCreator)
|
|
sub := cereal.NewSubscriber("mapdOut", cereal.MapdOutReader, true, false)
|
|
extendedSub := cereal.NewSubscriber("mapdExtendedOut", cereal.MapdExtendedOutReader, true, false)
|
|
m := uiModel{list: list.New(items, listDelegate, 0, 0), settings: getSettingsModel(), pub: &pub, sub: &sub, extendedSub: &extendedSub, download: getDownloadModel()}
|
|
m.list.Title = "Mapd Actions"
|
|
return m
|
|
}
|
|
|
|
func (m uiModel) Init() tea.Cmd {
|
|
// Just return `nil`, which means "no I/O right now, please."
|
|
return tickEvery()
|
|
}
|
|
|
|
func (m uiModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
switch msg := msg.(type) {
|
|
case tea.KeyMsg:
|
|
if msg.String() == "ctrl+c" {
|
|
return m, tea.Quit
|
|
}
|
|
if msg.Type == tea.KeyEnter && m.state == showMenu && m.list.FilterState() != list.Filtering {
|
|
it := m.list.SelectedItem().(item)
|
|
m.state = it.state
|
|
return m, nil
|
|
}
|
|
case tea.WindowSizeMsg:
|
|
h, v := docStyle.GetFrameSize()
|
|
m.list.SetSize(msg.Width-h, msg.Height-v)
|
|
m.settings, _ = m.settings.Update(msg, &m)
|
|
m.download, _ = m.download.Update(msg, &m)
|
|
m.output, _ = m.output.Update(msg, &m)
|
|
m.downloadProgress, _ = m.downloadProgress.Update(msg, &m)
|
|
case TickMsg:
|
|
extendedData, success := m.extendedSub.Read()
|
|
if success {
|
|
m.extendedData = extendedData
|
|
settingsData, _ := extendedData.Settings()
|
|
ms.Settings.Unmarshal([]byte(settingsData))
|
|
m.extendedDataValid = true
|
|
}
|
|
m.output, _ = m.output.Update(msg, &m)
|
|
m.downloadProgress, _ = m.downloadProgress.Update(msg, &m)
|
|
m.settings, _ = m.settings.Update(msg, &m)
|
|
return m, tickEvery()
|
|
}
|
|
|
|
var cmd tea.Cmd
|
|
switch m.state {
|
|
case showSettings:
|
|
m.settings, cmd = m.settings.Update(msg, &m)
|
|
case showOutput:
|
|
m.output, cmd = m.output.Update(msg, &m)
|
|
case showDownload:
|
|
m.download, cmd = m.download.Update(msg, &m)
|
|
case showDownloadProgress:
|
|
m.downloadProgress, cmd = m.downloadProgress.Update(msg, &m)
|
|
default:
|
|
m.list, cmd = m.list.Update(msg)
|
|
}
|
|
return m, cmd
|
|
}
|
|
|
|
func (m uiModel) View() string {
|
|
switch m.state {
|
|
case showSettings:
|
|
return m.settings.View()
|
|
case showOutput:
|
|
return m.output.View()
|
|
case showDownload:
|
|
return m.download.View()
|
|
case showDownloadProgress:
|
|
return m.downloadProgress.View()
|
|
}
|
|
return docStyle.Render(m.list.View())
|
|
}
|
|
|
|
func interactive() {
|
|
p := tea.NewProgram(initialModel(), tea.WithAltScreen())
|
|
if _, err := p.Run(); err != nil {
|
|
fmt.Printf("Alas, there's been an error: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|