package tui import ( "fmt" "strings" "github.com/charmbracelet/bubbles/progress" "github.com/charmbracelet/bubbles/viewport" "github.com/charmbracelet/lipgloss" ) func (m Model) headerView() string { bannerText := bannerStyle.Render(banner) return lipgloss.JoinVertical(lipgloss.Center, bannerText) } func (m Model) platformInfoView() string { var info strings.Builder if m.platform.AppVersion != "" { versionLine := titleStyle.Render("Version:") versionLine += " " versionLine += fmt.Sprintf("%s", m.platform.AppVersion) if m.versionCheckResult != nil && m.versionCheckResult.UpdateAvailable { versionLine += " - " versionLine += successStyle.Render("Update Available") } info.WriteString(infoStyle.Render(versionLine)) info.WriteString("\n") } info.WriteString(titleStyle.Render("OS:")) info.WriteString(" ") info.WriteString(infoStyle.Render(fmt.Sprintf("%s", m.platformInfo.String()))) info.WriteString("\n") if m.platform.CPU != "" { info.WriteString(titleStyle.Render("CPU:")) info.WriteString(" ") // Apply vendor color styling to CPU cpuStyle := getVendorColor(m.platform.CPUVendor) info.WriteString(cpuStyle.Render(fmt.Sprintf("%s", m.platform.CPU))) info.WriteString("\n") } if m.platform.GPU != "" { info.WriteString(titleStyle.Render("GPU:")) info.WriteString(" ") // Apply vendor color styling to GPU gpuStyle := getVendorColor(m.platform.GPUVendor) info.WriteString(gpuStyle.Render(fmt.Sprintf("%s", m.platform.GPU))) info.WriteString("\n") } if m.platform.HWA != "" { info.WriteString(titleStyle.Render("HW Decode:")) info.WriteString(" ") if m.platform.HWA == "Unknown" { info.WriteString(infoStyle.Render("Unknown")) } else { codecs := strings.Split(m.platform.HWA, ",") info.WriteString(formatCodecsDisplay(codecs)) } info.WriteString("\n") } // Show current HWA setting currentHWA := m.getCurrentHWAValue() info.WriteString(titleStyle.Render("HWA Status:")) info.WriteString(" ") if currentHWA == "" || currentHWA == "no" { info.WriteString(errorStyle.Render("Disabled")) } else { info.WriteString(successStyle.Render(fmt.Sprintf("Enabled (%s)", currentHWA))) } info.WriteString("\n") info.WriteString(subtitleStyle.Render("═════════════")) return infoStyle.Render(info.String()) } func (m Model) errorView() string { var content strings.Builder content.WriteString(titleStyle.Render("Installation Failed")) content.WriteString("\n") content.WriteString(subtitleStyle.Render("═══════════════")) content.WriteString("\n\n") content.WriteString(errorStyle.Render("✗ An error occurred")) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Error: ")) content.WriteString(errorStyle.Render(m.errorMessage)) content.WriteString("\n\n") if len(m.installOutput) > 0 { outputStyle := lipgloss.NewStyle(). Foreground(white). Background(black). Border(lipgloss.RoundedBorder()). BorderForeground(gray). Padding(1) content.WriteString(infoStyle.Render("Command output:")) content.WriteString("\n") content.WriteString(outputStyle.Render(m.outputViewport.View())) content.WriteString("\n\n") } content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to exit, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to return")) return m.wrapContentInViewport(content.String()) } func (m Model) View() string { if m.showHelp { return m.helpView() } if m.showVersion { return m.versionView() } var content strings.Builder content.WriteString(m.headerView()) content.WriteString("\n\n") if m.state == StateMainMenu { content.WriteString(m.platformInfoView()) content.WriteString("\n\n") content.WriteString(m.menuList.View()) content.WriteString("\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to select, ")) content.WriteString(subtitleStyle.Render("↑/↓")) content.WriteString(infoStyle.Render(" to navigate")) } else if m.state == StateInstallMenu { content.WriteString(m.platformInfoView()) content.WriteString("\n\n") content.WriteString(m.installMenuList.View()) content.WriteString("\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to select, ")) content.WriteString(subtitleStyle.Render("↑/↓")) content.WriteString(infoStyle.Render(" to navigate, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to go back to main menu")) } else if m.state == StateInstalling { content.WriteString(m.installingView()) } else if m.state == StateUpdateInstaller { content.WriteString(m.updateInstallerView()) } else if m.state == StateUpdates { content.WriteString(m.updatesView()) } else if m.state == StateUninstall { content.WriteString(m.uninstallView()) } else if m.state == StateInstallToPath { content.WriteString(m.installToPathView()) } else if m.state == StateSuccess { content.WriteString(m.successView()) } else if m.state == StateError { content.WriteString(m.errorView()) } else if m.state == StateLanguagePreferences { content.WriteString(m.langPreferenceSelectView()) } else if m.state == StateLanguageMajorSelect { content.WriteString(m.majorLangSelectViewRaw()) } else if m.state == StateLanguageRegionSelect { content.WriteString(m.regionLangSelectViewRaw()) } else if m.state == StateLanguageSelectedList { content.WriteString(m.selectedLangListViewRaw()) } else if m.state == StateLanguageConfirm { content.WriteString(m.languageConfirmView()) } else if m.state == StateConfigOptions { content.WriteString(m.configOptionsListView()) } else if m.state == StateFileAssociations { return m.installingView() } else if m.state == StateFileAssociationsMenu { content.WriteString(m.fileAssociationsListView()) } else if m.state == StateHWAOptions { content.WriteString(m.hwaOptionsListView()) } else if m.state == StateScreenshotOptions { content.WriteString(m.screenshotOptionsListView()) // Screenshot value selection views (dropdown lists) } else if m.state == StateScreenshotFormatEdit || m.state == StateScreenshotTagColorspaceEdit || m.state == StateScreenshotHighBitDepthEdit || m.state == StateScreenshotJpegQualityEdit || m.state == StateScreenshotPngCompressionEdit || m.state == StateScreenshotWebpLosslessEdit || m.state == StateScreenshotWebpQualityEdit || m.state == StateScreenshotJxlDistanceEdit || m.state == StateScreenshotAvifEncoderEdit || m.state == StateScreenshotAvifPixfmtEdit || m.state == StateSavePositionOnQuitEdit { content.WriteString(m.screenshotValueListView()) // Screenshot text input views } else if m.state == StateScreenshotTemplateEdit || m.state == StateScreenshotDirectoryEdit || m.state == StateScreenshotAvifOptsEdit { content.WriteString(m.screenshotTextInputView()) } else if m.state == StateRestoreConfig { content.WriteString(m.restoreConfigListView()) } else if m.state == StateWebUIMenu { content.WriteString(m.webUIMenuListView()) } else if m.state == StateHotkeysCategory { content.WriteString(m.hotkeysCategoryListView()) } else if m.state == StateHotkeys { content.WriteString(m.hotkeysListView()) } else if m.state == StateHotkeysPreset { content.WriteString(m.hotkeysPresetListView()) } else if m.state == StateUISelect { content.WriteString(m.uiSelectListView()) } mainContent := content.String() footer := m.footerView() return lipgloss.JoinVertical(lipgloss.Left, mainContent, "", footer) } func (m Model) successView() string { var content strings.Builder if m.loadingConfig { content.WriteString(titleStyle.Render("Configuration Loaded")) content.WriteString("\n") content.WriteString(subtitleStyle.Render("════════════════")) content.WriteString("\n\n") content.WriteString(successStyle.Render("✓ Configuration loaded successfully!")) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Your MPV configuration has been updated.")) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to exit, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to return to main menu")) } return m.wrapContentInViewport(content.String()) } func (m Model) updateCheckView() string { return infoStyle.Render("Checking for updates...") } func (m Model) updateInstallerView() string { var content strings.Builder content.WriteString(titleStyle.Render("Update MPV Manager")) content.WriteString("\n") content.WriteString(subtitleStyle.Render("═══════════════")) content.WriteString("\n\n") if m.versionCheckResult == nil { content.WriteString(infoStyle.Render("Checking for updates...")) } else if m.versionCheckResult.Error != nil { content.WriteString(errorStyle.Render(fmt.Sprintf("Error: %v", m.versionCheckResult.Error))) } else if m.versionCheckResult.UpdateAvailable { content.WriteString(successStyle.Render("Update available!")) content.WriteString("\n\n") content.WriteString(infoStyle.Render(fmt.Sprintf("Current version: %s", m.versionCheckResult.CurrentVersion))) content.WriteString("\n") content.WriteString(infoStyle.Render(fmt.Sprintf("Latest version: %s", m.versionCheckResult.LatestVersion))) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("U")) content.WriteString(infoStyle.Render(" to update, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to return to main menu")) } else { content.WriteString(successStyle.Render("Installer is up to date!")) content.WriteString("\n\n") content.WriteString(infoStyle.Render(fmt.Sprintf("Current version: %s", m.versionCheckResult.CurrentVersion))) content.WriteString("\n") content.WriteString(infoStyle.Render(fmt.Sprintf("Latest version: %s", m.versionCheckResult.LatestVersion))) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to return to main menu")) return m.wrapContentInViewport(content.String()) } return m.wrapContentInViewport(content.String()) } func (m Model) updatesView() string { return m.updatesListView() } func (m Model) updatesListView() string { var content strings.Builder content.WriteString(titleStyle.Render("Updates")) content.WriteString("\n") content.WriteString(subtitleStyle.Render("════════")) content.WriteString("\n\n") if len(m.updateList.Items()) == 0 { if m.versionCheckResult == nil && m.updateCheckResult == nil { content.WriteString(infoStyle.Render("Checking for updates...")) } else if m.versionCheckResult != nil { if m.versionCheckResult.Error != nil { content.WriteString(errorStyle.Render(fmt.Sprintf("Error: %v", m.versionCheckResult.Error))) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to return to main menu")) } else if m.versionCheckResult.UpdateAvailable { content.WriteString(successStyle.Render("Update available!")) content.WriteString("\n\n") content.WriteString(infoStyle.Render(fmt.Sprintf("Current version: %s", m.versionCheckResult.CurrentVersion))) content.WriteString("\n") content.WriteString(infoStyle.Render(fmt.Sprintf("Latest version: %s", m.versionCheckResult.LatestVersion))) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to return to main menu")) } else { content.WriteString(successStyle.Render("Installer is up to date!")) content.WriteString("\n\n") content.WriteString(infoStyle.Render(fmt.Sprintf("Current version: %s", m.versionCheckResult.CurrentVersion))) content.WriteString("\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to return to main menu")) } } else if m.updateCheckResult != nil { content.WriteString(infoStyle.Render("No MPV installations found.")) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Update via app or website")) content.WriteString("\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to return to main menu")) } return m.wrapContentInViewport(content.String()) } content.WriteString(m.updateList.View()) content.WriteString("\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to select, ")) content.WriteString(subtitleStyle.Render("↑/↓")) content.WriteString(infoStyle.Render(" to navigate, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to go back to main menu")) return m.wrapContentInViewport(content.String()) } func (m Model) restoreConfigListView() string { var content strings.Builder content.WriteString(titleStyle.Render("Restore MPV Config Backup")) content.WriteString("\n") content.WriteString(subtitleStyle.Render("════════════════════════")) content.WriteString("\n\n") if len(m.restoreConfigList.Items()) == 0 { content.WriteString(infoStyle.Render("No config backups found.")) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Backups are stored in:")) content.WriteString("\n") content.WriteString(subtitleStyle.Render(" ~/.config/mpv/conf_backups")) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to return to main menu")) return m.wrapContentInViewport(content.String()) } content.WriteString(m.restoreConfigList.View()) content.WriteString("\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to select, ")) content.WriteString(subtitleStyle.Render("↑/↓")) content.WriteString(infoStyle.Render(" to navigate, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to go back")) return m.wrapContentInViewport(content.String()) } func (m Model) fileAssociationsListView() string { var content strings.Builder content.WriteString(titleStyle.Render("File Associations")) content.WriteString("\n") content.WriteString(subtitleStyle.Render("═════════════════")) content.WriteString("\n\n") content.WriteString(m.fileAssociationsList.View()) content.WriteString("\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to select, ")) content.WriteString(subtitleStyle.Render("↑/↓")) content.WriteString(infoStyle.Render(" to navigate, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to go back")) return m.wrapContentInViewport(content.String()) } func (m Model) uninstallView() string { var content strings.Builder content.WriteString(titleStyle.Render("Uninstall MPV")) content.WriteString("\n") content.WriteString(subtitleStyle.Render("═════════════")) content.WriteString("\n\n") if m.uninstallList.Items() == nil || len(m.uninstallList.Items()) == 0 { content.WriteString(infoStyle.Render("Loading installed applications...")) return m.wrapContentInViewport(content.String()) } content.WriteString(infoStyle.Render("Select an application to uninstall:")) content.WriteString("\n\n") content.WriteString(m.uninstallList.View()) return m.wrapContentInViewport(content.String()) } func (m Model) installToPathView() string { var content strings.Builder isRemoving := isInstallMPVInPATH() var title string if isRemoving { title = "Remove mpv-manager from PATH" } else { title = "Add mpv-manager to your PATH" } content.WriteString(titleStyle.Render(title)) content.WriteString("\n") content.WriteString(subtitleStyle.Render("═══════════════════")) content.WriteString("\n\n") if isRemoving { content.WriteString(infoStyle.Render("This will remove the mpv-manager binary from your user's bin directory.")) content.WriteString("\n\n") content.WriteString(infoStyle.Render("The binary will be removed from:")) content.WriteString("\n") content.WriteString(" ") content.WriteString(subtitleStyle.Render(getUserBinDir())) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to remove, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to cancel")) } else { content.WriteString(infoStyle.Render("This will add the mpv-manager binary to your user's bin directory,")) content.WriteString("\n") content.WriteString(infoStyle.Render("making it accessible from anywhere in your terminal.")) content.WriteString("\n\n") content.WriteString(infoStyle.Render("After installation, you can run the app by typing:")) content.WriteString("\n") content.WriteString(" ") content.WriteString(subtitleStyle.Render("mpv-install")) content.WriteString("\n") content.WriteString(" ") content.WriteString(subtitleStyle.Render("mpv-manager")) content.WriteString("\n\n") content.WriteString(infoStyle.Render("The binary will be installed to:")) content.WriteString("\n") content.WriteString(" ") content.WriteString(subtitleStyle.Render(getUserBinDir())) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to install, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to cancel")) } return m.wrapContentInViewport(content.String()) } func (m Model) installingView() string { var content strings.Builder isUninstall := m.selectedUninstall != nil isPathInstall := m.currentCommand == "Installing mpv-manager to PATH" isPathRemove := m.currentCommand == "Removing mpv-manager from PATH" isUpdate := strings.HasPrefix(m.currentCommand, "Updating") isConfigRestore := m.selectedRestoreBackup != nil var title string if isPathInstall { title = "Installing to PATH" } else if isPathRemove { title = "Removing from PATH" } else if isUninstall { title = "Uninstalling MPV" } else if isUpdate { title = "Updating MPV" } else if isConfigRestore { title = "Restoring MPV Config" } else { title = "Installing MPV" } content.WriteString(titleStyle.Render(title)) content.WriteString("\n") content.WriteString(subtitleStyle.Render("═════════════")) content.WriteString("\n\n") if m.currentCommand != "" { content.WriteString(infoStyle.Render("Command: ")) content.WriteString(subtitleStyle.Render(m.currentCommand)) content.WriteString("\n\n") } if isUpdate && m.downloadTotal > 0 && !m.installComplete { content.WriteString(infoStyle.Render("Download progress:")) content.WriteString("\n") percent := float64(m.downloadWritten) / float64(m.downloadTotal) * 100 progress := progress.New(progress.WithDefaultGradient(), progress.WithWidth(40)) progStr := progress.ViewAs(percent) content.WriteString(progStr) content.WriteString("\n") writtenMB := float64(m.downloadWritten) / 1024 / 1024 totalMB := float64(m.downloadTotal) / 1024 / 1024 content.WriteString(infoStyle.Render(fmt.Sprintf("%.2f MB / %.2f MB", writtenMB, totalMB))) content.WriteString("\n\n") } outputStyle := lipgloss.NewStyle(). Foreground(white). Background(black). Border(lipgloss.RoundedBorder()). BorderForeground(gray). Padding(1) content.WriteString(outputStyle.Render(m.outputViewport.View())) content.WriteString("\n\n") if m.installComplete { var clientName string if isPathInstall || isPathRemove { clientName = "mpv-manager" } else if isUninstall && m.selectedUninstall != nil { clientName = m.selectedUninstall.AppName } else { clientName = getClientName(m.selectedMethodID, m.selectedMethod) } if m.installError != nil { content.WriteString(errorStyle.Render("✗ An error occurred")) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Error: ")) content.WriteString(errorStyle.Render(m.installError.Error())) content.WriteString("\n") } else { if isPathInstall { content.WriteString(successStyle.Render(fmt.Sprintf("✓ Success - %s installed to PATH", clientName))) content.WriteString("\n\n") content.WriteString(infoStyle.Render("You can now run the app from anywhere by typing:")) content.WriteString("\n") content.WriteString(" ") content.WriteString(subtitleStyle.Render("mpv-install")) content.WriteString("\n") content.WriteString(" ") content.WriteString(subtitleStyle.Render("mpv-manager")) content.WriteString("\n") } else if isPathRemove { content.WriteString(successStyle.Render(fmt.Sprintf("✓ Success - %s removed from PATH", clientName))) content.WriteString("\n\n") content.WriteString(infoStyle.Render("The application has been successfully removed from your PATH.")) content.WriteString("\n") } else if isUninstall { content.WriteString(successStyle.Render(fmt.Sprintf("✓ Success - %s uninstalled", clientName))) content.WriteString("\n\n") content.WriteString(infoStyle.Render("The application has been successfully removed.")) content.WriteString("\n") } else if isUpdate { content.WriteString(successStyle.Render("✓ Installer Updated Successfully!")) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Please restart the application to use the new version.")) content.WriteString("\n") } else if isConfigRestore { content.WriteString(successStyle.Render("✓ Success - MPV Config Restored")) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Your configuration has been restored from backup.")) content.WriteString("\n") } else { content.WriteString(successStyle.Render(fmt.Sprintf("✓ Success - %s installed", clientName))) content.WriteString("\n\n") if m.postInstallMessage != "" { content.WriteString(warningStyle.Render("⚠️ " + m.postInstallMessage)) content.WriteString("\n\n") } content.WriteString(infoStyle.Render("You can now run MPV. Enjoy watching videos!")) content.WriteString("\n") } } content.WriteString("\n") if isUpdate && m.installError == nil { content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to restart application")) } else { content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" or ")) content.WriteString(subtitleStyle.Render("ESC")) content.WriteString(infoStyle.Render(" to return to Main Menu")) } } else { content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Ctrl+C")) content.WriteString(infoStyle.Render(" to cancel")) } return m.wrapContentInViewport(content.String()) } func (m Model) helpView() string { var help strings.Builder help.WriteString(titleStyle.Render("Help")) help.WriteString("\n") help.WriteString(subtitleStyle.Render("═══════\n")) help.WriteString(infoStyle.Render("Navigation:")) help.WriteString("\n") help.WriteString(infoStyle.Render(" ↑/↓ - Navigate menu items")) help.WriteString("\n") help.WriteString(infoStyle.Render(" Enter - Select and install")) help.WriteString("\n") help.WriteString(infoStyle.Render(" Esc - Go back")) help.WriteString("\n") help.WriteString(infoStyle.Render(" Ctrl+C - Quit")) help.WriteString("\n") help.WriteString(subtitleStyle.Render("Commands:\n")) help.WriteString("\n") help.WriteString(infoStyle.Render(" Ctrl+H - Show/hide this help")) help.WriteString("\n") help.WriteString(infoStyle.Render(" Ctrl+V - Show/hide version info")) help.WriteString("\n") help.WriteString(infoStyle.Render("\n")) help.WriteString(subtitleStyle.Render("═══════\n")) help.WriteString(infoStyle.Render("For more information, visit ")) help.WriteString(linkStyle.Render("https://mpv.rocks")) help.WriteString("\n") help.WriteString(subtitleStyle.Render("═══════\n")) help.WriteString(infoStyle.Render("Press Ctrl+H to return")) help.WriteString("\n") return helpStyle.Render(help.String()) } func (m Model) versionView() string { var version strings.Builder version.WriteString(titleStyle.Render("Version Information")) version.WriteString("\n") version.WriteString(subtitleStyle.Render("═════════════════")) version.WriteString("\n") version.WriteString(infoStyle.Render(fmt.Sprintf("Version: %s", "0.1.0"))) version.WriteString("\n") version.WriteString(infoStyle.Render(fmt.Sprintf("Go Version: %s", "1.21"))) version.WriteString("\n") version.WriteString(infoStyle.Render(fmt.Sprintf("Platform: %s", "linux/amd64"))) version.WriteString("\n") version.WriteString(infoStyle.Render(fmt.Sprintf("Repository: %s", "https://gitgud.io/mike/mpv-manager"))) version.WriteString("\n") version.WriteString(infoStyle.Render("Press Ctrl+V to return")) version.WriteString("\n") return infoStyle.Render(version.String()) } func (m Model) configOptionsListView() string { var content strings.Builder content.WriteString(m.configOptionsList.View()) content.WriteString("\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to select, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to go back")) return content.String() } func (m Model) hwaOptionsListView() string { var content strings.Builder content.WriteString(titleStyle.Render("Hardware Acceleration")) content.WriteString("\n") content.WriteString(subtitleStyle.Render("═════════════════════")) content.WriteString("\n\n") if m.platform.HWA != "" { content.WriteString(infoStyle.Render(fmt.Sprintf("Supported Codecs: %s", m.platform.HWA))) content.WriteString("\n\n") } // Show current HWA status currentHWA := m.getCurrentHWAValue() content.WriteString(titleStyle.Render("Current:")) content.WriteString(" ") if currentHWA == "" || currentHWA == "no" { content.WriteString(errorStyle.Render("Disabled")) } else { content.WriteString(successStyle.Render(fmt.Sprintf("Enabled (%s)", currentHWA))) } content.WriteString("\n\n") content.WriteString(m.hwaOptionsList.View()) content.WriteString("\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to apply, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to go back")) return content.String() } func (m Model) screenshotOptionsListView() string { var content strings.Builder content.WriteString(titleStyle.Render("Screenshot Settings")) content.WriteString("\n") content.WriteString(subtitleStyle.Render("═════════════════════")) content.WriteString("\n\n") content.WriteString(m.screenshotOptionsList.View()) content.WriteString("\n") if m.errorMessage != "" { content.WriteString(warningStyle.Render(m.errorMessage)) content.WriteString("\n\n") m.errorMessage = "" // Clear after displaying } content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to view current value, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to return")) return content.String() } func (m Model) screenshotValueListView() string { var content strings.Builder content.WriteString(titleStyle.Render("Select Value")) content.WriteString("\n") content.WriteString(subtitleStyle.Render("════════════")) content.WriteString("\n\n") content.WriteString(m.screenshotValueList.View()) content.WriteString("\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to select value, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to go back")) return content.String() } func (m Model) screenshotTextInputView() string { var content strings.Builder content.WriteString(titleStyle.Render("Enter Value")) content.WriteString("\n") content.WriteString(subtitleStyle.Render("════════════")) content.WriteString("\n\n") content.WriteString(m.screenshotTextInput.View()) content.WriteString("\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to save, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to cancel")) return content.String() } func (m Model) webUIMenuListView() string { var content strings.Builder content.WriteString(m.webUIList.View()) content.WriteString("\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to create shortcut, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to go back")) return content.String() } func (m Model) uiSelectListView() string { var content strings.Builder content.WriteString(titleStyle.Render("Select UI Overlay")) content.WriteString("\n") content.WriteString(subtitleStyle.Render("══════════════════")) content.WriteString("\n\n") if m.pendingAppName != "" { content.WriteString(infoStyle.Render(fmt.Sprintf("Choose a UI overlay for %s:", m.pendingAppName))) } else { content.WriteString(infoStyle.Render("Choose a UI overlay:")) } content.WriteString("\n\n") content.WriteString(m.uiSelectList.View()) content.WriteString("\n\n") content.WriteString(infoStyle.Render("Press ")) content.WriteString(subtitleStyle.Render("Enter")) content.WriteString(infoStyle.Render(" to select, ")) content.WriteString(subtitleStyle.Render("↑/↓")) content.WriteString(infoStyle.Render(" to navigate, ")) content.WriteString(subtitleStyle.Render("Esc")) content.WriteString(infoStyle.Render(" to go back")) return content.String() } func (m Model) footerView() string { var footer strings.Builder footer.WriteString(infoStyle.Render("Press ")) footer.WriteString(subtitleStyle.Render("Ctrl+H")) footer.WriteString(infoStyle.Render(" for help, ")) footer.WriteString(subtitleStyle.Render("Ctrl+V")) footer.WriteString(infoStyle.Render(" for version, ")) footer.WriteString(subtitleStyle.Render("Ctrl+C")) footer.WriteString(infoStyle.Render(" to quit\n")) footer.WriteString(infoStyle.Render("Visit us at ")) footer.WriteString(linkStyle.Render("https://mpv.rocks")) return footerStyle.Render(footer.String()) } func (m Model) wrapContentInViewport(content string) string { vp := viewport.New(m.termWidth, m.termHeight-6) vp.SetContent(content) return vp.View() }