forked from SpoTUI/SpoTUI
697 lines
22 KiB
PowerShell
697 lines
22 KiB
PowerShell
$ThemeName = "SpoTUI"
|
|
$RepoUrl = "https://github.com/SkenSMasteR/SpoTUI"
|
|
$ThemesDir = Join-Path $env:APPDATA "spicetify\Themes"
|
|
$ThemePath = Join-Path $ThemesDir $ThemeName
|
|
|
|
$Esc = [char]27
|
|
$Reset = "$Esc[0m"
|
|
$AnsiPattern = "$Esc\[[0-9;]*m"
|
|
|
|
$BlockFull = [char]0x2588
|
|
$BlockLower = [char]0x2584
|
|
$BlockUpper = [char]0x2580
|
|
$BlockLeft = [char]0x258C
|
|
|
|
function Enable-VTMode {
|
|
$sig = @"
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
public static class SpoTUINative {
|
|
[DllImport("kernel32.dll")]
|
|
public static extern IntPtr GetStdHandle(int nStdHandle);
|
|
[DllImport("kernel32.dll")]
|
|
public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
|
|
[DllImport("kernel32.dll")]
|
|
public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
|
|
}
|
|
"@
|
|
try {
|
|
Add-Type -TypeDefinition $sig -ErrorAction SilentlyContinue
|
|
$handle = [SpoTUINative]::GetStdHandle(-11)
|
|
$mode = 0
|
|
[SpoTUINative]::GetConsoleMode($handle, [ref]$mode) | Out-Null
|
|
[SpoTUINative]::SetConsoleMode($handle, $mode -bor 0x0004) | Out-Null
|
|
} catch {}
|
|
}
|
|
Enable-VTMode
|
|
|
|
try {
|
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
} catch {}
|
|
|
|
function Get-RGBCode($r, $g, $b) {
|
|
return "$Esc[38;2;$r;$g;${b}m"
|
|
}
|
|
|
|
$OrangeLight = Get-RGBCode 255 140 66
|
|
$OrangeDark = Get-RGBCode 224 123 57
|
|
$OrangeMid = Get-RGBCode 240 131 61
|
|
$GreenAnsi = Get-RGBCode 140 255 140
|
|
$SelectBg = "$Esc[48;2;255;140;66m$Esc[38;2;0;0;0m"
|
|
|
|
$White = "White"
|
|
$Gray = "DarkGray"
|
|
$Red = "Red"
|
|
$Green = "Green"
|
|
$Cyan = "Cyan"
|
|
|
|
# Tracks whether we've already attempted a winget update this session,
|
|
# so Test-Dependencies doesn't re-run it on every menu action.
|
|
$script:WingetUpdateAttempted = $false
|
|
|
|
function Get-GradientColor($index, $total) {
|
|
$r1 = 255; $g1 = 140; $b1 = 66
|
|
$r2 = 224; $g2 = 123; $b2 = 57
|
|
$t = if ($total -le 1) { 0 } else { $index / ($total - 1) }
|
|
$r = [int]($r1 + ($r2 - $r1) * $t)
|
|
$g = [int]($g1 + ($g2 - $g1) * $t)
|
|
$b = [int]($b1 + ($b2 - $b1) * $t)
|
|
return Get-RGBCode $r $g $b
|
|
}
|
|
|
|
function Get-AsciiArtLine($template) {
|
|
$out = $template
|
|
$out = $out.Replace("A", $BlockFull)
|
|
$out = $out.Replace("B", $BlockLower)
|
|
$out = $out.Replace("C", $BlockUpper)
|
|
$out = $out.Replace("D", $BlockLeft)
|
|
return $out
|
|
}
|
|
|
|
function Get-HeaderLines {
|
|
$lines = @()
|
|
$lines += ""
|
|
$templates = @(
|
|
" BAAAAAAAA BAAAAAAAB BAAAAAAAB AAA AAA AB BA ",
|
|
" AAA AAA AAA AAA AAA AAA CAAAAAAAAAB AAA AAA AAA ",
|
|
" AAA AC AAA AAA AAA AAA CAAACCAA AAA AAA AAAD ",
|
|
" AAA AAA AAA AAA AAA AAA C AAA AAA AAAD ",
|
|
"CAAAAAAAAAAA CAAAAAAAAAC AAA AAA AAA AAA AAA AAAD ",
|
|
" AAA AAA AAA AAA AAA AAA AAA AAA ",
|
|
" BA AAA AAA AAA AAA AAA AAA AAA AAA ",
|
|
" BAAAAAAAAC BAAAAC CAAAAAAC BAAAAC AAAAAAAAC AC "
|
|
)
|
|
for ($i = 0; $i -lt $templates.Count; $i++) {
|
|
$color = Get-GradientColor $i $templates.Count
|
|
$line = Get-AsciiArtLine $templates[$i]
|
|
$lines += "$color$line$Reset"
|
|
}
|
|
$lines += ""
|
|
$lines += "$OrangeMid Spicetify Theme Manager$Reset"
|
|
$lines += "$OrangeDark =============================================================$Reset"
|
|
$lines += ""
|
|
return $lines
|
|
}
|
|
|
|
function Show-Header {
|
|
Clear-Host
|
|
foreach ($line in (Get-HeaderLines)) {
|
|
Write-Host $line
|
|
}
|
|
}
|
|
|
|
function Get-VisibleLength($text) {
|
|
$stripped = $text -replace $AnsiPattern, ""
|
|
return $stripped.Length
|
|
}
|
|
|
|
function Write-Frame($lines) {
|
|
try { [Console]::SetCursorPosition(0, 0) } catch {}
|
|
$width = 80
|
|
try { $width = $Host.UI.RawUI.WindowSize.Width } catch {}
|
|
foreach ($line in $lines) {
|
|
$visible = Get-VisibleLength $line
|
|
$pad = $width - $visible - 1
|
|
if ($pad -lt 0) { $pad = 0 }
|
|
Write-Host ($line + (" " * $pad))
|
|
}
|
|
}
|
|
|
|
function Get-ConsoleHeight {
|
|
$height = 30
|
|
try { $height = $Host.UI.RawUI.WindowSize.Height } catch {}
|
|
return $height
|
|
}
|
|
|
|
function Refresh-Path {
|
|
$machinePath = [System.Environment]::GetEnvironmentVariable("Path", "Machine")
|
|
$userPath = [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
$env:Path = "$machinePath;$userPath"
|
|
}
|
|
|
|
function Update-Winget {
|
|
Write-Host "$OrangeMid Updating winget...$Reset"
|
|
|
|
if (Get-Command winget -ErrorAction SilentlyContinue) {
|
|
try {
|
|
$proc = Start-Process -FilePath "winget" -ArgumentList "upgrade","--id","Microsoft.AppInstaller","-e","--source","winget","--accept-package-agreements","--accept-source-agreements" -Wait -PassThru -WindowStyle Hidden
|
|
Write-Host " winget upgrade exited with code $($proc.ExitCode)" -ForegroundColor $Gray
|
|
} catch {
|
|
Write-Host " winget upgrade command failed to run." -ForegroundColor $Red
|
|
}
|
|
|
|
try {
|
|
winget source reset --force | Out-Null
|
|
} catch {}
|
|
|
|
return
|
|
}
|
|
|
|
Write-Host " winget command not found. Installing App Installer from GitHub release..." -ForegroundColor $Gray
|
|
try {
|
|
$release = Invoke-RestMethod -Uri "https://api.github.com/repos/microsoft/winget-cli/releases/latest"
|
|
$asset = $release.assets | Where-Object { $_.name -like "*.msixbundle" } | Select-Object -First 1
|
|
|
|
if (-not $asset) {
|
|
Write-Host " Could not find a .msixbundle asset in the latest release." -ForegroundColor $Red
|
|
return
|
|
}
|
|
|
|
$downloadPath = Join-Path $env:TEMP $asset.name
|
|
Write-Host " Downloading $($asset.name)..." -ForegroundColor $Gray
|
|
Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $downloadPath
|
|
|
|
Write-Host " Installing package..." -ForegroundColor $Gray
|
|
Add-AppxPackage -Path $downloadPath -ErrorAction Stop
|
|
|
|
Write-Host " App Installer installed successfully." -ForegroundColor $Green
|
|
Remove-Item $downloadPath -Force -ErrorAction SilentlyContinue
|
|
}
|
|
catch {
|
|
Write-Host " Failed to install App Installer automatically: $($_.Exception.Message)" -ForegroundColor $Red
|
|
Write-Host " You can install it manually from the Microsoft Store (search 'App Installer')." -ForegroundColor $Gray
|
|
}
|
|
|
|
Refresh-Path
|
|
}
|
|
|
|
function Install-Dependency($name) {
|
|
if ($name -eq "git") {
|
|
if (Get-Command winget -ErrorAction SilentlyContinue) {
|
|
Write-Host " Launching winget to install Git..." -ForegroundColor $Gray
|
|
$proc = Start-Process -FilePath "winget" -ArgumentList "install","--id","Git.Git","-e","--source","winget","--accept-package-agreements","--accept-source-agreements" -Wait -PassThru
|
|
Write-Host " winget exited with code $($proc.ExitCode)" -ForegroundColor $Gray
|
|
|
|
# 0xC0000005 = access violation / winget crash. Update winget once and retry.
|
|
if ($proc.ExitCode -eq -1073741819 -and -not $script:WingetUpdateAttempted) {
|
|
Write-Host " winget crashed. Attempting to update winget and retry..." -ForegroundColor $Red
|
|
$script:WingetUpdateAttempted = $true
|
|
Update-Winget
|
|
|
|
Write-Host " Retrying Git install..." -ForegroundColor $Gray
|
|
$proc = Start-Process -FilePath "winget" -ArgumentList "install","--id","Git.Git","-e","--source","winget","--accept-package-agreements","--accept-source-agreements" -Wait -PassThru
|
|
Write-Host " winget exited with code $($proc.ExitCode)" -ForegroundColor $Gray
|
|
}
|
|
|
|
Refresh-Path
|
|
$tries = 0
|
|
while (-not (Get-Command git -ErrorAction SilentlyContinue) -and $tries -lt 10) {
|
|
Start-Sleep -Seconds 1
|
|
Refresh-Path
|
|
$tries++
|
|
}
|
|
}
|
|
else {
|
|
Write-Host " winget was not found. Install Git manually from https://git-scm.com/download/win" -ForegroundColor $Red
|
|
}
|
|
}
|
|
elseif ($name -eq "spicetify") {
|
|
$installCommand = "iwr -useb https://raw.githubusercontent.com/spicetify/cli/main/install.ps1 | iex"
|
|
Write-Host " Opening a new window to install Spicetify. Waiting for it to finish..." -ForegroundColor $Gray
|
|
Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", $installCommand -Wait
|
|
Write-Host " Spicetify installer window closed." -ForegroundColor $Gray
|
|
Refresh-Path
|
|
}
|
|
}
|
|
|
|
function Test-Dependencies {
|
|
$missing = @()
|
|
if (-not (Get-Command git -ErrorAction SilentlyContinue)) { $missing += "git" }
|
|
if (-not (Get-Command spicetify -ErrorAction SilentlyContinue)) { $missing += "spicetify" }
|
|
|
|
if ($missing.Count -eq 0) {
|
|
return $true
|
|
}
|
|
|
|
Write-Host " Missing dependencies: $($missing -join ', ')" -ForegroundColor $Red
|
|
Write-Host ""
|
|
$confirm = Read-Host " Press I to install them now, or any other key to cancel"
|
|
if ($confirm -ne "I" -and $confirm -ne "i") {
|
|
return $false
|
|
}
|
|
|
|
foreach ($dep in $missing) {
|
|
Write-Host ""
|
|
Write-Host "$OrangeMid Installing $dep...$Reset"
|
|
Install-Dependency $dep
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "$OrangeMid Refreshing environment PATH...$Reset"
|
|
Refresh-Path
|
|
|
|
$stillMissing = @()
|
|
if (-not (Get-Command git -ErrorAction SilentlyContinue)) { $stillMissing += "git" }
|
|
if (-not (Get-Command spicetify -ErrorAction SilentlyContinue)) { $stillMissing += "spicetify" }
|
|
|
|
if ($stillMissing.Count -gt 0) {
|
|
Write-Host ""
|
|
Write-Host " Still missing: $($stillMissing -join ', '). You may need to restart your terminal." -ForegroundColor $Red
|
|
return $false
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host " All dependencies installed successfully." -ForegroundColor $Green
|
|
return $true
|
|
}
|
|
|
|
function Get-DefaultBranch {
|
|
Push-Location $ThemePath
|
|
$ref = git symbolic-ref refs/remotes/origin/HEAD 2>$null
|
|
Pop-Location
|
|
if ($ref) {
|
|
$parts = $ref -split "/"
|
|
return $parts[$parts.Count - 1]
|
|
}
|
|
return "main"
|
|
}
|
|
|
|
function Test-IsDetached {
|
|
Push-Location $ThemePath
|
|
git symbolic-ref -q HEAD | Out-Null
|
|
$attached = $?
|
|
Pop-Location
|
|
return -not $attached
|
|
}
|
|
|
|
function Get-ThemeStatusDetailed {
|
|
if (-not (Test-Path $ThemePath)) {
|
|
return @{ Text = "Not Installed"; Color = $Red }
|
|
}
|
|
|
|
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
|
|
return @{ Text = "Installed"; Color = $Green }
|
|
}
|
|
|
|
Push-Location $ThemePath
|
|
git fetch origin --quiet 2>$null
|
|
$localHash = (git rev-parse HEAD 2>$null)
|
|
Pop-Location
|
|
|
|
if (Test-IsDetached) {
|
|
$shortHash = if ($localHash) { $localHash.Substring(0, 7) } else { "unknown" }
|
|
return @{ Text = "Installed (custom commit $shortHash)"; Color = $Cyan }
|
|
}
|
|
|
|
$branch = Get-DefaultBranch
|
|
Push-Location $ThemePath
|
|
$remoteHash = (git rev-parse "origin/$branch" 2>$null)
|
|
Pop-Location
|
|
|
|
if (-not $localHash -or -not $remoteHash) {
|
|
return @{ Text = "Installed"; Color = $Green }
|
|
}
|
|
|
|
if ($localHash -eq $remoteHash) {
|
|
return @{ Text = "Installed (up to date)"; Color = $Green }
|
|
}
|
|
|
|
return @{ Text = "Installed (outdated)"; Color = $Red }
|
|
}
|
|
|
|
function Install-Theme {
|
|
Show-Header
|
|
Write-Host "$OrangeLight Installing $ThemeName...$Reset"
|
|
Write-Host ""
|
|
|
|
if (-not (Test-Dependencies)) {
|
|
Pause-Return
|
|
return
|
|
}
|
|
|
|
if (-not (Test-Path $ThemesDir)) {
|
|
New-Item -ItemType Directory -Path $ThemesDir -Force | Out-Null
|
|
}
|
|
|
|
if (Test-Path $ThemePath) {
|
|
Write-Host "$OrangeMid Theme already exists locally. Pulling latest changes...$Reset"
|
|
Push-Location $ThemePath
|
|
git pull
|
|
Pop-Location
|
|
}
|
|
else {
|
|
Push-Location $ThemesDir
|
|
git clone $RepoUrl $ThemeName
|
|
Pop-Location
|
|
}
|
|
|
|
if (Test-Path $ThemePath) {
|
|
Write-Host ""
|
|
Write-Host "$OrangeMid Setting current theme to $ThemeName...$Reset"
|
|
spicetify config current_theme $ThemeName
|
|
|
|
Write-Host "$OrangeMid Applying Spicetify...$Reset"
|
|
spicetify apply
|
|
|
|
Write-Host ""
|
|
Write-Host " $ThemeName installed and applied successfully." -ForegroundColor $Green
|
|
}
|
|
else {
|
|
Write-Host ""
|
|
Write-Host " Installation failed. Check the errors above." -ForegroundColor $Red
|
|
}
|
|
|
|
Pause-Return
|
|
}
|
|
|
|
function Update-Theme {
|
|
Show-Header
|
|
Write-Host "$OrangeLight Updating $ThemeName...$Reset"
|
|
Write-Host ""
|
|
|
|
if (-not (Test-Path $ThemePath)) {
|
|
Write-Host " $ThemeName is not installed. Use Install instead." -ForegroundColor $Red
|
|
Pause-Return
|
|
return
|
|
}
|
|
|
|
if (-not (Test-Dependencies)) {
|
|
Pause-Return
|
|
return
|
|
}
|
|
|
|
if (Test-IsDetached) {
|
|
$branch = Get-DefaultBranch
|
|
Write-Host "$OrangeMid Currently on a custom commit. Returning to $branch...$Reset"
|
|
Push-Location $ThemePath
|
|
git checkout $branch --quiet
|
|
Pop-Location
|
|
}
|
|
|
|
Push-Location $ThemePath
|
|
git pull
|
|
Pop-Location
|
|
|
|
Write-Host ""
|
|
Write-Host "$OrangeMid Re-applying Spicetify...$Reset"
|
|
spicetify apply
|
|
|
|
Write-Host ""
|
|
Write-Host " $ThemeName updated successfully." -ForegroundColor $Green
|
|
Pause-Return
|
|
}
|
|
|
|
function Uninstall-Theme {
|
|
Show-Header
|
|
Write-Host "$OrangeLight Uninstalling $ThemeName...$Reset"
|
|
Write-Host ""
|
|
|
|
if (-not (Test-Path $ThemePath)) {
|
|
Write-Host " $ThemeName is not installed." -ForegroundColor $Red
|
|
Pause-Return
|
|
return
|
|
}
|
|
|
|
Write-Host " This will remove the theme folder and switch to Marketplace." -ForegroundColor $Gray
|
|
$confirm = Read-Host " Type Y to confirm"
|
|
if ($confirm -ne "Y" -and $confirm -ne "y") {
|
|
Write-Host " Cancelled." -ForegroundColor $Gray
|
|
Pause-Return
|
|
return
|
|
}
|
|
|
|
if (Get-Command spicetify -ErrorAction SilentlyContinue) {
|
|
Write-Host "$OrangeMid Switching Spicetify theme...$Reset"
|
|
spicetify config current_theme SpoTUI-
|
|
spicetify config current_theme marketplace
|
|
spicetify apply
|
|
}
|
|
|
|
Remove-Item -Path $ThemePath -Recurse -Force
|
|
|
|
Write-Host ""
|
|
Write-Host " $ThemeName has been uninstalled." -ForegroundColor $Green
|
|
Pause-Return
|
|
}
|
|
|
|
function Read-ArrowSelection {
|
|
param(
|
|
[string[]]$Items,
|
|
[int]$CurrentIndex = -1,
|
|
[string[]]$TitleLines
|
|
)
|
|
|
|
$selectedIndex = 0
|
|
if ($CurrentIndex -ge 0) { $selectedIndex = $CurrentIndex }
|
|
|
|
$headerLines = Get-HeaderLines
|
|
$overheadLines = $headerLines.Count + $TitleLines.Count + 4
|
|
|
|
$pageSize = (Get-ConsoleHeight) - $overheadLines
|
|
if ($pageSize -gt $Items.Count) { $pageSize = $Items.Count }
|
|
if ($pageSize -lt 1) { $pageSize = 1 }
|
|
|
|
Clear-Host
|
|
try { [Console]::CursorVisible = $false } catch {}
|
|
|
|
while ($true) {
|
|
$totalPages = [Math]::Ceiling($Items.Count / $pageSize)
|
|
if ($totalPages -lt 1) { $totalPages = 1 }
|
|
$currentPage = [Math]::Floor($selectedIndex / $pageSize)
|
|
$pageStart = $currentPage * $pageSize
|
|
$pageEnd = $pageStart + $pageSize - 1
|
|
if ($pageEnd -gt ($Items.Count - 1)) { $pageEnd = $Items.Count - 1 }
|
|
|
|
$frame = @()
|
|
$frame += $headerLines
|
|
$frame += $TitleLines
|
|
|
|
for ($i = $pageStart; $i -le $pageEnd; $i++) {
|
|
$prefix = if ($i -eq $CurrentIndex) { "> " } else { " " }
|
|
$text = "$prefix$($Items[$i])"
|
|
if ($i -eq $selectedIndex) {
|
|
$frame += "$SelectBg$text$Reset"
|
|
}
|
|
elseif ($i -eq $CurrentIndex) {
|
|
$frame += "$GreenAnsi$text$Reset"
|
|
}
|
|
else {
|
|
$frame += $text
|
|
}
|
|
}
|
|
|
|
$linesUsed = $pageEnd - $pageStart + 1
|
|
for ($p = $linesUsed; $p -lt $pageSize; $p++) {
|
|
$frame += ""
|
|
}
|
|
|
|
$frame += ""
|
|
$frame += "$OrangeDark =============================================================$Reset"
|
|
$frame += " Up/Down to move, Enter to select, Esc to go back Page $($currentPage + 1) of $totalPages"
|
|
|
|
Write-Frame $frame
|
|
|
|
$key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
|
$code = $key.VirtualKeyCode
|
|
|
|
if ($code -eq 38) {
|
|
if ($selectedIndex -gt 0) { $selectedIndex-- } else { $selectedIndex = $Items.Count - 1 }
|
|
}
|
|
elseif ($code -eq 40) {
|
|
if ($selectedIndex -lt $Items.Count - 1) { $selectedIndex++ } else { $selectedIndex = 0 }
|
|
}
|
|
elseif ($code -eq 13) {
|
|
try { [Console]::CursorVisible = $true } catch {}
|
|
return $selectedIndex
|
|
}
|
|
elseif ($code -eq 27) {
|
|
try { [Console]::CursorVisible = $true } catch {}
|
|
return -1
|
|
}
|
|
}
|
|
}
|
|
|
|
function Get-CommitList {
|
|
Push-Location $ThemePath
|
|
git fetch origin --quiet 2>$null
|
|
$rawLog = git log --all --pretty=format:"%H|%h|%ad|%s" --date=short
|
|
Pop-Location
|
|
|
|
$commits = @()
|
|
foreach ($line in $rawLog) {
|
|
$parts = $line -split "\|", 4
|
|
if ($parts.Count -eq 4) {
|
|
$commits += [PSCustomObject]@{
|
|
FullHash = $parts[0]
|
|
ShortHash = $parts[1]
|
|
Date = $parts[2]
|
|
Subject = $parts[3]
|
|
}
|
|
}
|
|
}
|
|
return $commits
|
|
}
|
|
|
|
function Show-CommitHistory {
|
|
if (-not (Test-Path $ThemePath)) {
|
|
Show-Header
|
|
Write-Host " $ThemeName is not installed." -ForegroundColor $Red
|
|
Pause-Return
|
|
return
|
|
}
|
|
|
|
if (-not (Test-Dependencies)) {
|
|
Pause-Return
|
|
return
|
|
}
|
|
|
|
$viewing = $true
|
|
while ($viewing) {
|
|
$commits = Get-CommitList
|
|
if ($commits.Count -eq 0) {
|
|
Show-Header
|
|
Write-Host " No commits found." -ForegroundColor $Red
|
|
Pause-Return
|
|
return
|
|
}
|
|
|
|
Push-Location $ThemePath
|
|
$currentHash = (git rev-parse HEAD 2>$null)
|
|
Pop-Location
|
|
|
|
$currentIndex = -1
|
|
$items = @()
|
|
for ($i = 0; $i -lt $commits.Count; $i++) {
|
|
$commit = $commits[$i]
|
|
$items += "$($commit.ShortHash) $($commit.Date) $($commit.Subject)"
|
|
if ($commit.FullHash -eq $currentHash) {
|
|
$currentIndex = $i
|
|
}
|
|
}
|
|
$returnLatestIndex = $items.Count
|
|
$items += "Return to latest version"
|
|
$backIndex = $items.Count
|
|
$items += "Back"
|
|
|
|
$titleLines = @("$OrangeLight Commit History$Reset", "")
|
|
|
|
$selection = Read-ArrowSelection -Items $items -CurrentIndex $currentIndex -TitleLines $titleLines
|
|
|
|
if ($selection -eq -1 -or $selection -eq $backIndex) {
|
|
$viewing = $false
|
|
}
|
|
elseif ($selection -eq $returnLatestIndex) {
|
|
Update-Theme
|
|
}
|
|
elseif ($selection -ge 0 -and $selection -lt $commits.Count) {
|
|
Checkout-Commit $commits[$selection]
|
|
}
|
|
}
|
|
}
|
|
|
|
function Checkout-Commit($commit) {
|
|
Show-Header
|
|
Write-Host "$OrangeLight Checking out commit $($commit.ShortHash)...$Reset"
|
|
Write-Host " $($commit.Date) $($commit.Subject)" -ForegroundColor $Gray
|
|
Write-Host ""
|
|
Write-Host " This will switch the theme to this specific version." -ForegroundColor $Gray
|
|
$confirm = Read-Host " Type Y to confirm"
|
|
if ($confirm -ne "Y" -and $confirm -ne "y") {
|
|
Write-Host " Cancelled." -ForegroundColor $Gray
|
|
Pause-Return
|
|
return
|
|
}
|
|
|
|
Push-Location $ThemePath
|
|
git checkout $commit.FullHash --quiet
|
|
Pop-Location
|
|
|
|
if (Get-Command spicetify -ErrorAction SilentlyContinue) {
|
|
Write-Host ""
|
|
Write-Host "$OrangeMid Applying Spicetify...$Reset"
|
|
spicetify apply
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host " $ThemeName is now on commit $($commit.ShortHash)." -ForegroundColor $Green
|
|
Pause-Return
|
|
}
|
|
|
|
function Check-ForUpdates {
|
|
Show-Header
|
|
Write-Host "$OrangeLight Checking for updates...$Reset"
|
|
Write-Host ""
|
|
|
|
if (-not (Test-Path $ThemePath)) {
|
|
Write-Host " $ThemeName is not installed." -ForegroundColor $Red
|
|
Pause-Return
|
|
return
|
|
}
|
|
|
|
if (-not (Test-Dependencies)) {
|
|
Pause-Return
|
|
return
|
|
}
|
|
|
|
$status = Get-ThemeStatusDetailed
|
|
Write-Host " Status: " -NoNewline -ForegroundColor $White
|
|
Write-Host $status.Text -ForegroundColor $status.Color
|
|
|
|
if ($status.Text -eq "Installed (outdated)") {
|
|
Write-Host ""
|
|
Write-Host " A newer version is available." -ForegroundColor $Gray
|
|
$confirm = Read-Host " Type Y to update now"
|
|
if ($confirm -eq "Y" -or $confirm -eq "y") {
|
|
Update-Theme
|
|
return
|
|
}
|
|
}
|
|
|
|
Pause-Return
|
|
}
|
|
|
|
function Pause-Return {
|
|
Write-Host ""
|
|
Write-Host " Press any key to return to the menu..." -ForegroundColor $Gray
|
|
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
|
}
|
|
|
|
function Show-Menu {
|
|
Show-Header
|
|
$status = Get-ThemeStatusDetailed
|
|
|
|
Write-Host " Status: " -NoNewline -ForegroundColor $White
|
|
Write-Host $status.Text -ForegroundColor $status.Color
|
|
Write-Host ""
|
|
Write-Host " [1] Install $ThemeName" -ForegroundColor $White
|
|
Write-Host " [2] Update $ThemeName" -ForegroundColor $White
|
|
Write-Host " [3] Uninstall $ThemeName" -ForegroundColor $White
|
|
Write-Host " [4] Commit History / Downgrade" -ForegroundColor $White
|
|
Write-Host " [5] Check for Updates" -ForegroundColor $White
|
|
Write-Host " [6] Exit" -ForegroundColor $White
|
|
Write-Host ""
|
|
Write-Host "$OrangeDark =============================================================$Reset"
|
|
Write-Host ""
|
|
$choice = Read-Host " Select an option"
|
|
return $choice
|
|
}
|
|
|
|
$running = $true
|
|
while ($running) {
|
|
$choice = Show-Menu
|
|
switch ($choice) {
|
|
"1" { Install-Theme }
|
|
"2" { Update-Theme }
|
|
"3" { Uninstall-Theme }
|
|
"4" { Show-CommitHistory }
|
|
"5" { Check-ForUpdates }
|
|
"6" { $running = $false }
|
|
default {
|
|
Show-Header
|
|
Write-Host " Invalid option." -ForegroundColor $Red
|
|
Pause-Return
|
|
}
|
|
}
|
|
}
|
|
|
|
Clear-Host |