your personal website on atproto - mirror blento.app
25
fork

Configure Feed

Select the types of activity you want to include in your feed.

at fix/layout-stuff 97 lines 2.9 kB view raw
1<script lang="ts" module> 2 export const settingsModalState = $state({ 3 visible: false, 4 show: () => (settingsModalState.visible = true), 5 hide: () => (settingsModalState.visible = false) 6 }); 7</script> 8 9<script lang="ts"> 10 import type { WebsiteData } from '$lib/types'; 11 import Modal from '$lib/components/modal/Modal.svelte'; 12 13 let { data = $bindable() }: { data: WebsiteData } = $props(); 14 15 type LayoutMode = NonNullable<WebsiteData['publication']['preferences']>['layoutMode']; 16 17 type LayoutOption = { 18 key: string; 19 value: LayoutMode; 20 label: string; 21 description: string; 22 }; 23 24 const options: LayoutOption[] = [ 25 { 26 key: 'automatic', 27 value: undefined, 28 label: 'Automatic', 29 description: 'Automatically syncs layouts until both are edited independently' 30 }, 31 { 32 key: 'desktop-leads', 33 value: 'desktop-leads', 34 label: 'Desktop drives mobile', 35 description: 'Desktop edits update mobile, mobile edits are independent' 36 }, 37 { 38 key: 'mobile-leads', 39 value: 'mobile-leads', 40 label: 'Mobile drives desktop', 41 description: 'Mobile edits update desktop, desktop edits are independent' 42 }, 43 { 44 key: 'independent', 45 value: 'independent', 46 label: 'Independent', 47 description: 'Desktop and mobile layouts are fully independent' 48 } 49 ]; 50 51 let selected = $derived(data.publication.preferences?.layoutMode ?? 'automatic'); 52 53 function selectOption(option: LayoutOption) { 54 data.publication.preferences ??= {}; 55 data.publication.preferences.layoutMode = option.value; 56 data = { ...data }; 57 } 58</script> 59 60<Modal bind:open={settingsModalState.visible}> 61 <h3 class="text-base-900 dark:text-base-100 text-lg font-semibold">Settings</h3> 62 63 <div class="mt-4"> 64 <h4 class="text-base-800 dark:text-base-200 text-sm font-medium">Layout Sync</h4> 65 <p class="text-base-500 dark:text-base-400 mt-1 text-xs"> 66 Control how desktop and mobile layouts stay in sync. 67 </p> 68 69 <div class="mt-3 flex flex-col gap-2"> 70 {#each options as option (option.key)} 71 {@const isSelected = option.key === (selected === undefined ? 'automatic' : selected)} 72 <button 73 type="button" 74 class="border-base-200 dark:border-base-700 hover:border-base-300 dark:hover:border-base-600 rounded-xl border-2 px-4 py-3 text-left transition-colors {isSelected 75 ? 'border-accent-500 bg-accent-50 dark:bg-accent-950/20' 76 : 'bg-base-50 dark:bg-base-800/50'}" 77 onclick={() => selectOption(option)} 78 > 79 <span 80 class="text-sm font-semibold {isSelected 81 ? 'text-accent-700 dark:text-accent-300' 82 : 'text-base-900 dark:text-base-100'}" 83 > 84 {option.label} 85 </span> 86 <p 87 class="mt-0.5 text-xs {isSelected 88 ? 'text-accent-600 dark:text-accent-400' 89 : 'text-base-500 dark:text-base-400'}" 90 > 91 {option.description} 92 </p> 93 </button> 94 {/each} 95 </div> 96 </div> 97</Modal>