mirror of
https://github.com/anotherhadi/proton-vpn-tui.git
synced 2026-10-05 19:28:28 +02:00
init
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"charm.land/bubbles/v2/key"
|
||||
tea "charm.land/bubbletea/v2"
|
||||
|
||||
ilovetuiapp "github.com/anotherhadi/ilovetui/app"
|
||||
"github.com/anotherhadi/ilovetui/drawer"
|
||||
"github.com/anotherhadi/ilovetui/minsize"
|
||||
"github.com/anotherhadi/ilovetui/modal"
|
||||
"github.com/anotherhadi/ilovetui/notification"
|
||||
zone "github.com/lrstanley/bubblezone/v2"
|
||||
|
||||
"github.com/anotherhadi/proton-vpn-tui/internal/config"
|
||||
"github.com/anotherhadi/proton-vpn-tui/internal/ui"
|
||||
)
|
||||
|
||||
const (
|
||||
minWidth = 30
|
||||
minHeight = 16
|
||||
)
|
||||
|
||||
type appModel struct {
|
||||
core app.Model
|
||||
drawers drawer.Model
|
||||
modals modal.Model
|
||||
notif notification.Model
|
||||
minSize minsize.Model
|
||||
|
||||
width, height int
|
||||
}
|
||||
|
||||
func newApp() appModel {
|
||||
return appModel{
|
||||
core: app.New(),
|
||||
drawers: drawer.New(drawer.WithMaxWidth(100000)),
|
||||
modals: modal.New(),
|
||||
notif: notification.New(),
|
||||
minSize: minsize.New(minWidth, minHeight),
|
||||
}
|
||||
}
|
||||
|
||||
func (a appModel) Init() tea.Cmd {
|
||||
return tea.Batch(a.core.Init(), a.drawers.Init(), a.modals.Init(), a.notif.Init())
|
||||
}
|
||||
|
||||
func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
if _, ok := msg.(ilovetuiapp.QuitMsg); ok {
|
||||
return a, tea.Quit
|
||||
}
|
||||
|
||||
if sizeMsg, ok := msg.(tea.WindowSizeMsg); ok {
|
||||
a.width, a.height = sizeMsg.Width, sizeMsg.Height
|
||||
}
|
||||
|
||||
var drawerCmd, modalCmd tea.Cmd
|
||||
a.drawers, drawerCmd = a.drawers.Update(msg)
|
||||
a.modals, modalCmd = a.modals.Update(msg)
|
||||
a.core.Overlay = a.drawers.Open() || a.modals.Open()
|
||||
|
||||
helpToggled := false
|
||||
if keyMsg, ok := msg.(tea.KeyPressMsg); ok && key.Matches(keyMsg, config.Global.Keybindings.Global.Help) {
|
||||
a.core.ToggleHelp()
|
||||
helpToggled = true
|
||||
}
|
||||
|
||||
var coreCmd, notifCmd tea.Cmd
|
||||
a.core, coreCmd = a.core.Update(msg)
|
||||
a.notif, notifCmd = a.notif.Update(msg)
|
||||
|
||||
if _, isResize := msg.(tea.WindowSizeMsg); a.drawers.Open() && (isResize || helpToggled) {
|
||||
var cmd tea.Cmd
|
||||
a.drawers, cmd = a.drawers.Update(a.core.DrawerWindowSizeMsg())
|
||||
drawerCmd = tea.Batch(drawerCmd, cmd)
|
||||
}
|
||||
|
||||
return a, tea.Batch(coreCmd, drawerCmd, modalCmd, notifCmd)
|
||||
}
|
||||
|
||||
func (a appModel) View() tea.View {
|
||||
bg := a.core.View()
|
||||
bg = zone.Scan(bg)
|
||||
bg = a.drawers.Render(bg)
|
||||
bg = a.modals.Render(bg)
|
||||
bg = a.notif.Render(bg)
|
||||
bg = strings.Join([]string{bg, a.core.HelpView()}, "\n")
|
||||
if !a.minSize.Fits(a.width, a.height) {
|
||||
bg = a.minSize.View(a.width, a.height)
|
||||
}
|
||||
return tea.View{
|
||||
Content: bg,
|
||||
AltScreen: true,
|
||||
WindowTitle: a.core.WindowTitle(),
|
||||
MouseMode: tea.MouseModeCellMotion,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime/debug"
|
||||
|
||||
tea "charm.land/bubbletea/v2"
|
||||
zone "github.com/lrstanley/bubblezone/v2"
|
||||
|
||||
"github.com/anotherhadi/ilovetui/style"
|
||||
"github.com/anotherhadi/proton-vpn-tui/internal/backend"
|
||||
"github.com/anotherhadi/proton-vpn-tui/internal/config"
|
||||
"github.com/anotherhadi/proton-vpn-tui/internal/icons"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var version = "dev"
|
||||
|
||||
func main() {
|
||||
var (
|
||||
flagConfig string
|
||||
flagAddDefaultConfig bool
|
||||
)
|
||||
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "proton-vpn-tui",
|
||||
Short: "A minimal, TUI and keyboard friendly wrapper for proton-vpn-cli.",
|
||||
Version: version,
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if flagAddDefaultConfig {
|
||||
home, _ := os.UserHomeDir()
|
||||
cfgPath := filepath.Join(home, ".config", "proton-vpn-tui", "config.yaml")
|
||||
if flagConfig != "" {
|
||||
cfgPath = flagConfig
|
||||
}
|
||||
if err := config.WriteDefaultConfig(cfgPath); err != nil {
|
||||
return fmt.Errorf("add-default-config: %w", err)
|
||||
}
|
||||
fmt.Printf("default config written to %s\n", cfgPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
home, _ := os.UserHomeDir()
|
||||
cfgPath := filepath.Join(home, ".config", "proton-vpn-tui", "config.yaml")
|
||||
if flagConfig != "" {
|
||||
cfgPath = flagConfig
|
||||
}
|
||||
|
||||
if err := config.Load(cfgPath); err != nil {
|
||||
return fmt.Errorf("config: %w", err)
|
||||
}
|
||||
config.Global.Version = version
|
||||
|
||||
style.Init()
|
||||
icons.Init()
|
||||
zone.NewGlobal()
|
||||
|
||||
if err := backend.Available(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
p := tea.NewProgram(newApp())
|
||||
if _, err := p.Run(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
rootCmd.Flags().StringVarP(&flagConfig, "config", "c", "", "path to config file")
|
||||
rootCmd.Flags().BoolVar(&flagAddDefaultConfig, "add-default-config", false, "copy the default config file to the config path and exit")
|
||||
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
if version != "dev" {
|
||||
return
|
||||
}
|
||||
if info, ok := debug.ReadBuildInfo(); ok && info.Main.Version != "" && info.Main.Version != "(devel)" {
|
||||
version = info.Main.Version
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user