style: improve platform/version card in sidebar

This commit is contained in:
Sam Chau
2026-01-20 00:56:51 +10:30
parent ec0db073d2
commit facf391f16
9 changed files with 111 additions and 78 deletions

View File

@@ -45,6 +45,19 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Determine channel
id: channel
run: |
if [[ "${{ github.ref }}" == "refs/heads/v2" ]]; then
echo "value=develop" >> $GITHUB_OUTPUT
elif [[ "${{ github.ref }}" == refs/tags/v*-beta* ]]; then
echo "value=beta" >> $GITHUB_OUTPUT
elif [[ "${{ github.ref }}" == refs/tags/v* ]]; then
echo "value=stable" >> $GITHUB_OUTPUT
else
echo "value=develop" >> $GITHUB_OUTPUT
fi
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
@@ -70,6 +83,8 @@ jobs:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VITE_CHANNEL=${{ steps.channel.outputs.value }}
cache-from: type=registry,ref=${{ env.IMAGE_BASE }}/${{ matrix.image }}:buildcache
cache-to: type=registry,ref=${{ env.IMAGE_BASE }}/${{ matrix.image }}:buildcache,mode=max

View File

@@ -22,6 +22,14 @@ RUN deno install --node-modules-dir
# Build the application
# 1. Vite builds SvelteKit to dist/build/
# 2. Deno compiles to standalone binary
# Build-time variables for version card
# TARGETARCH is automatically set by Docker buildx (amd64 or arm64)
ARG TARGETARCH
ARG VITE_CHANNEL=stable
ENV VITE_PLATFORM=docker-${TARGETARCH}
ENV VITE_CHANNEL=${VITE_CHANNEL}
ENV APP_BASE_PATH=/build/dist/build
RUN deno run -A npm:vite build
RUN deno compile \

View File

