[READ-ONLY] Mirror of https://github.com/mrgnw/ananas. learn multiple languages at once ananas.xcc.es
0

Configure Feed

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

deprecation fun

+193 -402
+3 -5
src/jibs/LanguageList.svelte src/jibs/deprecrated/LanguageList.svelte
··· 1 1 <script> 2 2 import { Badge } from "$lib/components/ui/badge"; 3 3 import X from "lucide-svelte/icons/x"; 4 - import { translateLanguages } from '$lib/stores/translateLanguages.svelte.js'; 4 + import { translateLanguages } from '$jibs/deprecrated/translateLanguages.svelte.js'; 5 5 6 6 let selectedCodes = $derived(() => Object.keys(translateLanguages.languages)); 7 - 7 + 8 8 function removeLanguage(code) { 9 - // The store will handle normalization internally 10 9 translateLanguages.removeLanguage(code); 11 10 } 12 11 ··· 14 13 function handle_variant(hovered_lang) { 15 14 return hovered_lang == selected_lang_to_remove ? "destructive" : "outline"; 16 15 } 17 - 18 16 </script> 19 17 20 18 <div class="selected-languages"> 21 19 <ul> 22 - {#each selectedCodes as langCode} 20 + {#each selectedCodes as langCode (langCode)} 23 21 <li> 24 22 <Badge variant={handle_variant(langCode)}> 25 23 {translateLanguages.getLanguageInfo(langCode)?.label || langCode}
-177
src/jibs/LanguagePicker.svelte
··· 1 - <script lang="ts"> 2 - import Check from "lucide-svelte/icons/check"; 3 - import { Combobox } from "bits-ui"; 4 - import { languages } from 'countries-list'; 5 - import LanguageList from './LanguageList.svelte'; 6 - import { translateLanguages } from '$lib/stores/translateLanguages.svelte.js'; 7 - import languageData from '$lib/data/wikidata-languages.json'; 8 - import { Languages, Plus } from 'lucide-svelte'; 9 - 10 - let selectedCodes = $derived(() => Object.keys(translateLanguages.languages)); 11 - 12 - const iso3ToIso1Map = new Map( 13 - languageData.filter(lang => lang.iso1).map(lang => [lang.iso, lang.iso1]) 14 - ); 15 - 16 - const countryLanguages = new Map( 17 - Object.entries(languages).map(([code, info]) => [code, { 18 - value: code, 19 - label: info.name, 20 - native: info.native 21 - }]) 22 - ); 23 - 24 - const customLanguages = new Map([ 25 - ['scn', { value: 'scn', label: 'Sicilian', native: 'Sicilianu' }] 26 - ]); 27 - 28 - const allLanguages = new Map(); 29 - countryLanguages.forEach((info, code) => allLanguages.set(code, info)); 30 - customLanguages.forEach((info, code) => allLanguages.set(code, info)); 31 - languageData.forEach(lang => { 32 - if (!lang.iso1 && !allLanguages.has(lang.iso)) { 33 - allLanguages.set(lang.iso, { 34 - value: lang.iso, 35 - label: lang.langLabel, 36 - native: lang.nativeNames?.[0] || lang.langLabel 37 - }); 38 - } 39 - }); 40 - 41 - let inputValue = $state(""); 42 - let langs = $derived(() => Array.from(allLanguages.values())); 43 - let filteredLangs = $derived(() => filterLanguages(inputValue)); 44 - 45 - function isLanguageSelected(langCode) { 46 - const codeToCheck = iso3ToIso1Map.get(langCode) || langCode; 47 - return selectedCodes.includes(codeToCheck) || selectedCodes.includes(langCode); 48 - } 49 - 50 - function handleLanguageAdd(langCode) { 51 - const codeToUse = iso3ToIso1Map.get(langCode) || langCode; 52 - const langInfo = allLanguages.get(codeToUse) || allLanguages.get(langCode); 53 - if (!selectedCodes.includes(codeToUse)) { 54 - translateLanguages.addLanguage(codeToUse, { 55 - label: langInfo?.label || codeToUse, 56 - native: langInfo?.native || codeToUse, 57 - rtl: false, 58 - display: true 59 - }); 60 - } 61 - inputValue = ""; 62 - } 63 - 64 - function filterLanguages(inputValue) { 65 - const lowerInput = inputValue.toLowerCase(); 66 - return langs 67 - .filter( 68 - (lang) => 69 - lang.value.toLowerCase().includes(lowerInput) || 70 - lang.label.toLowerCase().includes(lowerInput) || 71 - lang.native.toLowerCase().includes(lowerInput) 72 - ) 73 - .sort((a, b) => { 74 - const aExactMatch = a.value.toLowerCase() === lowerInput; 75 - const bExactMatch = b.value.toLowerCase() === lowerInput; 76 - if (aExactMatch && !bExactMatch) return -1; 77 - if (!aExactMatch && bExactMatch) return 1; 78 - const aStartsWith = a.value.toLowerCase().startsWith(lowerInput) || 79 - a.label.toLowerCase().startsWith(lowerInput) || 80 - a.native.toLowerCase().startsWith(lowerInput); 81 - const bStartsWith = b.value.toLowerCase().startsWith(lowerInput) || 82 - b.label.toLowerCase().startsWith(lowerInput) || 83 - b.native.toLowerCase().startsWith(lowerInput); 84 - if (aStartsWith && !bStartsWith) return -1; 85 - if (!aStartsWith && bStartsWith) return 1; 86 - return 0; 87 - }); 88 - } 89 - 90 - function handleKeyDown(event) { 91 - if (event.key === 'Enter') { 92 - const exactMatch = filteredLangs.find(lang => lang.value.toLowerCase() === inputValue.toLowerCase()); 93 - if (exactMatch) { 94 - handleLanguageAdd(exactMatch.value); 95 - } 96 - } 97 - } 98 - 99 - function getLanguageName(lang) { 100 - return lang.label || lang.native || lang.code; 101 - } 102 - </script> 103 - 104 - <div class="flex gap-2 items-center"> 105 - <div class="flex gap-1"> 106 - {#each $translateLanguages as lang} 107 - <button on:click={() => translateLanguages.removeLanguage(lang)} class="px-2 py-1 bg-gray-100 rounded hover:bg-gray-200"> 108 - {getLanguageName(lang)} 109 - </button> 110 - {/each} 111 - </div> 112 - <a href="/languages" class="p-2 hover:text-yellow-500 transition-colors" title="Add or remove languages"> 113 - <Languages class="w-5 h-5" /> 114 - </a> 115 - </div> 116 - 117 - <Combobox.Root items={filteredLangs} bind:inputValue touchedInput=open> 118 - <div class="relative"> 119 - <Combobox.Input 120 - class="inline-flex h-input w-[296px] truncate rounded-9px border border-border-input bg-background px-11 text-sm transition-colors placeholder:text-foreground-alt/50 focus:outline-none focus:ring-2 focus:ring-foreground focus:ring-offset-2 focus:ring-offset-background" 121 - placeholder="Add a language" aria-label="Add a language" onkeydown={handleKeyDown} /> 122 - </div> 123 - <Combobox.Content class="w-full rounded-xl border border-muted bg-background px-1 py-3 shadow-popover outline-none"> 124 - {#each filteredLangs as lang} 125 - <Combobox.Item value={lang.value} label="{lang.label} | {lang.native}" 126 - class="cursor-pointer flex items-center justify-between" onclick={()=> handleLanguageAdd(lang.value)} 127 - > 128 - <span class="flex items-center"> 129 - {#if isLanguageSelected(lang.value)} 130 - <Check class="mr-2" /> 131 - {:else} 132 - <span class="mr-2" style="width: 1em; height: 1em;"></span> 133 - {/if} 134 - {lang.label} | {lang.native} 135 - </span> 136 - </Combobox.Item> 137 - {:else} 138 - <span class="block px-5 py-2 text-sm text-muted-foreground"> 139 - No results found 140 - </span> 141 - {/each} 142 - </Combobox.Content> 143 - </Combobox.Root> 144 - 145 - <LanguageList /> 146 - 147 - <style> 148 - .language-picker { 149 - display: grid; 150 - grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); 151 - gap: 10px; 152 - max-height: 300px; 153 - overflow-y: auto; 154 - } 155 - 156 - .language-item { 157 - display: flex; 158 - align-items: center; 159 - gap: 8px; 160 - } 161 - 162 - .flag { 163 - font-size: 1.5em; 164 - } 165 - 166 - .lang-name { 167 - font-size: 0.9em; 168 - } 169 - 170 - .selected-languages { 171 - margin-bottom: 20px; 172 - } 173 - 174 - .highlight { 175 - color: blue; 176 - } 177 - </style>
+1 -1
src/jibs/LanguageVisibility.svelte src/jibs/deprecrated/LanguageVisibility.svelte
··· 10 10 DropdownMenuRadioItem, 11 11 DropdownMenuCheckboxItem 12 12 } from '$lib/components/ui/dropdown-menu'; 13 - import { translateLanguages } from '$lib/stores/translateLanguages.svelte.js'; 13 + import { translateLanguages } from '$jibs/deprecrated/translateLanguages.svelte.js'; 14 14 15 15 import DropdownMenuLabel from '@/components/ui/dropdown-menu/dropdown-menu-label.svelte'; 16 16 import { DropdownMenu, DropdownMenu } from 'bits-ui';
+11 -4
src/jibs/NewLang.svelte src/jibs/deprecrated/NewLang.svelte
··· 1 1 <script> 2 2 import { exampleTranslations } from '$lib/example'; 3 - import { translateLanguages } from '$lib/stores/translateLanguages.svelte.js'; 4 3 import { translationHistory } from '$lib/stores/translationHistory.svelte.js'; 5 4 import { exampleTyper } from '$lib/stores/exampleTyper.svelte.js'; 6 5 import { translationStateMachine, STATES } from '$lib/stores/translationStateMachine.svelte.js'; ··· 13 12 import PlayPauseButton from './PlayPauseButton.svelte'; 14 13 import { getColorByIndex } from '$lib/colors'; 15 14 import { onMount, onDestroy } from 'svelte'; 15 + import { userStore } from '$lib/stores/user.svelte.js'; 16 16 17 17 // State tracking variables 18 18 let isTyping = $state(false); ··· 86 86 let truncate_lines = $state(true); 87 87 88 88 // Language management 89 - let user_langs = $derived(translateLanguages.languages); 90 - let tgt_langs = $derived(Object.keys(user_langs)); 91 - let show_langs = $derived( 89 + let user_langs = $derived(() => userStore.user.selectedLanguages); 90 + let tgt_langs = $derived(() => userStore.user.selectedLanguages); 91 + let show_langs = $derived(() => 92 92 Object.entries(user_langs) 93 93 .filter(([_, lang]) => lang.display) 94 94 .map(([key, _]) => key) ··· 247 247 translationStateMachine.actions.userTyping(); 248 248 exampleTyper.markUserTyped(); 249 249 } 250 + } 251 + 252 + function addDefaultLanguages() { 253 + // Set some default ISO codes (e.g. English, Russian, Japanese, Spanish, Italian, Catalan) 254 + const defaults = ['eng', 'rus', 'jpn', 'spa', 'ita', 'cat']; 255 + defaults.forEach(code => userStore.addLanguage(code)); 256 + toast.success("Added default languages"); 250 257 } 251 258 </script> 252 259
src/jibs/PlayPauseButton.svelte src/jibs/deprecrated/PlayPauseButton.svelte
src/jibs/TranslationInput.svelte src/jibs/deprecrated/TranslationInput.svelte
+64
src/jibs/deprecrated/LanguagePicker.svelte
··· 1 + <script lang="ts"> 2 + import { userStore } from '$lib/stores/user.svelte.js'; 3 + import languageData from '$lib/data/wikidata-languages.json'; 4 + import Check from "lucide-svelte/icons/check"; 5 + 6 + // All available languages 7 + const allLanguages = languageData.map(lang => ({ 8 + code: lang.iso, 9 + label: lang.langLabel, 10 + native: lang.nativeNames?.[0] || lang.langLabel 11 + })); 12 + 13 + function addLanguage(code) { 14 + userStore.addLanguage(code); 15 + } 16 + 17 + function removeLanguage(code) { 18 + userStore.removeLanguage(code); 19 + } 20 + 21 + function isSelected(code) { 22 + // Always reference the store directly for reactivity 23 + return userStore.user.selectedLanguages.includes(code); 24 + } 25 + </script> 26 + 27 + <!-- Selected languages at the top --> 28 + <div class="selected-languages flex gap-2 mb-4 flex-wrap"> 29 + {#each userStore.user.selectedLanguages as code (code)} 30 + <span class="px-2 py-1 bg-gray-200 rounded flex items-center gap-1"> 31 + {allLanguages.find(l => l.code === code)?.label || code} 32 + <button on:click={() => removeLanguage(code)} aria-label="Remove"> 33 + &times; 34 + </button> 35 + </span> 36 + {/each} 37 + </div> 38 + 39 + <!-- All languages (no sorting) --> 40 + <ul class="all-languages space-y-1"> 41 + {#each allLanguages as lang (lang.code)} 42 + <li class="flex items-center gap-2"> 43 + <button 44 + disabled={isSelected(lang.code)} 45 + on:click={() => addLanguage(lang.code)} 46 + class="border rounded px-2 py-1" 47 + aria-label={isSelected(lang.code) ? "Selected" : "Add"} 48 + > 49 + {#if isSelected(lang.code)} 50 + <Check class="inline w-4 h-4 text-green-600" /> 51 + {:else} 52 + + 53 + {/if} 54 + </button> 55 + <span>{lang.label} <span class="text-gray-500">({lang.native})</span></span> 56 + </li> 57 + {/each} 58 + </ul> 59 + 60 + <style> 61 + .selected-languages { 62 + flex-wrap: wrap; 63 + } 64 + </style>
+103
src/jibs/deprecrated/translateLanguages.svelte.js
··· 1 + import { defaultLanguages } from '$lib/utils/languages.js'; 2 + import languageData from '$lib/data/wikidata-languages.json'; 3 + 4 + function normalizeLanguageCode(code) { 5 + return code; 6 + } 7 + 8 + // Single source of truth for selected languages 9 + let languages = $state({}); 10 + 11 + function loadFromStorage() { 12 + if (typeof localStorage === 'undefined') return false; 13 + try { 14 + const saved = localStorage.getItem('user_langs'); 15 + if (saved) { 16 + const parsed = JSON.parse(saved); 17 + Object.keys(languages).forEach(k => delete languages[k]); 18 + Object.assign(languages, parsed); 19 + return true; 20 + } 21 + } catch (e) { 22 + // ignore 23 + } 24 + return false; 25 + } 26 + 27 + function saveToStorage() { 28 + if (typeof localStorage === 'undefined') return; 29 + try { 30 + localStorage.setItem('user_langs', JSON.stringify(languages)); 31 + localStorage.setItem('tgt_langs', JSON.stringify(Object.keys(languages))); 32 + } catch (e) { 33 + // ignore 34 + } 35 + } 36 + 37 + function addLanguage(code, info) { 38 + const normalized = normalizeLanguageCode(code); 39 + if (!languages[normalized]) { 40 + languages[normalized] = { 41 + label: info.label || code, 42 + native: info.native || code, 43 + rtl: info.rtl || false, 44 + display: true 45 + }; 46 + saveToStorage(); 47 + } 48 + } 49 + 50 + function removeLanguage(code) { 51 + const normalized = normalizeLanguageCode(code); 52 + if (languages[normalized]) { 53 + delete languages[normalized]; 54 + saveToStorage(); 55 + } 56 + } 57 + 58 + function clearLanguages() { 59 + Object.keys(languages).forEach(k => delete languages[k]); 60 + saveToStorage(); 61 + } 62 + 63 + function resetToDefaults() { 64 + Object.keys(languages).forEach(k => delete languages[k]); 65 + Object.assign(languages, defaultLanguages); 66 + saveToStorage(); 67 + } 68 + 69 + function addDefaultLanguages() { 70 + Object.assign(languages, defaultLanguages); 71 + saveToStorage(); 72 + } 73 + 74 + function toggleLanguageDisplay(code) { 75 + const normalized = normalizeLanguageCode(code); 76 + if (languages[normalized]) { 77 + languages[normalized].display = !languages[normalized].display; 78 + saveToStorage(); 79 + } 80 + } 81 + 82 + function getLanguageInfo(code) { 83 + const normalized = normalizeLanguageCode(code); 84 + return languages[normalized]; 85 + } 86 + 87 + // On module load, initialize from storage or defaults 88 + if (!loadFromStorage()) { 89 + Object.assign(languages, defaultLanguages); 90 + saveToStorage(); 91 + } 92 + 93 + export const translateLanguages = { 94 + languages, // $state object 95 + addLanguage, 96 + removeLanguage, 97 + clearLanguages, 98 + resetToDefaults, 99 + addDefaultLanguages, 100 + toggleLanguageDisplay, 101 + getLanguageInfo, 102 + normalizeLanguageCode 103 + };
-1
src/lib/components/SettingsButton.svelte
··· 3 3 import { Settings } from "lucide-svelte"; 4 4 import { toast } from "svelte-sonner"; 5 5 import * as DropdownMenu from "$lib/components/ui/dropdown-menu"; 6 - import { translateLanguages } from '$lib/stores/translateLanguages.svelte.js' 7 6 import { userStore } from '$lib/stores/user.svelte.js'; 8 7 import { defaultLanguages } from '$lib/utils/languages.js'; 9 8
-45
src/lib/stores.ts
··· 1 - import { writable } from 'svelte/store'; 2 - import { translateLanguages } from './stores/translateLanguages.svelte.js'; 3 - 4 - // Create a writable store that syncs with translateLanguages 5 - function createLanguagesStore() { 6 - const { subscribe, set, update } = writable<string[]>([]); 7 - 8 - return { 9 - subscribe, 10 - update: (fn: (value: string[]) => string[]) => { 11 - update(fn); 12 - // Sync with translateLanguages store 13 - const newValue = fn([]); 14 - newValue.forEach(code => { 15 - if (!translateLanguages.languages[code]) { 16 - translateLanguages.addLanguage(code, { 17 - label: code, 18 - native: code, 19 - rtl: false, 20 - display: true 21 - }); 22 - } 23 - }); 24 - }, 25 - set: (value: string[]) => { 26 - set(value); 27 - // Sync with translateLanguages store 28 - value.forEach(code => { 29 - if (!translateLanguages.languages[code]) { 30 - translateLanguages.addLanguage(code, { 31 - label: code, 32 - native: code, 33 - rtl: false, 34 - display: true 35 - }); 36 - } 37 - }); 38 - } 39 - }; 40 - } 41 - 42 - export const languages = createLanguagesStore(); 43 - 44 - // Initialize the store with current translateLanguages values 45 - languages.set(Object.keys(translateLanguages.languages));
-166
src/lib/stores/translateLanguages.svelte.js
··· 1 - import { defaultLanguages } from '$lib/utils/languages.js'; 2 - import languageData from '$lib/data/wikidata-languages.json'; 3 - 4 - function normalizeLanguageCode(code) { 5 - return code; 6 - } 7 - 8 - let languages = $state({}); // <-- Move this outside the factory for singleton reactivity 9 - 10 - function initializeFromStorage() { 11 - if (typeof localStorage === 'undefined') { 12 - // If localStorage isn't available, just use defaults 13 - languages = { ...defaultLanguages }; 14 - return; 15 - } 16 - 17 - try { 18 - // Load saved languages if they exist 19 - const savedUserLangs = localStorage.getItem('user_langs'); 20 - if (savedUserLangs) { 21 - const saved = JSON.parse(savedUserLangs); 22 - languages = { ...saved }; 23 - } else { 24 - // If no saved languages, use defaults 25 - languages = { ...defaultLanguages }; 26 - 27 - // Check legacy format as fallback 28 - const oldLangs = localStorage.getItem('tgt_langs'); 29 - if (oldLangs) { 30 - const oldCodes = JSON.parse(oldLangs); 31 - oldCodes.forEach(code => { 32 - const normalizedCode = normalizeLanguageCode(code); 33 - if (!languages[normalizedCode]) { 34 - languages[normalizedCode] = { 35 - label: code, 36 - native: code, 37 - rtl: false, 38 - display: true 39 - }; 40 - } 41 - }); 42 - } 43 - } 44 - 45 - saveToStorage(); 46 - console.log('Initialized languages:', Object.keys(languages)); 47 - } catch (e) { 48 - console.error('Failed to initialize languages from storage:', e); 49 - // Fallback to defaults 50 - languages = { ...defaultLanguages }; 51 - } 52 - } 53 - 54 - function saveToStorage() { 55 - if (typeof localStorage === 'undefined') return; 56 - 57 - try { 58 - const languagesStr = JSON.stringify(languages); 59 - localStorage.setItem('user_langs', languagesStr); 60 - // Keep tgt_langs in sync for backward compatibility 61 - localStorage.setItem('tgt_langs', JSON.stringify(Object.keys(languages))); 62 - console.log('Saved languages:', Object.keys(languages)); 63 - } catch (e) { 64 - console.error('Failed to save languages to storage:', e); 65 - } 66 - } 67 - 68 - function addLanguage(code, info) { 69 - if (!code || !info) { 70 - throw new Error('Language code and info are required'); 71 - } 72 - 73 - const normalizedCode = normalizeLanguageCode(code); 74 - console.log('Adding language:', { original: code, normalized: normalizedCode }); 75 - 76 - // If it's already in the store with the normalized code, don't add it again 77 - if (languages[normalizedCode]) { 78 - console.log('Language already exists with normalized code:', normalizedCode); 79 - return; 80 - } 81 - 82 - languages[normalizedCode] = { 83 - label: info.label || code, 84 - native: info.native || code, 85 - rtl: info.rtl || false, 86 - display: true 87 - }; 88 - saveToStorage(); 89 - } 90 - 91 - function removeLanguage(code) { 92 - if (!code) { 93 - throw new Error('Language code is required'); 94 - } 95 - 96 - const normalizedCode = normalizeLanguageCode(code); 97 - console.log('Removing language:', { original: code, normalized: normalizedCode }); 98 - 99 - delete languages[normalizedCode]; 100 - saveToStorage(); 101 - } 102 - 103 - function getSelectedCodes() { 104 - return Object.keys(languages); 105 - } 106 - 107 - function getLanguageInfo(code) { 108 - const normalizedCode = normalizeLanguageCode(code); 109 - return languages[normalizedCode]; 110 - } 111 - 112 - function clearLanguages() { 113 - // Clear all languages 114 - languages = {}; 115 - if (typeof localStorage !== 'undefined') { 116 - localStorage.removeItem('user_langs'); 117 - localStorage.removeItem('tgt_langs'); 118 - } 119 - 120 - saveToStorage(); 121 - console.log('Cleared all languages'); 122 - } 123 - 124 - function addDefaultLanguages() { 125 - // Add default languages to the current set 126 - languages = { ...languages, ...defaultLanguages }; 127 - saveToStorage(); 128 - console.log('Added default languages:', Object.keys(defaultLanguages)); 129 - } 130 - 131 - function resetToDefaults() { 132 - // Clear current languages and set to defaults 133 - languages = { ...defaultLanguages }; 134 - saveToStorage(); 135 - console.log('Reset to defaults:', Object.keys(languages)); 136 - } 137 - 138 - function toggleLanguageDisplay(code) { 139 - const normalizedCode = normalizeLanguageCode(code); 140 - const langInfo = languages[normalizedCode]; 141 - if (langInfo) { 142 - languages[normalizedCode] = { 143 - ...langInfo, 144 - display: !langInfo.display 145 - }; 146 - saveToStorage(); 147 - console.log('Toggled display for:', normalizedCode, 'to:', !langInfo.display); 148 - } 149 - } 150 - 151 - // Initialize on module load 152 - initializeFromStorage(); 153 - 154 - export const translateLanguages = { 155 - languages, // <-- Export the $state object directly 156 - get selectedCodes() { return getSelectedCodes(); }, 157 - getLanguageInfo, 158 - addLanguage, 159 - removeLanguage, 160 - clearLanguages, 161 - addDefaultLanguages, 162 - resetToDefaults, 163 - toggleLanguageDisplay, 164 - normalizeLanguageCode, 165 - _initializeFromStorage: initializeFromStorage 166 - };
src/lib/stores/translationHistory.svelte.js src/jibs/deprecrated/translationHistory.svelte.js
src/lib/stores/translationStateMachine.svelte.js src/jibs/deprecrated/translationStateMachine.svelte.js
+1 -1
src/routes/+page.svelte
··· 1 1 <script lang="ts"> 2 2 import type { PageData } from './$types'; 3 - import NewLang from '$jibs/NewLang.svelte'; 3 + import NewLang from '$jibs/deprecrated/NewLang.svelte'; 4 4 import { translationInput } from '$lib/stores/translationStore'; 5 5 6 6 interface Props {
+9 -1
src/routes/languages/+page.svelte
··· 46 46 }, {}) 47 47 ); 48 48 49 + // Add a $derived for selectedCodes that always returns an array 50 + let selectedCodes = $derived(() => Array.isArray(translateLanguages.selectedCodes) ? translateLanguages.selectedCodes : (Object.keys(translateLanguages.languages) ?? [])); 51 + 49 52 function toggleLanguage(code: string) { 50 53 if (isSelected(code)) { 51 54 translateLanguages.removeLanguage(code); ··· 60 63 } 61 64 62 65 function isSelected(code: string) { 63 - return translateLanguages.selectedCodes.includes(code); 66 + const codes = Array.isArray(selectedCodes) 67 + ? selectedCodes 68 + : (selectedCodes && typeof selectedCodes === 'object') 69 + ? Object.values(selectedCodes) 70 + : []; 71 + return codes.includes(code); 64 72 } 65 73 66 74 function formatSpeakers(count: number | undefined) {
+1 -1
src/routes/test/+page.svelte
··· 1 1 <script> 2 - import { translateLanguages, createTranslateLanguages } from '$lib/stores/translateLanguages.svelte.js'; 2 + import { translateLanguages, createTranslateLanguages } from '$jibs/deprecrated/translateLanguages.svelte.js'; 3 3 4 4 // Test data 5 5 const testLanguages = {