package tui import ( "fmt" "math/rand" "charm.land/bubbles/v2/spinner" tea "charm.land/bubbletea/v2" ) const ( imageName = "hub.davinti.com.br:443/app-dono/app-cliente:latest" wireguardImageName = "hub.davinti.com.br:443/davinti-vproxy:latest" configPath = "config.toml" wireguardConfigPath = "envs" ) func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if key, ok := msg.(tea.KeyPressMsg); ok { switch key.String() { case "ctrl+c": return m, tea.Quit } } switch msg := msg.(type) { case tea.WindowSizeMsg: m.width = msg.Width m.height = msg.Height case spinner.TickMsg: var cmd tea.Cmd m.spinner, cmd = m.spinner.Update(msg) return m, cmd } switch m.currentStep { case StepCheckDocker: return m.updateCheckDocker(msg) case StepDockerInstall: return m.updateDockerInstall(msg) case StepDockerLogin: done, cmd := m.loginForm.Update(msg) if done { m.configValues.Login = m.loginForm.Values() m.currentStep = StepDownloadImage return m, DownloadImageCmd(m.configValues.Login["user"], m.configValues.Login["password"]) } return m, cmd case StepDownloadImage: return m.updateDownloadImage(msg) // Ip & Wireguard case StepIPQuestion: return m.updateIPQuestion(msg) case StepWireguardConfig: done, cmd := m.wireguardForm.Update(msg) if done { m.configValues.Wireguard = m.wireguardForm.Values() m.downloadDone = false m.downloadMessage = "" m.downloadError = nil m.currentStep = StepGenerateWireguardFile return m, GenerateWireguardConfigFile(m.configValues, wireguardConfigPath) } return m, cmd case StepGenerateWireguardFile: return m.updateGenerateWireguardFile(msg) case StepDownloadWireguard: return m.updateDownloadWireguard(msg) case StepRunWireguard: return m.updateRunWireguardDocker(msg) case StepAppConfig: done, cmd := m.appForm.Update(msg) if done { m.configValues.Application = m.appForm.Values() m.currentStep = StepServerConfig } return m, cmd case StepServerConfig: done, cmd := m.serverForm.Update(msg) if done { m.configValues.Server = m.serverForm.Values() m.currentStep = StepDatabaseConfig } return m, cmd case StepDatabaseConfig: done, cmd := m.dbForm.Update(msg) if done { m.configValues.Database = m.dbForm.Values() m.currentStep = StepCertConfig } return m, cmd case StepCertConfig: done, cmd := m.certForm.Update(msg) if done { m.configValues.Cert = m.certForm.Values() m.currentStep = StepGenerateFile m.finishedFile = false m.configFileError = nil return m, GenerateConfigFile(m.configValues, configPath) } return m, cmd case StepGenerateFile: return m.updateGenerateFile(msg) case StepRunDocker: return m.updateRunDocker(msg) case StepDone: return m, tea.Quit } return m, nil } func (m Model) updateCheckDocker(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case DockerCheckedMsg: m.dockerInstalled = msg.Installed m.checkDockerDone = true case TickMsg: if m.checkProgress < 1.0 { m.checkProgress += 0.2 + (rand.Float64()*0.2 - 0.2) if m.checkProgress > 1.0 { m.checkProgress = 1.0 } return m, TickCmd() } case tea.KeyPressMsg: if m.checkDockerDone && m.checkProgress == 1 { if m.dockerInstalled { m.loading = true m.currentStep = StepDockerLogin } else { m.currentStep = StepDockerInstall } } } return m, nil } func (m Model) updateDockerInstall(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg.(type) { case tea.KeyPressMsg: return m, tea.Quit } return m, nil } func (m Model) updateDownloadImage(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case ImageDownloadFinishedMsg: m.downloadDone = true m.downloadMessage = msg.Message m.downloadError = msg.Err return m, nil case tea.KeyPressMsg: if m.downloadDone && m.downloadError == nil { m.currentStep = StepIPQuestion } else if m.downloadDone { return m, tea.Quit } } return m, nil } func (m Model) updateIPQuestion(msg tea.Msg) (tea.Model, tea.Cmd) { numOptions := 2 switch msg := msg.(type) { case tea.KeyPressMsg: switch msg.String() { case "up", "k": if m.cursor > 0 { m.cursor-- } case "down", "j": if m.cursor < numOptions-1 { m.cursor++ } case "enter": // Yes if m.cursor == 0 { m.currentStep = StepAppConfig return m, nil } m.currentStep = StepWireguardConfig } } return m, nil } func (m Model) updateDownloadWireguard(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case ImageDownloadFinishedMsg: m.downloadDone = true m.downloadMessage = msg.Message m.downloadError = msg.Err if m.downloadError == nil { m.currentStep = StepRunWireguard return m, RunWireguardContainer(wireguardConfigPath, m.configValues) } case tea.KeyPressMsg: if m.downloadDone && m.downloadError == nil { m.currentStep = StepRunWireguard } else if m.downloadDone { return m, tea.Quit } } return m, nil } func (m Model) updateGenerateWireguardFile(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case ConfigFileMsg: m.finishedFile = true m.configFileError = msg.Err if msg.Err == nil { m.currentStep = StepDownloadWireguard return m, DownloadWireguardImageCmd(m.configValues.Login["user"], m.configValues.Login["password"]) } case tea.KeyPressMsg: if m.finishedFile && m.configFileError != nil { return m, tea.Quit } else if m.finishedFile && m.configFileError == nil { m.currentStep = StepDownloadWireguard return m, DownloadWireguardImageCmd(m.configValues.Login["user"], m.configValues.Login["password"]) } } return m, nil } func (m Model) updateRunWireguardDocker(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case DockerRunMsg: m.finishedDockerRun = true m.dockerRunError = msg.Err case tea.KeyPressMsg: if m.finishedDockerRun && m.dockerRunError != nil { return m, tea.Quit } else if m.finishedDockerRun && m.dockerRunError == nil { m.currentStep = StepAppConfig } } return m, nil } func (m Model) updateGenerateFile(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case ConfigFileMsg: m.finishedFile = true m.configFileError = msg.Err case tea.KeyPressMsg: if m.finishedFile && m.configFileError != nil { return m, tea.Quit } else if m.finishedFile && m.configFileError == nil { m.currentStep = StepRunDocker m.finishedDockerRun = false m.dockerRunError = nil return m, RunAppContainer( imageName, "app-dono-cliente", configPath, fmt.Sprintf("/app/%s", configPath), m.configValues, ) } } return m, nil } func (m Model) updateRunDocker(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case DockerRunMsg: m.finishedDockerRun = true m.dockerRunError = msg.Err case tea.KeyPressMsg: if m.finishedDockerRun && m.dockerRunError != nil { return m, tea.Quit } else if m.finishedDockerRun && m.dockerRunError == nil { m.currentStep = StepDone } } return m, nil }