mirror of
https://github.com/anotherhadi/proton-vpn-tui.git
synced 2026-10-05 19:28:28 +02:00
145 lines
3.2 KiB
Go
145 lines
3.2 KiB
Go
package app
|
|
|
|
import (
|
|
"time"
|
|
|
|
tea "charm.land/bubbletea/v2"
|
|
|
|
"github.com/anotherhadi/ilovetui/notification"
|
|
|
|
"github.com/anotherhadi/proton-vpn-tui/internal/backend"
|
|
)
|
|
|
|
type (
|
|
tickMsg time.Time
|
|
serversMsg []backend.LogicalServer
|
|
serversRefreshedMsg []backend.LogicalServer
|
|
|
|
serversErrMsg struct{ err error }
|
|
statusMsg backend.ConnectionStatus
|
|
statusErrMsg struct{ err error }
|
|
|
|
serversCacheErrMsg struct{ err error }
|
|
|
|
quickStatusMsg bool
|
|
quickStatusErrMsg struct{ err error }
|
|
|
|
connectResultMsg struct {
|
|
err error
|
|
target string
|
|
disconnect bool
|
|
|
|
freeFallback bool
|
|
}
|
|
)
|
|
|
|
func tickCmd() tea.Cmd {
|
|
return tea.Tick(5*time.Second, func(t time.Time) tea.Msg { return tickMsg(t) })
|
|
}
|
|
|
|
func fetchServersCache() tea.Msg {
|
|
servers, err := backend.ParseCache()
|
|
if err != nil {
|
|
return serversCacheErrMsg{err: err}
|
|
}
|
|
return serversMsg(servers)
|
|
}
|
|
|
|
func refreshServers() tea.Msg {
|
|
if err := backend.RefreshServerList(); err != nil {
|
|
return serversErrMsg{err: err}
|
|
}
|
|
servers, err := parseCacheAfterRefresh()
|
|
if err != nil {
|
|
return serversErrMsg{err: err}
|
|
}
|
|
return serversMsg(servers)
|
|
}
|
|
|
|
func refreshServersManual() tea.Msg {
|
|
if err := backend.RefreshServerList(); err != nil {
|
|
return serversErrMsg{err: err}
|
|
}
|
|
servers, err := parseCacheAfterRefresh()
|
|
if err != nil {
|
|
return serversErrMsg{err: err}
|
|
}
|
|
return serversRefreshedMsg(servers)
|
|
}
|
|
|
|
func parseCacheAfterRefresh() ([]backend.LogicalServer, error) {
|
|
servers, err := backend.ParseCache()
|
|
if err == nil {
|
|
return servers, nil
|
|
}
|
|
time.Sleep(300 * time.Millisecond)
|
|
return backend.ParseCache()
|
|
}
|
|
|
|
func fetchStatus() tea.Msg {
|
|
status, err := backend.Status()
|
|
if err != nil {
|
|
return statusErrMsg{err: err}
|
|
}
|
|
return statusMsg(status)
|
|
}
|
|
|
|
func fetchQuickStatus() tea.Msg {
|
|
connected, err := backend.IsConnected()
|
|
if err != nil {
|
|
return quickStatusErrMsg{err: err}
|
|
}
|
|
return quickStatusMsg(connected)
|
|
}
|
|
|
|
func connectGroup(country, city, prefer string, f filters) tea.Cmd {
|
|
return func() tea.Msg {
|
|
target := backend.CountryName(country)
|
|
if city != "" {
|
|
target = city + ", " + target
|
|
}
|
|
|
|
err, fallback := connectWithFreeFallback(func() error {
|
|
if prefer == "random" {
|
|
return backend.ConnectRandom(country, city, f.P2P, f.SecureCore, f.Tor)
|
|
}
|
|
return backend.ConnectFastest(country, city, f.P2P, f.SecureCore, f.Tor)
|
|
})
|
|
if fallback {
|
|
target = "an available free server"
|
|
}
|
|
return connectResultMsg{err: err, target: target, freeFallback: fallback}
|
|
}
|
|
}
|
|
|
|
func connectServer(s backend.LogicalServer) tea.Cmd {
|
|
return func() tea.Msg {
|
|
target := s.Name
|
|
|
|
err, fallback := connectWithFreeFallback(func() error { return backend.ConnectId(s.Name) })
|
|
if fallback {
|
|
target = "an available free server"
|
|
}
|
|
return connectResultMsg{err: err, target: target, freeFallback: fallback}
|
|
}
|
|
}
|
|
|
|
func connectWithFreeFallback(attempt func() error) (err error, fallback bool) {
|
|
err = attempt()
|
|
if !backend.IsFreePlanRestricted(err) {
|
|
return err, false
|
|
}
|
|
return backend.ConnectAny(), true
|
|
}
|
|
|
|
func disconnectCmd() tea.Cmd {
|
|
return func() tea.Msg {
|
|
err := backend.Disconnect()
|
|
return connectResultMsg{err: err, disconnect: true}
|
|
}
|
|
}
|
|
|
|
func errorToast(err error) tea.Cmd {
|
|
return notification.Show("Error", err.Error(), notification.Error)
|
|
}
|