@@ -28,7 +28,7 @@
},
"tasks": {
"dev": "deno run -A scripts/dev.ts",
"dev:server": "DENO_ENV=development PORT=6969 HOST=0.0.0.0 APP_BASE_PATH=./dist/dev PARSER_HOST=localhost PARSER_PORT=5000 deno run -A npm:vite dev",
"dev:server": "DENO_ENV=development PORT=6969 HOST=0.0.0.0 APP_BASE_PATH=./dist/dev PARSER_HOST=localhost PARSER_PORT=5000 VITE_PLATFORM=linux-amd64 VITE_CHANNEL=dev deno run -A npm:vite dev",
"dev:parser": "cd src/services/parser && dotnet watch run --urls http://localhost:5000",
"build": "APP_BASE_PATH=./dist/build deno run -A npm:vite build && deno compile --no-check --allow-net --allow-read --allow-write --allow-env --allow-ffi --allow-run --allow-sys --target x86_64-unknown-linux-gnu --output dist/build/profilarr dist/build/mod.ts",
"build:windows": "APP_BASE_PATH=./dist/build deno run -A npm:vite build && deno compile --no-check --allow-net --allow-read --allow-write --allow-env --allow-ffi --allow-run --allow-sys --target x86_64-pc-windows-msvc --output dist/windows/profilarr.exe dist/build/mod.ts",

View File

@@ -1,42 +0,0 @@
# Dirty Handling for Upgrades & Renames
**Status: Planning**
## Summary
Both the Upgrades and Rename configuration pages have issues with form state management and dirty tracking. This task covers fixing save errors and implementing proper dirty state handling.
## Problems
### Upgrades Page
- Save errors occurring (need to investigate root cause)
- Dirty tracking not properly implemented
- Form state management inconsistent
### Rename Page
- Needs dirty tracking implementation
- Should follow same pattern as upgrades (once fixed)
## Requirements
1. Fix save errors in upgrades page
2. Implement proper dirty tracking for both pages:
- Track when form values differ from saved values
- Show unsaved changes indicator
- Warn before navigating away with unsaved changes
- Reset dirty state after successful save
## Implementation Notes
TBD - needs investigation of current issues first.
---
## Related Files
- `src/routes/arr/[id]/upgrades/+page.svelte`
- `src/routes/arr/[id]/upgrades/+page.server.ts`
- `src/routes/arr/[id]/rename/+page.svelte`
- `src/routes/arr/[id]/rename/+page.server.ts`

View File

@@ -6,6 +6,7 @@
import { navIconStore } from '$stores/navIcons';
export let collapsed: boolean = false;
export let version: string = '';
$: useEmoji = $navIconStore === 'emoji';
</script>
@@ -79,5 +80,5 @@
</Group>
</div>
<Version />
<Version {version} />
</nav>

View File

@@ -1,26 +1,26 @@
<script lang="ts">
import { getBuildLabel, VERSION } from '$shared/version.ts';
import { Package } from 'lucide-svelte';
import { getPlatformLabel, getChannelLabel, shouldShowVersion } from '$shared/version.ts';
import logo from '$assets/logo-512.png';
const buildLabel = getBuildLabel();
export let version: string = '';
const platform = getPlatformLabel();
const channel = getChannelLabel();
const showVersion = shouldShowVersion();
</script>
<div class="p-4">
<div
class="flex items-center gap-2.5 rounded-lg border border-neutral-300 px-3 py-2 dark:border-neutral-700"
>
<div
class="flex h-6 w-6 flex-shrink-0 items-center justify-center rounded bg-neutral-200 dark:bg-neutral-700"
>
<Package class="h-3.5 w-3.5 text-neutral-700 dark:text-neutral-300" />
</div>
<img src={logo} alt="Profilarr logo" class="h-5 w-5 flex-shrink-0" />
<div class="flex-1">
<div class="font-mono text-xs font-semibold text-neutral-900 dark:text-neutral-50">
<div class="text-xs font-semibold text-neutral-900 dark:text-neutral-50">
profilarr
</div>
<div class="font-mono text-[10px] text-neutral-600 dark:text-neutral-400">
{buildLabel} · v{VERSION}
{platform} · {channel}{#if showVersion && version} · {version}{/if}
</div>
</div>
</div>

View File

@@ -1,31 +1,72 @@
// Version is injected at build time from package.json
declare const __APP_VERSION__: string;
// Platform and channel are injected at build time
// Version comes from the database (fetched via API)
export const VERSION = __APP_VERSION__;
export const BUILD_TYPE = import.meta.env.MODE === 'development' ? 'dev' : 'stable';
type Platform =
| 'docker-amd64'
| 'docker-arm64'
| 'windows-amd64'
| 'linux-amd64'
| 'linux-arm64'
| 'macos-amd64'
| 'macos-arm64';
export function getBuildLabel(): string {
// Check for custom build type from environment
const customBuildType = import.meta.env.VITE_BUILD_TYPE as string | undefined;
type Channel = 'stable' | 'beta' | 'develop' | 'dev';
if (customBuildType) {
switch (customBuildType) {
case 'beta':
return 'Beta';
case 'docker':
return 'Docker';
case 'dev':
return 'Develop';
case 'stable':
default:
return 'Stable';
const PLATFORM_LABELS: Record<Platform, string> = {
'docker-amd64': 'docker/amd64',
'docker-arm64': 'docker/arm64',
'windows-amd64': 'windows/amd64',
'linux-amd64': 'linux/amd64',
'linux-arm64': 'linux/arm64',
'macos-amd64': 'macos/amd64',
'macos-arm64': 'macos/arm64'
};
const CHANNEL_LABELS: Record<Channel, string> = {
stable: 'Stable',
beta: 'Beta',
develop: 'Develop',
dev: 'Dev'
};
function detectPlatform(): Platform {
// Try to detect from navigator in browser
if (typeof navigator !== 'undefined' && navigator.platform) {
const platform = navigator.platform.toLowerCase();
if (platform.includes('win')) return 'windows-amd64';
if (platform.includes('mac')) {
// Check for Apple Silicon - this is a heuristic
return 'macos-arm64';
}
if (platform.includes('linux')) return 'linux-amd64';
}
// Fallback based on Vite mode
return import.meta.env.MODE === 'development' ? 'Developer Build' : 'Stable';
return 'linux-amd64';
}
export function getFullVersionString(): string {
return `Profilarr ${getBuildLabel()} v${VERSION}`;
export function getPlatform(): Platform {
const envPlatform = import.meta.env.VITE_PLATFORM as Platform | undefined;
return envPlatform || detectPlatform();
}
export function getChannel(): Channel {
const envChannel = import.meta.env.VITE_CHANNEL as Channel | undefined;
if (envChannel) return envChannel;
// Default to dev for development mode, stable otherwise
return import.meta.env.MODE === 'development' ? 'dev' : 'stable';
}
export function getPlatformLabel(): string {
const platform = getPlatform();
return PLATFORM_LABELS[platform] || platform;
}
export function getChannelLabel(): string {
const channel = getChannel();
return CHANNEL_LABELS[channel] || channel;
}
export function shouldShowVersion(): boolean {
const channel = getChannel();
return channel === 'stable' || channel === 'beta';
}

View File

@@ -0,0 +1,8 @@
import type { LayoutServerLoad } from './$types';
import { appInfoQueries } from '$db/queries/appInfo.ts';
export const load: LayoutServerLoad = async () => {
return {
version: appInfoQueries.getVersion()
};
};

View File

@@ -5,6 +5,8 @@
import PageNav from '$ui/navigation/pageNav/pageNav.svelte';
import AlertContainer from '$alerts/AlertContainer.svelte';
import { sidebarCollapsed } from '$lib/client/stores/sidebar';
export let data;
</script>
<svelte:head>
@@ -13,7 +15,7 @@
</svelte:head>
<Navbar collapsed={$sidebarCollapsed} />
<PageNav collapsed={$sidebarCollapsed} />
<PageNav collapsed={$sidebarCollapsed} version={data.version} />
<AlertContainer />
<!-- Sidebar collapse toggle button -->