diff --git a/scripts/install/linux/install.sh b/scripts/install/linux/install.sh new file mode 100644 index 0000000..e69de29 diff --git a/scripts/install/windows/install.ps1 b/scripts/install/windows/install.ps1 index 25141a2..0e3c0c6 100644 --- a/scripts/install/windows/install.ps1 +++ b/scripts/install/windows/install.ps1 @@ -46,10 +46,13 @@ $OrangeLight = Get-RGBCode 255 140 66 $OrangeDark = Get-RGBCode 224 123 57 $OrangeMid = Get-RGBCode 240 131 61 +$SelectBg = "$Esc[48;2;255;140;66m$Esc[38;2;0;0;0m" + $White = "White" $Gray = "DarkGray" $Red = "Red" $Green = "Green" +$Cyan = "Cyan" function Get-GradientColor($index, $total) { $r1 = 255; $g1 = 140; $b1 = 66 @@ -106,11 +109,58 @@ function Test-Dependencies { return $true } -function Get-ThemeStatus { - if (Test-Path $ThemePath) { - return "Installed" +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 "Not Installed" + 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 { @@ -174,6 +224,14 @@ function Update-Theme { 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 @@ -220,6 +278,199 @@ function Uninstall-Theme { Pause-Return } +function Read-ArrowSelection { + param( + [string[]]$Items, + [int]$CurrentIndex = -1, + [scriptblock]$HeaderRenderer + ) + + $selectedIndex = 0 + if ($CurrentIndex -ge 0) { $selectedIndex = $CurrentIndex } + + while ($true) { + & $HeaderRenderer + + for ($i = 0; $i -lt $Items.Count; $i++) { + $prefix = if ($i -eq $CurrentIndex) { "> " } else { " " } + $text = "$prefix$($Items[$i])" + + if ($i -eq $selectedIndex) { + Write-Host "$SelectBg $text $Reset" + } + elseif ($i -eq $CurrentIndex) { + Write-Host $text -ForegroundColor $Green + } + else { + Write-Host $text -ForegroundColor $White + } + } + + Write-Host "" + Write-Host "$OrangeDark =============================================================$Reset" + Write-Host " Up/Down to move, Enter to select, Esc to go back" -ForegroundColor $Gray + + $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) { + return $selectedIndex + } + elseif ($code -eq 27) { + 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" + + $headerRenderer = { + Show-Header + Write-Host "$OrangeLight Commit History$Reset" + Write-Host "" + } + + $selection = Read-ArrowSelection -Items $items -CurrentIndex $currentIndex -HeaderRenderer $headerRenderer + + 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 @@ -228,16 +479,17 @@ function Pause-Return { function Show-Menu { Show-Header - $status = Get-ThemeStatus - $statusColor = if ($status -eq "Installed") { $Green } else { $Red } + $status = Get-ThemeStatusDetailed Write-Host " Status: " -NoNewline -ForegroundColor $White - Write-Host $status -ForegroundColor $statusColor + 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] Exit" -ForegroundColor $White + 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 "" @@ -252,7 +504,9 @@ while ($running) { "1" { Install-Theme } "2" { Update-Theme } "3" { Uninstall-Theme } - "4" { $running = $false } + "4" { Show-CommitHistory } + "5" { Check-ForUpdates } + "6" { $running = $false } default { Show-Header Write-Host " Invalid option." -ForegroundColor $Red