chore(store): add AppSettings example (#573)
* basic example foundation * add examples to workspace * cleanup and load fix * fmt * reset lockfile --------- Co-authored-by: FabianLars <fabianlars@fabianlars.de>pull/998/head
@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
#dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"]
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
# Tauri + Vanilla TS
|
||||
|
||||
This template should help get you started developing with Tauri in vanilla HTML, CSS and Typescript.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
- [VS Code](https://code.visualstudio.com/) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
|
@ -0,0 +1,54 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="stylesheet" href="/src/styles.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Tauri App</title>
|
||||
<script type="module" src="/src/main.ts" defer></script>
|
||||
<style>
|
||||
.logo.vite:hover {
|
||||
filter: drop-shadow(0 0 2em #747bff);
|
||||
}
|
||||
|
||||
.logo.typescript:hover {
|
||||
filter: drop-shadow(0 0 2em #2d79c7);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Welcome to Tauri!</h1>
|
||||
|
||||
<div class="row">
|
||||
<a href="https://vitejs.dev" target="_blank">
|
||||
<img src="/src/assets/vite.svg" class="logo vite" alt="Vite logo" />
|
||||
</a>
|
||||
<a href="https://tauri.app" target="_blank">
|
||||
<img
|
||||
src="/src/assets/tauri.svg"
|
||||
class="logo tauri"
|
||||
alt="Tauri logo"
|
||||
/>
|
||||
</a>
|
||||
<a href="https://www.typescriptlang.org/docs" target="_blank">
|
||||
<img
|
||||
src="/src/assets/typescript.svg"
|
||||
class="logo typescript"
|
||||
alt="typescript logo"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p>Click on the Tauri logo to learn more about the framework</p>
|
||||
|
||||
<!-- <form class="row" id="greet-form">
|
||||
<input id="greet-input" placeholder="Enter a name..." />
|
||||
<button type="submit">Greet</button>
|
||||
</form> -->
|
||||
|
||||
<p id="greet-msg"></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,15 @@
|
||||
{
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"preview": "vite preview",
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "1.5.10",
|
||||
"vite": "^5.0.12",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
|
@ -0,0 +1,24 @@
|
||||
[package]
|
||||
name = "app_settings_manager"
|
||||
version = "0.0.0"
|
||||
description = "A Tauri App"
|
||||
authors = ["you"]
|
||||
license = ""
|
||||
repository = ""
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build.workspace = true
|
||||
|
||||
[dependencies]
|
||||
tauri = { workspace = true, features = ["shell-open"] }
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
tauri-plugin-store = { path = "../../../" }
|
||||
|
||||
[features]
|
||||
# this feature is used for production builds or when `devPath` points to the filesystem
|
||||
# DO NOT REMOVE!!
|
||||
custom-protocol = ["tauri/custom-protocol"]
|
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 974 B |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 903 B |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 14 KiB |
@ -0,0 +1 @@
|
||||
pub mod settings;
|
@ -0,0 +1,29 @@
|
||||
use tauri_plugin_store::Store;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AppSettings {
|
||||
pub launch_at_login: bool,
|
||||
pub theme: String,
|
||||
}
|
||||
|
||||
impl AppSettings {
|
||||
pub fn load_from_store<R: tauri::Runtime>(
|
||||
store: &Store<R>,
|
||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
let launch_at_login = store
|
||||
.get("appSettings.launchAtLogin")
|
||||
.and_then(|v| v.as_bool())
|
||||
.unwrap_or(false);
|
||||
|
||||
let theme = store
|
||||
.get("appSettings.theme")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string())
|
||||
.unwrap_or_else(|| "dark".to_string());
|
||||
|
||||
Ok(AppSettings {
|
||||
launch_at_login,
|
||||
theme,
|
||||
})
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
use tauri_plugin_store::StoreBuilder;
|
||||
|
||||
mod app;
|
||||
use app::settings::AppSettings;
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_store::Builder::default().build())
|
||||
.setup(|app| {
|
||||
// Init store and load it from disk
|
||||
let mut store = StoreBuilder::new(app.handle(), "settings.json".parse()?).build();
|
||||
|
||||
// If there are no saved settings yet, this will return an error so we ignore the return value.
|
||||
let _ = store.load();
|
||||
|
||||
let app_settings = AppSettings::load_from_store(&store);
|
||||
|
||||
match app_settings {
|
||||
Ok(app_settings) => {
|
||||
let theme = app_settings.theme;
|
||||
let launch_at_login = app_settings.launch_at_login;
|
||||
|
||||
println!("theme {}", theme);
|
||||
println!("launch_at_login {}", launch_at_login);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("Error loading settings: {}", err);
|
||||
// Handle the error case if needed
|
||||
Err(err) // Convert the error to a Box<dyn Error> and return Err(err) here
|
||||
}
|
||||
}
|
||||
})
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
{
|
||||
"build": {
|
||||
"beforeDevCommand": "pnpm dev",
|
||||
"beforeBuildCommand": "pnpm build",
|
||||
"devPath": "http://localhost:1420",
|
||||
"distDir": "../dist",
|
||||
"withGlobalTauri": true
|
||||
},
|
||||
"package": {
|
||||
"productName": "AppSettingsManager",
|
||||
"version": "0.0.0"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
"all": false,
|
||||
"shell": {
|
||||
"all": false,
|
||||
"open": true
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"identifier": "com.tauri.dev",
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
]
|
||||
},
|
||||
"security": {
|
||||
"csp": null
|
||||
},
|
||||
"windows": [
|
||||
{
|
||||
"fullscreen": false,
|
||||
"resizable": true,
|
||||
"title": "AppSettingsManager",
|
||||
"width": 800,
|
||||
"height": 600
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,5 @@
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
document.querySelector("#greet-form")?.addEventListener("submit", (e) => {
|
||||
e.preventDefault();
|
||||
});
|
||||
});
|
@ -0,0 +1,109 @@
|
||||
:root {
|
||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 400;
|
||||
|
||||
color: #0f0f0f;
|
||||
background-color: #f6f6f6;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 0;
|
||||
padding-top: 10vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: 0.75s;
|
||||
}
|
||||
|
||||
.logo.tauri:hover {
|
||||
filter: drop-shadow(0 0 2em #24c8db);
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
input,
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
color: #0f0f0f;
|
||||
background-color: #ffffff;
|
||||
transition: border-color 0.25s;
|
||||
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
border-color: #396cd8;
|
||||
}
|
||||
button:active {
|
||||
border-color: #396cd8;
|
||||
background-color: #e8e8e8;
|
||||
}
|
||||
|
||||
input,
|
||||
button {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#greet-input {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
color: #f6f6f6;
|
||||
background-color: #2f2f2f;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #24c8db;
|
||||
}
|
||||
|
||||
input,
|
||||
button {
|
||||
color: #ffffff;
|
||||
background-color: #0f0f0f98;
|
||||
}
|
||||
button:active {
|
||||
background-color: #0f0f0f69;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(async () => ({
|
||||
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
|
||||
//
|
||||
// 1. prevent vite from obscuring rust errors
|
||||
clearScreen: false,
|
||||
// 2. tauri expects a fixed port, fail if that port is not available
|
||||
server: {
|
||||
port: 1420,
|
||||
strictPort: true,
|
||||
},
|
||||
// 3. to make use of `TAURI_DEBUG` and other env variables
|
||||
// https://tauri.studio/v1/api/config#buildconfig.beforedevcommand
|
||||
envPrefix: ["VITE_", "TAURI_"],
|
||||
}));
|