Skip to content

Commit 92ced3d

Browse files
committed
Merge branch 'feat/public-migration' into main
2 parents 403d9bb + 998f69a commit 92ced3d

File tree

20 files changed

+1833
-1662
lines changed

20 files changed

+1833
-1662
lines changed

Dockerfile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ RUN apk add --no-cache curl openssl3
5151

5252
# Set environment variables for Prisma
5353
ENV PRISMA_CLI_BINARY_TARGETS="linux-musl-openssl-3.0.x,linux-musl-arm64-openssl-3.0.x"
54-
ENV DATABASE_URL="file:/app/data/sqlite.db"
54+
55+
# Allow building instance-specific images (private/public) and set default instance
56+
ARG INSTANCE=public
57+
ENV INSTANCE=$INSTANCE
5558

5659
# Copy built application
5760
COPY --from=builder --chown=appuser:nodejs /app/package*.json ./

client/src/app/globals.css

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,15 @@
33
@tailwind utilities;
44

55
/* Prevent theme flash on page load - set default background */
6-
html {
7-
background-color: #000000; /* safe default for dark/mono to avoid white flash */
6+
html, body, #__next, :root {
7+
background-color: transparent; /* allow theme to control actual color */
88
color-scheme: light; /* default */
9+
min-height: 100%;
910
}
1011

