This commit is contained in:
parent
c2bfa06faa
commit
a56ca40204
16 changed files with 816 additions and 234 deletions
|
|
@ -9,6 +9,8 @@
|
|||
import EbookReaderOverlay from '$lib/components/EbookReaderOverlay.svelte';
|
||||
import ChessGameOverlay from '$lib/components/ChessGameOverlay.svelte';
|
||||
import GlobalAudioPlayer from '$lib/components/GlobalAudioPlayer.svelte';
|
||||
import ScreensaverOverlay from '$lib/components/ScreensaverOverlay.svelte';
|
||||
import { screensaver } from '$lib/stores/screensaver';
|
||||
import '../app.css';
|
||||
|
||||
let showDropdown = false;
|
||||
|
|
@ -43,6 +45,22 @@
|
|||
onMount(() => {
|
||||
auth.init().then(() => {
|
||||
fetchBalance();
|
||||
// Initialize screensaver if user is authenticated
|
||||
const unsubscribe = auth.subscribe(state => {
|
||||
if (state.user) {
|
||||
screensaver.init({
|
||||
screensaverEnabled: state.user.screensaverEnabled,
|
||||
screensaverTimeoutMinutes: state.user.screensaverTimeoutMinutes
|
||||
});
|
||||
}
|
||||
});
|
||||
// Initial check
|
||||
if ($auth.user) {
|
||||
screensaver.init({
|
||||
screensaverEnabled: $auth.user.screensaverEnabled,
|
||||
screensaverTimeoutMinutes: $auth.user.screensaverTimeoutMinutes
|
||||
});
|
||||
}
|
||||
});
|
||||
loadSiteSettings();
|
||||
|
||||
|
|
@ -291,42 +309,42 @@
|
|||
|
||||
.role-badge.admin {
|
||||
background: rgba(239, 68, 68, 0.2);
|
||||
color: #ef4444;
|
||||
color: var(--role-admin);
|
||||
}
|
||||
|
||||
.role-badge.moderator {
|
||||
background: rgba(168, 85, 247, 0.2);
|
||||
color: #a855f7;
|
||||
color: var(--role-moderator);
|
||||
}
|
||||
|
||||
.role-badge.streamer {
|
||||
background: rgba(59, 130, 246, 0.2);
|
||||
color: #3b82f6;
|
||||
color: var(--role-streamer);
|
||||
}
|
||||
|
||||
.role-badge.restreamer {
|
||||
background: rgba(20, 184, 166, 0.2);
|
||||
color: #14b8a6;
|
||||
color: var(--role-restreamer);
|
||||
}
|
||||
|
||||
.role-badge.uploader {
|
||||
background: rgba(34, 197, 94, 0.2);
|
||||
color: #22c55e;
|
||||
color: var(--role-uploader);
|
||||
}
|
||||
|
||||
.role-badge.texter {
|
||||
background: rgba(251, 146, 60, 0.2);
|
||||
color: #fb923c;
|
||||
color: var(--role-texter);
|
||||
}
|
||||
|
||||
.role-badge.sticker-creator {
|
||||
background: rgba(236, 72, 153, 0.2);
|
||||
color: #ec4899;
|
||||
color: var(--role-sticker);
|
||||
}
|
||||
|
||||
.role-badge.watch-creator {
|
||||
background: rgba(99, 102, 241, 0.2);
|
||||
color: #6366f1;
|
||||
color: var(--role-watch);
|
||||
}
|
||||
|
||||
.dropdown-username {
|
||||
|
|
@ -582,6 +600,7 @@
|
|||
<ChatTerminal />
|
||||
<EbookReaderOverlay />
|
||||
<ChessGameOverlay />
|
||||
<ScreensaverOverlay />
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
import { browser } from '$app/environment';
|
||||
import { auth, isAuthenticated, isBot, isStickerCreator } from '$lib/stores/auth';
|
||||
import { siteSettings } from '$lib/stores/siteSettings';
|
||||
import { screensaver } from '$lib/stores/screensaver';
|
||||
import { goto } from '$app/navigation';
|
||||
import * as pgp from '$lib/pgp';
|
||||
import GraffitiEditor from '$lib/components/GraffitiEditor.svelte';
|
||||
|
|
@ -108,6 +109,13 @@
|
|||
let referralPurchasing = false;
|
||||
let referralSystemEnabled = false;
|
||||
|
||||
// Screensaver settings
|
||||
let screensaverEnabled = false;
|
||||
let screensaverTimeoutMinutes = 5;
|
||||
let screensaverLoading = false;
|
||||
let screensaverMessage = '';
|
||||
let screensaverError = '';
|
||||
|
||||
// User data for safe access
|
||||
let currentUser = null;
|
||||
|
||||
|
|
@ -151,6 +159,8 @@
|
|||
graffitiUrl = data.user.graffitiUrl || '';
|
||||
userColor = data.user.colorCode || '#561D5E';
|
||||
newColor = userColor;
|
||||
screensaverEnabled = data.user.screensaverEnabled || false;
|
||||
screensaverTimeoutMinutes = data.user.screensaverTimeoutMinutes || 5;
|
||||
currentUser = data.user;
|
||||
|
||||
// Update auth store with fresh data
|
||||
|
|
@ -564,6 +574,40 @@
|
|||
setTimeout(() => { referralMessage = ''; }, 3000);
|
||||
}
|
||||
|
||||
async function updateScreensaverSettings() {
|
||||
screensaverLoading = true;
|
||||
screensaverError = '';
|
||||
screensaverMessage = '';
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/user/screensaver', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({
|
||||
enabled: screensaverEnabled,
|
||||
timeout_minutes: screensaverTimeoutMinutes
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok && data.success) {
|
||||
screensaverMessage = 'Screensaver settings saved';
|
||||
// Update the screensaver store
|
||||
screensaver.updateSettings(screensaverEnabled, screensaverTimeoutMinutes);
|
||||
setTimeout(() => { screensaverMessage = ''; }, 3000);
|
||||
} else {
|
||||
screensaverError = data.error || 'Failed to save settings';
|
||||
}
|
||||
} catch (e) {
|
||||
screensaverError = 'Error saving settings';
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
screensaverLoading = false;
|
||||
}
|
||||
|
||||
function validatePassword(pass) {
|
||||
if (pass.length < 8) {
|
||||
return 'Password must be at least 8 characters';
|
||||
|
|
@ -2196,6 +2240,13 @@
|
|||
Referrals
|
||||
</button>
|
||||
{/if}
|
||||
<button
|
||||
class="tab-button"
|
||||
class:active={activeTab === 'screensaver'}
|
||||
on:click={() => activeTab = 'screensaver'}
|
||||
>
|
||||
Screensaver
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{#if activeTab === 'profile'}
|
||||
|
|
@ -3211,6 +3262,74 @@ bot.connect();</code></pre>
|
|||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{:else if activeTab === 'screensaver'}
|
||||
<div class="card">
|
||||
<h2>Screensaver Settings</h2>
|
||||
<p style="color: var(--gray); font-size: 0.9rem; margin-bottom: 1.5rem;">
|
||||
Enable a snowfall screensaver that activates when you're idle.
|
||||
</p>
|
||||
|
||||
{#if screensaverMessage}
|
||||
<div class="success" style="margin-bottom: 1rem;">{screensaverMessage}</div>
|
||||
{/if}
|
||||
|
||||
{#if screensaverError}
|
||||
<div class="error" style="margin-bottom: 1rem;">{screensaverError}</div>
|
||||
{/if}
|
||||
|
||||
<form on:submit|preventDefault={updateScreensaverSettings}>
|
||||
<div class="form-group">
|
||||
<label class="checkbox-label" style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={screensaverEnabled}
|
||||
style="width: 18px; height: 18px; cursor: pointer;"
|
||||
/>
|
||||
<span>Enable screensaver</span>
|
||||
</label>
|
||||
<p style="font-size: 0.85rem; color: var(--gray); margin-top: 0.5rem;">
|
||||
When enabled, a snowfall animation will appear after the idle timeout.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{#if screensaverEnabled}
|
||||
<div class="form-group" style="margin-top: 1.5rem;">
|
||||
<label for="screensaver-timeout">Idle timeout (minutes)</label>
|
||||
<input
|
||||
type="number"
|
||||
id="screensaver-timeout"
|
||||
bind:value={screensaverTimeoutMinutes}
|
||||
min="1"
|
||||
max="30"
|
||||
style="width: 100px;"
|
||||
/>
|
||||
<p style="font-size: 0.85rem; color: var(--gray); margin-top: 0.5rem;">
|
||||
Time of inactivity before the screensaver activates (1-30 minutes).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 1rem; padding: 1rem; background: rgba(139, 92, 246, 0.1); border-radius: 8px; border: 1px solid rgba(139, 92, 246, 0.2);">
|
||||
<p style="font-size: 0.85rem; color: var(--gray); margin: 0;">
|
||||
<strong>Note:</strong> The screensaver will not activate while:
|
||||
</p>
|
||||
<ul style="font-size: 0.85rem; color: var(--gray); margin: 0.5rem 0 0 1.5rem; padding: 0;">
|
||||
<li>Video or audio is playing</li>
|
||||
<li>The browser tab is not visible</li>
|
||||
</ul>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div style="margin-top: 2rem;">
|
||||
<button
|
||||
type="submit"
|
||||
disabled={screensaverLoading}
|
||||
>
|
||||
{screensaverLoading ? 'Saving...' : 'Save Settings'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue