feat(settings): add working shortcuts and custom shortcuts

This commit is contained in:
sethburkart123
2024-09-06 17:29:07 +10:00
parent 7f93aef9cc
commit 9363de5fb4
9 changed files with 194 additions and 61 deletions
+14 -11
View File
@@ -7,6 +7,7 @@
import { createStandalone } from '../utils/standalone.svelte';
import { onMount } from 'svelte'
import { settingsState } from '@/seqta/utils/listeners/SettingsState'
const openChangelog = () => {
browser.runtime.sendMessage({ type: 'currentTab', info: 'OpenChangelog' });
@@ -21,16 +22,18 @@
});
</script>
<div class="relative flex flex-col w-[384px] shadow-2xl gap-2 bg-white { standalone ? 'h-[600px]' : 'h-[100vh] rounded-xl' } overflow-clip dark:bg-zinc-800 dark:text-white">
<div class="grid border-b border-b-zinc-200/40 place-items-center">
<img src={browser.runtime.getURL('resources/icons/betterseqta-dark-full.png')} class="w-4/5 dark:hidden" alt="Light logo" />
<img src={browser.runtime.getURL('resources/icons/betterseqta-light-full.png')} class="hidden w-4/5 dark:block" alt="Dark logo" />
<button onclick={openChangelog} class="absolute w-8 h-8 text-lg rounded-xl font-IconFamily top-1 right-1 bg-zinc-100 dark:bg-zinc-700"></button>
</div>
<div class="w-[384px] shadow-2xl {$settingsState.DarkMode ? 'dark' : ''} { standalone ? 'h-[600px]' : 'h-full rounded-xl' } overflow-clip">
<div class="relative flex flex-col h-full gap-2 bg-white overflow-clip dark:bg-zinc-800 dark:text-white">
<div class="grid border-b border-b-zinc-200/40 place-items-center">
<img src={browser.runtime.getURL('resources/icons/betterseqta-dark-full.png')} class="w-4/5 dark:hidden" alt="Light logo" />
<img src={browser.runtime.getURL('resources/icons/betterseqta-light-full.png')} class="hidden w-4/5 dark:block" alt="Dark logo" />
<button onclick={openChangelog} class="absolute w-8 h-8 text-lg rounded-xl font-IconFamily top-1 right-1 bg-zinc-100 dark:bg-zinc-700"></button>
</div>
<TabbedContainer tabs={[
{ title: 'Settings', Content: Settings },
{ title: 'Shortcuts', Content: Shortcuts },
{ title: 'Themes', Content: Theme },
]} />
<TabbedContainer tabs={[
{ title: 'Settings', Content: Settings },
{ title: 'Shortcuts', Content: Shortcuts },
{ title: 'Themes', Content: Theme },
]} />
</div>
</div>
@@ -22,7 +22,7 @@
</div>
{/snippet}
<div class="flex flex-col -mt-4 overflow-y-scroll divide-y divide-zinc-100 dark:divide-zinc-700">
<div class="flex flex-col divide-y divide-zinc-100 dark:divide-zinc-700">
{#each [
{
title: "Transparency Effects",
@@ -1,25 +1,130 @@
<script lang="ts">
import { settingsState } from "@/seqta/utils/listeners/SettingsState.ts"
// @ts-expect-error umm idk
import { MotionDiv } from 'svelte-motion';
import { settingsState } from "@/seqta/utils/listeners/SettingsState.ts"
import Switch from "@/svelte-interface/components/Switch.svelte"
const switchChange = (index: number) => {
const updatedShortcuts = [...settingsState.shortcuts];
updatedShortcuts[index].enabled = !updatedShortcuts[index].enabled;
settingsState.shortcuts = updatedShortcuts;
}
let isFormVisible = $state(false);
let newTitle = $state("");
let newURL = $state("");
const toggleForm = () => {
isFormVisible = !isFormVisible;
};
const formatUrl = (inputUrl: string) => {
const protocolRegex = /^(http:\/\/|https:\/\/|ftp:\/\/)/;
return protocolRegex.test(inputUrl) ? inputUrl : `https://${inputUrl}`;
};
const isValidTitle = (title: string) => title.trim() !== "";
const isValidURL = (url: string) => {
const pattern = new RegExp("^(https?:\\/\\/)?[\\w.-]+(?:\\.[\\w\\-]+)*(?::\\d+)?(/[\\w\\-./]*)*$", "i");
return pattern.test(url);
};
const addNewCustomShortcut = () => {
if (isValidTitle(newTitle) && isValidURL(newURL)) {
const newShortcut = { name: newTitle.trim(), url: formatUrl(newURL).trim(), icon: newTitle[0] };
settingsState.customshortcuts = [...settingsState.customshortcuts, newShortcut];
newTitle = "";
newURL = "";
isFormVisible = false;
} else {
alert("Please enter a valid title and URL.");
}
};
const deleteCustomShortcut = (index: number) => {
settingsState.customshortcuts = settingsState.customshortcuts.filter((_, i) => i !== index);
};
const springTransition = { type: 'spring', damping: 20 };
</script>
{#snippet Shortcuts([string, Shortcut]) }
{#snippet Shortcuts([index, Shortcut]: [string, { name: string, enabled: boolean }]) }
<div class="flex items-center justify-between px-4 py-3">
<div class="pr-4">
<h2 class="text-sm font-bold">{Shortcut.name}</h2>
<p class="text-xs">{Shortcut.enabled}</p>
<h2 class="text-sm">{Shortcut.name}</h2>
</div>
<Switch state={Shortcut.enabled} onChange={() => switchChange(parseInt(index))} />
</div>
{/snippet}
<div class="flex flex-col pt-4 divide-y divide-zinc-100 dark:divide-zinc-700">
<div>
<MotionDiv
initial={{ opacity: 0, height: 0 }}
animate={isFormVisible ? { opacity: 1, height: "auto" } : { opacity: 0, height: 0 }}
exit={{ opacity: 0, height: 0 }}
transition={springTransition}
>
{#if isFormVisible}
<div class="flex flex-col items-center">
<MotionDiv
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.1, duration: 0.4 }}
class="w-full"
>
<input
class="w-full p-2 transition border-0 rounded-lg placeholder-zinc-300 bg-zinc-100 dark:bg-zinc-700 focus:bg-zinc-200/50 dark:focus:bg-zinc-600"
type="text"
placeholder="Shortcut Name"
bind:value={newTitle}
/>
</MotionDiv>
<MotionDiv
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.2, duration: 0.4 }}
class="w-full"
>
<input
class="w-full p-2 my-2 transition border-0 rounded-lg placeholder-zinc-300 bg-zinc-100 dark:bg-zinc-700 focus:bg-zinc-200/50 dark:focus:bg-zinc-600"
type="text"
placeholder="URL eg. https://google.com"
bind:value={newURL}
/>
</MotionDiv>
</div>
{/if}
</MotionDiv>
<div class="text-xl">shortcuts tab</div>
<MotionDiv
animate={isFormVisible ? { y: 0 } : { y: 0 }}
transition={springTransition}
>
<button
class="w-full px-4 py-2 mb-4 text-white transition rounded-xl bg-zinc-700/50"
onclick={isFormVisible ? addNewCustomShortcut : toggleForm}
>
{isFormVisible ? 'Add' : 'Add Custom Shortcut'}
</button>
</MotionDiv>
</div>
<div class="flex flex-col -mt-4 overflow-y-scroll divide-y divide-zinc-100 dark:divide-zinc-700">
{#each Object.entries(settingsState.shortcuts) as shortcut}
<!-- do processing stuff here -->
{@render Shortcuts(shortcut)}
{/each}
{#each Object.entries($settingsState.shortcuts) as shortcut}
{@render Shortcuts(shortcut)}
{/each}
<!-- Custom Shortcuts Section -->
{#each $settingsState.customshortcuts as shortcut, index}
<div class="flex items-center justify-between px-4 py-3">
{shortcut.name}
<button onclick={() => deleteCustomShortcut(index)}>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width={1.5} stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
{/each}
</div>