mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
feat: build themes into a centralised plugin
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { hasEnoughStorageSpace, isIndexedDBSupported, writeData, openDatabase, readAllData, deleteData } from '@/interface/hooks/BackgroundDataLoader';
|
||||
import { setTheme } from '@/seqta/ui/themes/setTheme';
|
||||
import Spinner from '../Spinner.svelte';
|
||||
import { settingsState } from '@/seqta/utils/listeners/SettingsState'
|
||||
import Fuse from 'fuse.js';
|
||||
import { backgroundUpdates } from '@/interface/hooks/BackgroundUpdates'
|
||||
import { ThemeManager } from '@/plugins/built-in/themes/theme-manager'
|
||||
|
||||
const themeManager = ThemeManager.getInstance();
|
||||
|
||||
type Background = { id: string; category: string; type: string; lowResUrl: string; highResUrl: string; name: string; description: string; featured?: boolean };
|
||||
let { searchTerm } = $props<{ searchTerm: string }>();
|
||||
@@ -170,7 +172,7 @@
|
||||
|
||||
function selectNoBackground() {
|
||||
selectedBackground = null;
|
||||
setTheme('');
|
||||
themeManager.setTheme('');
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
<script lang="ts">
|
||||
import type { CustomTheme, ThemeList } from '@/types/CustomThemes'
|
||||
import { getAvailableThemes } from '@/seqta/ui/themes/getAvailableThemes'
|
||||
import { onDestroy, onMount } from 'svelte'
|
||||
import { OpenThemeCreator } from '@/seqta/ui/ThemeCreator'
|
||||
import shareTheme from '@/seqta/ui/themes/shareTheme'
|
||||
import { InstallTheme } from '@/seqta/ui/themes/downloadTheme'
|
||||
import { disableTheme } from '@/seqta/ui/themes/disableTheme'
|
||||
import { setTheme } from '@/seqta/ui/themes/setTheme'
|
||||
import { deleteTheme } from '@/seqta/ui/themes/deleteTheme'
|
||||
import { OpenStorePage } from '@/seqta/ui/renderStore'
|
||||
import { themeUpdates } from '@/interface/hooks/ThemeUpdates'
|
||||
import { closeExtensionPopup } from '@/seqta/utils/Closers/closeExtensionPopup'
|
||||
import { ThemeManager } from '@/plugins/built-in/themes/theme-manager'
|
||||
|
||||
const themeManager = ThemeManager.getInstance();
|
||||
|
||||
let themes = $state<ThemeList | null>(null);
|
||||
let { isEditMode } = $props<{ isEditMode: boolean }>();
|
||||
@@ -20,10 +17,10 @@
|
||||
const handleThemeClick = async (theme: CustomTheme) => {
|
||||
if (isEditMode) return;
|
||||
if (theme.id === themes?.selectedTheme) {
|
||||
await disableTheme();
|
||||
await themeManager.disableTheme();
|
||||
themes.selectedTheme = '';
|
||||
} else {
|
||||
await setTheme(theme.id);
|
||||
await themeManager.setTheme(theme.id);
|
||||
if (!themes) return;
|
||||
themes.selectedTheme = theme.id;
|
||||
}
|
||||
@@ -31,13 +28,13 @@
|
||||
|
||||
const handleThemeDelete = async (themeId: string) => {
|
||||
try {
|
||||
await deleteTheme(themeId);
|
||||
await themeManager.deleteTheme(themeId);
|
||||
if (!themes) return;
|
||||
|
||||
themes.themes = themes.themes.filter(theme => theme.id !== themeId);
|
||||
if (themeId === themes.selectedTheme) {
|
||||
themes.selectedTheme = '';
|
||||
await disableTheme();
|
||||
await themeManager.disableTheme();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error deleting theme:', error);
|
||||
@@ -46,7 +43,7 @@
|
||||
|
||||
const handleShareTheme = async (theme: CustomTheme) => {
|
||||
try {
|
||||
await shareTheme(theme.id);
|
||||
await themeManager.shareTheme(theme.id);
|
||||
} catch (error) {
|
||||
console.error('Error sharing theme:', error);
|
||||
}
|
||||
@@ -72,7 +69,7 @@
|
||||
try {
|
||||
const result = JSON.parse(event.target?.result as string);
|
||||
tempTheme = result;
|
||||
await InstallTheme(result);
|
||||
await themeManager.installTheme(result);
|
||||
await fetchThemes();
|
||||
} catch (error) {
|
||||
console.error('Error parsing file:', error);
|
||||
@@ -84,7 +81,10 @@
|
||||
}
|
||||
|
||||
const fetchThemes = async () => {
|
||||
themes = await getAvailableThemes();
|
||||
themes = {
|
||||
themes: await themeManager.getAvailableThemes(),
|
||||
selectedTheme: themeManager.getSelectedThemeId() || '',
|
||||
}
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
|
||||
@@ -9,16 +9,15 @@
|
||||
import type { Theme } from '../types/Theme'
|
||||
import browser from 'webextension-polyfill'
|
||||
import ThemeModal from '../components/store/ThemeModal.svelte'
|
||||
import { StoreDownloadTheme } from '@/seqta/ui/themes/downloadTheme'
|
||||
import { setTheme } from '@/seqta/ui/themes/setTheme'
|
||||
import Header from '../components/store/Header.svelte'
|
||||
import { deleteTheme } from '@/seqta/ui/themes/deleteTheme'
|
||||
import { getAvailableThemes } from '@/seqta/ui/themes/getAvailableThemes'
|
||||
import { themeUpdates } from '../hooks/ThemeUpdates'
|
||||
import { ThemeManager } from '@/plugins/built-in/themes/theme-manager'
|
||||
|
||||
import { loadBackground } from '@/seqta/ui/ImageBackgrounds'
|
||||
import Backgrounds from '../components/store/Backgrounds.svelte'
|
||||
|
||||
const themeManager = ThemeManager.getInstance();
|
||||
|
||||
// State variables
|
||||
let searchTerm = $state('');
|
||||
let themes = $state<Theme[]>([]);
|
||||
@@ -33,8 +32,8 @@
|
||||
let selectedBackground = $state<string | null>(null);
|
||||
|
||||
const fetchCurrentThemes = async () => {
|
||||
const themes = await getAvailableThemes();
|
||||
currentThemes = themes.themes.filter(theme => theme !== null).map(theme => theme.id);
|
||||
const themes = await themeManager.getAvailableThemes();
|
||||
currentThemes = themes.filter(theme => theme !== null).map(theme => theme.id);
|
||||
};
|
||||
|
||||
const setDisplayTheme = (theme: Theme | null) => {
|
||||
@@ -123,8 +122,8 @@
|
||||
{setDisplayTheme}
|
||||
onInstall={async () => {
|
||||
if (displayTheme) {
|
||||
await StoreDownloadTheme({themeContent: displayTheme})
|
||||
setTheme(displayTheme.id);
|
||||
await themeManager.downloadTheme(displayTheme);
|
||||
await themeManager.setTheme(displayTheme.id);
|
||||
themeUpdates.triggerUpdate();
|
||||
await fetchCurrentThemes();
|
||||
}
|
||||
@@ -132,7 +131,7 @@
|
||||
onRemove={async () => {
|
||||
if (displayTheme?.id) {
|
||||
console.debug('deleting theme', displayTheme.id);
|
||||
deleteTheme(displayTheme.id)
|
||||
await themeManager.deleteTheme(displayTheme.id);
|
||||
themeUpdates.triggerUpdate();
|
||||
await fetchCurrentThemes();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
import { type LoadedCustomTheme } from '@/types/CustomThemes'
|
||||
|
||||
import { settingsState } from '@/seqta/utils/listeners/SettingsState'
|
||||
import { getTheme } from '@/seqta/ui/themes/getTheme'
|
||||
|
||||
import Divider from '@/interface/components/themeCreator/divider.svelte'
|
||||
import Switch from '@/interface/components/Switch.svelte'
|
||||
@@ -22,14 +21,13 @@
|
||||
handleImageVariableChange,
|
||||
handleCoverImageUpload
|
||||
} from '../utils/themeImageHandlers';
|
||||
import { ClearThemePreview, UpdateThemePreview } from '@/seqta/ui/themes/UpdateThemePreview'
|
||||
import { saveTheme } from '@/seqta/ui/themes/saveTheme'
|
||||
import { CloseThemeCreator } from '@/seqta/ui/ThemeCreator'
|
||||
import { themeUpdates } from '../hooks/ThemeUpdates'
|
||||
import { disableTheme } from '@/seqta/ui/themes/disableTheme'
|
||||
import { setTheme } from '@/seqta/ui/themes/setTheme'
|
||||
import { ThemeManager } from '@/plugins/built-in/themes/theme-manager'
|
||||
|
||||
const { themeID } = $props<{ themeID: string }>()
|
||||
const themeManager = ThemeManager.getInstance();
|
||||
|
||||
let theme = $state<LoadedCustomTheme>({
|
||||
id: uuidv4(),
|
||||
name: '',
|
||||
@@ -62,10 +60,10 @@
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
await disableTheme();
|
||||
await themeManager.disableTheme();
|
||||
|
||||
if (themeID) {
|
||||
const tempTheme = await getTheme(themeID)
|
||||
const tempTheme = await themeManager.getTheme(themeID)
|
||||
|
||||
if (!tempTheme) return
|
||||
|
||||
@@ -104,7 +102,7 @@
|
||||
theme = await handleCoverImageUpload(event, theme);
|
||||
}
|
||||
|
||||
function submitTheme() {
|
||||
async function submitTheme() {
|
||||
const themeClone = JSON.parse(JSON.stringify(theme));
|
||||
|
||||
// re-insert blobs into themeClone
|
||||
@@ -114,15 +112,17 @@
|
||||
}))
|
||||
themeClone.coverImage = theme.coverImage
|
||||
|
||||
ClearThemePreview();
|
||||
saveTheme(themeClone);
|
||||
setTheme(themeClone.id);
|
||||
themeManager.clearPreview();
|
||||
await themeManager.saveTheme(themeClone);
|
||||
await themeManager.setTheme(themeClone.id);
|
||||
themeUpdates.triggerUpdate();
|
||||
CloseThemeCreator();
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
UpdateThemePreview(theme);
|
||||
if (themeLoaded) {
|
||||
void themeManager.updatePreview(theme);
|
||||
}
|
||||
});
|
||||
|
||||
type SettingType = 'switch' | 'button' | 'slider' | 'colourPicker' | 'select' | 'codeEditor' | 'imageUpload' | 'conditional' | 'lightDarkToggle';
|
||||
@@ -215,7 +215,7 @@
|
||||
bind:value={image.variableName}
|
||||
oninput={(e) => onImageVariableChange(image.id, e.currentTarget.value)}
|
||||
placeholder="CSS Variable Name"
|
||||
class="grow flex-3 w-full p-2 transition border-0 rounded-lg dark:placeholder-zinc-300 bg-zinc-200 dark:bg-zinc-600/50 focus:bg-zinc-300/50 dark:focus:bg-zinc-600"
|
||||
class="p-2 w-full rounded-lg border-0 transition grow flex-3 dark:placeholder-zinc-300 bg-zinc-200 dark:bg-zinc-600/50 focus:bg-zinc-300/50 dark:focus:bg-zinc-600"
|
||||
/>
|
||||
<button onclick={() => onRemoveImage(image.id)} class="p-2 transition dark:text-white">
|
||||
<span class='text-xl font-IconFamily'>{'\ued8c'}</span>
|
||||
@@ -253,7 +253,7 @@
|
||||
|
||||
<div class='h-screen overflow-y-scroll {$settingsState.DarkMode && "dark"} no-scrollbar'>
|
||||
{#if codeEditorFullscreen}
|
||||
<div class="absolute inset-0 z-10000 bg-white dark:bg-zinc-900 dark:text-white">
|
||||
<div class="absolute inset-0 bg-white z-10000 dark:bg-zinc-900 dark:text-white">
|
||||
<div class="sticky top-0 px-2 h-screen">
|
||||
<div class="flex justify-between items-center my-4">
|
||||
<h2 class="text-xl font-bold">Custom CSS</h2>
|
||||
|
||||
Reference in New Issue
Block a user