[READ-ONLY] Mirror of https://github.com/probablykasper/ferrum. Music library app for Mac, Linux and Windows ferrum.kasper.space
electron linux macos music music-library music-player napi windows
0

Configure Feed

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

Remember library location

Kasper (Mar 5, 2026, 2:02 PM +0100) a882b9de 4cabf15b

+65 -17
+17
Cargo.lock
··· 1152 1152 "tauri-plugin-dialog", 1153 1153 "tauri-plugin-fs", 1154 1154 "tauri-plugin-opener", 1155 + "tauri-plugin-store", 1155 1156 "tauri-specta", 1156 1157 ] 1157 1158 ··· 4403 4404 "url", 4404 4405 "windows 0.61.3", 4405 4406 "zbus", 4407 + ] 4408 + 4409 + [[package]] 4410 + name = "tauri-plugin-store" 4411 + version = "2.4.2" 4412 + source = "registry+https://github.com/rust-lang/crates.io-index" 4413 + checksum = "5ca1a8ff83c269b115e98726ffc13f9e548a10161544a92ad121d6d0a96e16ea" 4414 + dependencies = [ 4415 + "dunce", 4416 + "serde", 4417 + "serde_json", 4418 + "tauri", 4419 + "tauri-plugin", 4420 + "thiserror 2.0.16", 4421 + "tokio", 4422 + "tracing", 4406 4423 ] 4407 4424 4408 4425 [[package]]
+11 -1
mobile/package-lock.json
··· 12 12 "@tauri-apps/api": "^2", 13 13 "@tauri-apps/plugin-dialog": "^2.6.0", 14 14 "@tauri-apps/plugin-fs": "^2.4.5", 15 - "@tauri-apps/plugin-opener": "^2" 15 + "@tauri-apps/plugin-opener": "^2", 16 + "@tauri-apps/plugin-store": "^2.4.2" 16 17 }, 17 18 "devDependencies": { 18 19 "@sveltejs/adapter-static": "^3.0.6", ··· 1508 1509 "version": "2.5.3", 1509 1510 "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.5.3.tgz", 1510 1511 "integrity": "sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ==", 1512 + "license": "MIT OR Apache-2.0", 1513 + "dependencies": { 1514 + "@tauri-apps/api": "^2.8.0" 1515 + } 1516 + }, 1517 + "node_modules/@tauri-apps/plugin-store": { 1518 + "version": "2.4.2", 1519 + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-store/-/plugin-store-2.4.2.tgz", 1520 + "integrity": "sha512-0ClHS50Oq9HEvLPhNzTNFxbWVOqoAp3dRvtewQBeqfIQ0z5m3JRnOISIn2ZVPCrQC0MyGyhTS9DWhHjpigQE7A==", 1511 1521 "license": "MIT OR Apache-2.0", 1512 1522 "dependencies": { 1513 1523 "@tauri-apps/api": "^2.8.0"
+2 -1
mobile/package.json
··· 20 20 "@tauri-apps/api": "^2", 21 21 "@tauri-apps/plugin-dialog": "^2.6.0", 22 22 "@tauri-apps/plugin-fs": "^2.4.5", 23 - "@tauri-apps/plugin-opener": "^2" 23 + "@tauri-apps/plugin-opener": "^2", 24 + "@tauri-apps/plugin-store": "^2.4.2" 24 25 }, 25 26 "devDependencies": { 26 27 "@sveltejs/adapter-static": "^3.0.6",
+1
mobile/src-tauri/Cargo.toml
··· 28 28 tauri-plugin-dialog = "2" 29 29 simd-json = "0.16.0" 30 30 tauri-plugin-fs = "2" 31 + tauri-plugin-store = "2" 31 32 32 33 [target.'cfg(target_os = "android")'.dependencies] 33 34 android_logger = "0.15.1"
+2 -1
mobile/src-tauri/capabilities/default.json
··· 9 9 "core:default", 10 10 "opener:default", 11 11 "dialog:default", 12 - "fs:default" 12 + "fs:default", 13 + "store:default" 13 14 ] 14 15 }
+1
mobile/src-tauri/src/lib.rs
··· 97 97 let specta_builder = gen_types(); 98 98 99 99 tauri::Builder::default() 100 + .plugin(tauri_plugin_store::Builder::new().build()) 100 101 .plugin(tauri_plugin_fs::init()) 101 102 .plugin(tauri_plugin_dialog::init()) 102 103 .plugin(tauri_plugin_opener::init())
+16 -4
mobile/src/routes/+page.svelte
··· 4 4 import type { LibraryTauri } from '../../bindings' 5 5 import { readTextFile } from '@tauri-apps/plugin-fs' 6 6 import Library from './Library.svelte' 7 + import { Store } from '@tauri-apps/plugin-store' 7 8 8 9 9 - let library = $state<LibraryTauri | null>(null); 10 10 let loading = $state(false); 11 11 let error = $state(''); 12 12 13 - // ── Library loading ──────────────────────────────────────────────────────── 13 + const store = await Store.load('settings.json'); 14 + let library = $state<LibraryTauri | null>(null); 15 + 16 + const saved_library_path = await store.get('library_path') 17 + if (typeof saved_library_path === 'string') { 18 + load_library(saved_library_path) 19 + } 14 20 15 21 async function open_library() { 16 22 const path = await open({ 17 23 filters: [{ name: 'JSON', extensions: ['json'] }], 18 24 }); 19 - if (!path) return; 20 - 25 + if (path) { 26 + load_library(path) 27 + } 28 + } 29 + console.log(await store.entries()) 30 + async function load_library(path: string) { 21 31 loading = true; 22 32 library = null 23 33 error = ''; ··· 26 36 const result = await commands.loadLibrary(contents); 27 37 if (result.status === 'ok') { 28 38 library = result.data; 39 + store.set('library_path', path) 40 + store.save() 29 41 } else { 30 42 error = result.error; 31 43 }
+15 -10
mobile/svelte.config.js
··· 2 2 // so we use adapter-static with a fallback to index.html to put the site in SPA mode 3 3 // See: https://svelte.dev/docs/kit/single-page-apps 4 4 // See: https://v2.tauri.app/start/frontend/sveltekit/ for more info 5 - import adapter from "@sveltejs/adapter-static"; 6 - import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; 5 + import adapter from '@sveltejs/adapter-static' 6 + import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' 7 7 8 8 /** @type {import('@sveltejs/kit').Config} */ 9 9 const config = { 10 - preprocess: vitePreprocess(), 11 - kit: { 12 - adapter: adapter({ 13 - fallback: "index.html", 14 - }), 15 - }, 16 - }; 10 + preprocess: vitePreprocess(), 11 + kit: { 12 + adapter: adapter({ 13 + fallback: 'index.html', 14 + }), 15 + }, 16 + compilerOptions: { 17 + experimental: { 18 + async: true, 19 + }, 20 + }, 21 + } 17 22 18 - export default config; 23 + export default config