1112
/* Match browser chrome/overscroll color to theme by default */
12-
@media (prefers-color-scheme: light) {
13-
html { background-color: #f9fafb; }
14-
}
15-
@media (prefers-color-scheme: dark) {
16-
html { background-color: #111827; color-scheme: dark; }
17-
}
13+
@media (prefers-color-scheme: light) { html { background-color: #f9fafb; } }
14+
@media (prefers-color-scheme: dark) { html { background-color: #111827; color-scheme: dark; } }
1815

1916
/* Themed scrollbars (WebKit + Firefox) */
2017
/* Base (light) */
@@ -39,7 +36,8 @@ html {
3936

4037
/* Dark */
4138
.dark html, .modern-dark html, .mono html { scrollbar-color: #0f172a transparent; }
42-
.dark html, .modern-dark html, .mono html { color-scheme: dark; }
39+
.dark html, .modern-dark html, .mono html { color-scheme: dark; }
40+
.mono html { background-color: #000000; }
4341
.dark *::-webkit-scrollbar-track,
4442
.modern-dark *::-webkit-scrollbar-track,
4543
.mono *::-webkit-scrollbar-track { background: transparent; }
@@ -98,8 +96,20 @@ body.theme-loaded {
9896
.light html, .light body {
9997
@apply bg-gray-50;
10098
}
101-
.dark html, .dark body {
102-
@apply bg-gray-900;
99+
.dark html, .dark body { @apply bg-gray-900; }
100+
.light html, .light body { @apply bg-gray-50; }
101+
.dark html, .dark body { @apply bg-gray-900; }
102+
.mono html, .mono body { @apply bg-black; }
103+
.light html, .light body, .dark html, .dark body, .mono html, .mono body { min-height: 100%; }
104+
105+
/* Force overscroll/out-of-bounds to match active theme */
106+
.light html, .light body, .light :root, .light #__next { background-color: #f9fafb !important; }
107+
.dark html, .dark body, .dark :root, .dark #__next { background-color: #111827 !important; }
108+
.mono html, .mono body, .mono :root, .mono #__next { background-color: #000000 !important; }
109+
110+
/* Ensure the viewport/out-of-bounds rubber-band area inherits theme color */
111+
html, body {
112+
background-color: inherit;
103113
}
104114

105115
/* Override body background for modern themes */
@@ -174,8 +184,14 @@ body.theme-loaded {
174184

175185
.mono .card,
176186
.mono .bg-white,
177-
.mono .bg-gray-50,
178-
.mono .bg-gray-800 {
187+
.mono .bg-gray-50 {
188+
@apply bg-black border border-white/20 rounded-lg shadow-[inset_0_1px_0_rgba(255,255,255,0.03),0_8px_30px_rgba(0,0,0,0.6)];
189+
}
190+
191+
/* Override gray-800 only for cards and containers, not for color indicators */
192+
.mono .card.bg-gray-800,
193+
.mono .bg-white.bg-gray-800,
194+
.mono .bg-gray-50.bg-gray-800 {
179195
@apply bg-black border border-white/20 rounded-lg shadow-[inset_0_1px_0_rgba(255,255,255,0.03),0_8px_30px_rgba(0,0,0,0.6)];
180196
}
181197

@@ -242,18 +258,31 @@ body.theme-loaded {
242258
.mono .from-*,
243259
.mono .to-* { /* no-op to avoid gradients */ }
244260

245-
.mono .bg-blue-600,
246-
.mono .bg-red-600,
247-
.mono .bg-green-600,
248-
.mono .bg-purple-600,
249-
.mono .bg-blue-700,
250-
.mono .bg-red-700,
251-
.mono .bg-green-700,
252-
.mono .bg-purple-700,
253-
.mono .bg-blue-800,
254-
.mono .bg-red-800,
255-
.mono .bg-green-800,
256-
.mono .bg-purple-800 {
261+
/* Override colored backgrounds only for UI elements, not for group color indicators */
262+
.mono .card .bg-blue-600,
263+
.mono .card .bg-red-600,
264+
.mono .card .bg-green-600,
265+
.mono .card .bg-purple-600,
266+
.mono .card .bg-blue-700,
267+
.mono .card .bg-red-700,
268+
.mono .card .bg-green-700,
269+
.mono .card .bg-purple-700,
270+
.mono .card .bg-blue-800,
271+
.mono .card .bg-red-800,
272+
.mono .card .bg-green-800,
273+
.mono .card .bg-purple-800,
274+
.mono .bg-white .bg-blue-600,
275+
.mono .bg-white .bg-red-600,
276+
.mono .bg-white .bg-green-600,
277+
.mono .bg-white .bg-purple-600,
278+
.mono .bg-white .bg-blue-700,
279+
.mono .bg-white .bg-red-700,
280+
.mono .bg-white .bg-green-700,
281+
.mono .bg-white .bg-purple-700,
282+
.mono .bg-white .bg-blue-800,
283+
.mono .bg-white .bg-red-800,
284+
.mono .bg-white .bg-green-800,
285+
.mono .bg-white .bg-purple-800 {
257286
@apply bg-black;
258287
}
259288

@@ -499,7 +528,8 @@ body.theme-loaded {
499528
background-color: #1f1f1f !important;
500529
border: 1px solid rgba(255, 255, 255, 0.2) !important;
501530
}
502-
.mono [class*="inline-flex"][class*="h-5"][class*="w-9"][class*="rounded-full"][class*="bg-"] {
531+
/* Override toggle switches only, not group color indicators */
532+
.mono [class*="inline-flex"][class*="h-5"][class*="w-9"][class*="rounded-full"][class*="bg-"]:not([class*="w-10"][class*="h-10"]) {
503533
background-color: #1f1f1f !important;
504534
border: 1px solid rgba(255, 255, 255, 0.2) !important;
505535
}
@@ -509,7 +539,8 @@ body.theme-loaded {
509539
background-color: #1f1f1f !important;
510540
border: 1px solid rgba(255, 255, 255, 0.2) !important;
511541
}
512-
.mono [class*="inline-flex"][class*="h-6"][class*="w-11"][class*="rounded-full"][class*="bg-"] {
542+
/* Override toggle switches only, not group color indicators */
543+
.mono [class*="inline-flex"][class*="h-6"][class*="w-11"][class*="rounded-full"][class*="bg-"]:not([class*="w-10"][class*="h-10"]) {
513544
background-color: #1f1f1f !important;
514545
border: 1px solid rgba(255, 255, 255, 0.2) !important;
515546
}
@@ -652,6 +683,15 @@ body.theme-loaded {
652683
}
653684

654685
@layer components {
686+
/* When a modal overlay is present, dim all fixed headers/buttons except the modal */
687+
.modal-open .fixed,
688+
.modal-open [class*="z-"] {
689+
filter: brightness(0.8);
690+
}
691+
.modal-open .modal-root,
692+
.modal-open .modal-root * {
693+
filter: none !important;
694+
}
655695
.btn {
656696
@apply inline-flex items-center justify-center px-4 py-2 text-sm font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed;
657697
}

client/src/app/layout.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,30 @@ export default function RootLayout({
3232
<meta name="application-name" content="Syncio" />
3333
<meta name="apple-mobile-web-app-title" content="Syncio" />
3434
<meta name="description" content="Syncio - Stremio Group Manager" />
35+
{/* Single theme-color; ThemeProvider updates it dynamically */}
36+
<meta name="theme-color" content="#111827" />
37+
{/* Pre-init theme to avoid flash and fix overscroll background before paint */}
38+
<script
39+
dangerouslySetInnerHTML={{
40+
__html: `
41+
(function(){
42+
try {
43+
var d = document.documentElement;
44+
var saved = localStorage.getItem('theme');
45+
var isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
46+
var theme = saved || (isDark ? 'dark' : 'light');
47+
if (theme === 'modern' || theme === 'modern-dark') theme = 'dark';
48+
d.classList.remove('light','dark','modern','modern-dark','mono');
49+
d.classList.add(theme);
50+
var tag = document.querySelector('meta[name="theme-color"]');
51+
if (!tag) { tag = document.createElement('meta'); tag.setAttribute('name','theme-color'); document.head.appendChild(tag); }
52+
var colors = { light: '#f9fafb', dark: '#111827', mono: '#000000', 'modern': '#f9fafb', 'modern-dark': '#111827' };
53+
tag.setAttribute('content', colors[theme] || '#111827');
54+
} catch(e){}
55+
})();
56+
`
57+
}}
58+
/>
3559
<link rel="manifest" href="/site.webmanifest" />
3660
<link rel="icon" href="/favicon.ico" />
3761
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />

client/src/components/auth/UserMenuButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ export default function UserMenuButton({ className = '' }: Props) {
123123
}`
124124

125125
return (
126-
<div className="relative z-[300]" ref={wrapperRef}>
126+
<div className="relative z-[10]" ref={wrapperRef}>
127127
<button className={btnClasses} onClick={() => setShowMenu((s) => !s)} title="Account">
128128
<UserIcon size={18} />
129129
</button>

client/src/components/common/SyncBadge.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default function SyncBadge({
4545
case 'connect':
4646
return {
4747
text: 'Connect Stremio',
48-
dotColor: 'bg-stremio-purple',
48+
dotColor: 'bg-purple-200',
4949
bgColor: 'bg-stremio-purple text-white'
5050
}
5151
case 'syncing':

client/src/components/pages/AddonsPage.tsx

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,35 @@ export default function AddonsPage() {
450450
const theme = isMono ? 'mono' : isModern ? 'modern' : isModernDark ? 'modern-dark' : isDark ? 'dark' : 'light'
451451
return getColorBgClass(colorIndex, theme)
452452
}
453+
454+
// Helper function to convert Tailwind classes to actual color values
455+
const getColorValue = (tailwindClass: string): string => {
456+
const colorMap: Record<string, string> = {
457+
'bg-black': '#000000',
458+
'bg-gray-800': '#1f2937',
459+
'bg-gray-600': '#4b5563',
460+
'bg-gray-400': '#9ca3af',
461+
'bg-gray-300': '#d1d5db',
462+
'bg-blue-500': '#3b82f6',
463+
'bg-green-500': '#10b981',
464+
'bg-purple-500': '#8b5cf6',
465+
'bg-orange-500': '#f97316',
466+
'bg-red-500': '#ef4444',
467+
// Add gradient classes for modern themes
468+
'bg-gradient-to-br from-blue-500 to-blue-600': '#3b82f6',
469+
'bg-gradient-to-br from-green-500 to-green-600': '#10b981',
470+
'bg-gradient-to-br from-purple-500 to-purple-600': '#8b5cf6',
471+
'bg-gradient-to-br from-orange-500 to-orange-600': '#f97316',
472+
'bg-gradient-to-br from-red-500 to-red-600': '#ef4444',
473+
'bg-gradient-to-br from-blue-600 to-blue-700': '#2563eb',
474+
'bg-gradient-to-br from-green-600 to-green-700': '#059669',
475+
'bg-gradient-to-br from-purple-600 to-purple-700': '#7c3aed',
476+
'bg-gradient-to-br from-orange-600 to-orange-700': '#ea580c',
477+
'bg-gradient-to-br from-red-600 to-red-700': '#dc2626'
478+
}
479+
return colorMap[tailwindClass] || '#000000'
480+
}
481+
453482
const [mounted, setMounted] = useState(false)
454483
const [hasLoadedData, setHasLoadedData] = useState(false)
455484
useEffect(() => { setMounted(true) }, [])
@@ -556,10 +585,8 @@ export default function AddonsPage() {
556585
return base.filter((addon: any) => {
557586
const name = String(addon.name || '')
558587
const description = String(addon.description || '')
559-
const tags = Array.isArray(addon.tags) ? addon.tags.join(' ') : String(addon.tags || '')
560588
const matchesSearch = name.toLowerCase().includes(debouncedSearchTerm.toLowerCase()) ||
561-
description.toLowerCase().includes(debouncedSearchTerm.toLowerCase()) ||
562-
tags.toLowerCase().includes(debouncedSearchTerm.toLowerCase())
589+
description.toLowerCase().includes(debouncedSearchTerm.toLowerCase())
563590
return matchesSearch
564591
})
565592
}, [addons, debouncedSearchTerm])
@@ -1335,7 +1362,7 @@ export default function AddonsPage() {
13351362
onClick={() => handleEditAddon(addon)}
13361363
>
13371364
<div className="flex items-center justify-between gap-3">
1338-
<div className="flex items-center flex-1 min-w-0">
1365+
<div className="flex items-center flex-1 min-w-0 max-w-[calc(100%-200px)]">
13391366
<div className={`w-10 h-10 rounded-lg flex items-center justify-center mr-3 flex-shrink-0 overflow-hidden ${
13401367
isMono ? 'border border-white/20' : ''
13411368
}`}>
@@ -1390,7 +1417,7 @@ export default function AddonsPage() {
13901417
</div>
13911418
</div>
13921419
{addon.description && (
1393-
<p className={`hidden sm:block text-sm truncate ${
1420+
<p className={`hidden sm:block text-sm truncate max-w-[250px] lg:max-w-[300px] ${
13941421
isModern
13951422
? 'text-purple-600'
13961423
: isModernDark
@@ -1638,10 +1665,10 @@ export default function AddonsPage() {
16381665
: `bg-gray-100 text-gray-700 border-gray-300 hover:bg-gray-200 hover:border-gray-400 ${isMono ? '' : ''}`
16391666
}`}
16401667
>
1641-
<div className={`w-10 h-10 rounded-lg flex items-center justify-center text-white ${getGroupColorClass(group?.colorIndex)}`}
1642-
style={{
1643-
backgroundColor: group?.colorIndex === 2 && isMono ? '#1f2937' : undefined
1644-
}}>
1668+
<div
1669+
className={`w-10 h-10 rounded-lg flex items-center justify-center text-white ${!isMono ? getGroupColorClass(group?.colorIndex) : ''}`}
1670+
style={isMono ? { backgroundColor: getColorValue(getGroupColorClass(group?.colorIndex)) } : undefined}
1671+
>
16451672
<span className="text-sm font-semibold">
16461673
{group.name ? group.name.charAt(0).toUpperCase() : 'G'}
16471674
</span>
@@ -1766,10 +1793,10 @@ export default function AddonsPage() {
17661793
: `bg-gray-100 text-gray-700 border-gray-300 hover:bg-gray-200 hover:border-gray-400 ${isMono ? '' : ''}`
17671794
}`}
17681795
>
1769-
<div className={`w-10 h-10 rounded-lg flex items-center justify-center text-white ${getGroupColorClass(group?.colorIndex)}`}
1770-
style={{
1771-
backgroundColor: group?.colorIndex === 2 && isMono ? '#1f2937' : undefined
1772-
}}>
1796+
<div
1797+
className={`w-10 h-10 rounded-lg flex items-center justify-center text-white ${!isMono ? getGroupColorClass(group?.colorIndex) : ''}`}
1798+
style={isMono ? { backgroundColor: getColorValue(getGroupColorClass(group?.colorIndex)) } : undefined}
1799+
>
17731800
<span className="text-sm font-semibold">
17741801
{group.name ? group.name.charAt(0).toUpperCase() : 'G'}
17751802
</span>

0 commit comments

Comments
 (0)