commit 91addf85db925dfac324d6bff8fed3e2c65857cd Author: Bytemalte Date: Sat Jan 31 16:33:07 2026 +0100 Setup for UI, without functions diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..48c3ca4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/dist/ +/target/ +/Cargo.lock diff --git a/.taurignore b/.taurignore new file mode 100644 index 0000000..1ebdc6d --- /dev/null +++ b/.taurignore @@ -0,0 +1,3 @@ +/src +/public +/Cargo.toml \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..24d7cc6 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..e6d9d21 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "emmet.includeLanguages": { + "rust": "html" + } +} diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f2306d2 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "metanos-ui" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[dependencies] +yew = { version = "0.21", features = ["csr"] } +yew-router = "0.18" +wasm-bindgen = "0.2" +wasm-bindgen-futures = "0.4" +web-sys = "0.3" +js-sys = "0.3" +serde = { version = "1", features = ["derive"] } +serde-wasm-bindgen = "0.6" +console_error_panic_hook = "0.1.7" + +[workspace] +members = ["src-tauri"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..4eee105 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Tauri + Yew + +This template should help get you started developing with Tauri and Yew. + +## 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). diff --git a/Trunk.toml b/Trunk.toml new file mode 100644 index 0000000..c9a88b7 --- /dev/null +++ b/Trunk.toml @@ -0,0 +1,9 @@ +[build] +target = "./index.html" + +[watch] +ignore = ["./src-tauri"] + +[serve] +port = 1420 +open = false diff --git a/index.html b/index.html new file mode 100644 index 0000000..317aa6d --- /dev/null +++ b/index.html @@ -0,0 +1,10 @@ + + + + + Tauri + Yew App + + + + + diff --git a/public/tauri.svg b/public/tauri.svg new file mode 100644 index 0000000..31b62c9 --- /dev/null +++ b/public/tauri.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/yew.png b/public/yew.png new file mode 100644 index 0000000..e2062e8 Binary files /dev/null and b/public/yew.png differ diff --git a/src-tauri/.gitignore b/src-tauri/.gitignore new file mode 100644 index 0000000..b21bd68 --- /dev/null +++ b/src-tauri/.gitignore @@ -0,0 +1,7 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ + +# Generated by Tauri +# will have schema files for capabilities auto-completion +/gen/schemas diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml new file mode 100644 index 0000000..73b55eb --- /dev/null +++ b/src-tauri/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "metanos" +version = "0.1.0" +description = "A Tauri App" +authors = ["you"] +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +# The `_lib` suffix may seem redundant but it is necessary +# to make the lib name unique and wouldn't conflict with the bin name. +# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519 +name = "metanos_lib" +crate-type = ["staticlib", "cdylib", "rlib"] + +[build-dependencies] +tauri-build = { version = "2", features = [] } + +[dependencies] +tauri = { version = "2", features = [] } +tauri-plugin-opener = "2" +serde = { version = "1", features = ["derive"] } +serde_json = "1" +easy-nostr = { path = "./easy-nostr" } diff --git a/src-tauri/build.rs b/src-tauri/build.rs new file mode 100644 index 0000000..d860e1e --- /dev/null +++ b/src-tauri/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json new file mode 100644 index 0000000..4cdbf49 --- /dev/null +++ b/src-tauri/capabilities/default.json @@ -0,0 +1,10 @@ +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "default", + "description": "Capability for the main window", + "windows": ["main"], + "permissions": [ + "core:default", + "opener:default" + ] +} diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png new file mode 100644 index 0000000..6be5e50 Binary files /dev/null and b/src-tauri/icons/128x128.png differ diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png new file mode 100644 index 0000000..e81bece Binary files /dev/null and b/src-tauri/icons/128x128@2x.png differ diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png new file mode 100644 index 0000000..a437dd5 Binary files /dev/null and b/src-tauri/icons/32x32.png differ diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png new file mode 100644 index 0000000..0ca4f27 Binary files /dev/null and b/src-tauri/icons/Square107x107Logo.png differ diff --git a/src-tauri/icons/Square142x142Logo.png b/src-tauri/icons/Square142x142Logo.png new file mode 100644 index 0000000..b81f820 Binary files /dev/null and b/src-tauri/icons/Square142x142Logo.png differ diff --git a/src-tauri/icons/Square150x150Logo.png b/src-tauri/icons/Square150x150Logo.png new file mode 100644 index 0000000..624c7bf Binary files /dev/null and b/src-tauri/icons/Square150x150Logo.png differ diff --git a/src-tauri/icons/Square284x284Logo.png b/src-tauri/icons/Square284x284Logo.png new file mode 100644 index 0000000..c021d2b Binary files /dev/null and b/src-tauri/icons/Square284x284Logo.png differ diff --git a/src-tauri/icons/Square30x30Logo.png b/src-tauri/icons/Square30x30Logo.png new file mode 100644 index 0000000..6219700 Binary files /dev/null and b/src-tauri/icons/Square30x30Logo.png differ diff --git a/src-tauri/icons/Square310x310Logo.png b/src-tauri/icons/Square310x310Logo.png new file mode 100644 index 0000000..f9bc048 Binary files /dev/null and b/src-tauri/icons/Square310x310Logo.png differ diff --git a/src-tauri/icons/Square44x44Logo.png b/src-tauri/icons/Square44x44Logo.png new file mode 100644 index 0000000..d5fbfb2 Binary files /dev/null and b/src-tauri/icons/Square44x44Logo.png differ diff --git a/src-tauri/icons/Square71x71Logo.png b/src-tauri/icons/Square71x71Logo.png new file mode 100644 index 0000000..63440d7 Binary files /dev/null and b/src-tauri/icons/Square71x71Logo.png differ diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png new file mode 100644 index 0000000..f3f705a Binary files /dev/null and b/src-tauri/icons/Square89x89Logo.png differ diff --git a/src-tauri/icons/StoreLogo.png b/src-tauri/icons/StoreLogo.png new file mode 100644 index 0000000..4556388 Binary files /dev/null and b/src-tauri/icons/StoreLogo.png differ diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns new file mode 100644 index 0000000..12a5bce Binary files /dev/null and b/src-tauri/icons/icon.icns differ diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico new file mode 100644 index 0000000..06c23c8 Binary files /dev/null and b/src-tauri/icons/icon.ico differ diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png new file mode 100644 index 0000000..e1cd261 Binary files /dev/null and b/src-tauri/icons/icon.png differ diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs new file mode 100644 index 0000000..4a277ef --- /dev/null +++ b/src-tauri/src/lib.rs @@ -0,0 +1,14 @@ +// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/ +#[tauri::command] +fn greet(name: &str) -> String { + format!("Hello, {}! You've been greeted from Rust!", name) +} + +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + tauri::Builder::default() + .plugin(tauri_plugin_opener::init()) + .invoke_handler(tauri::generate_handler![greet]) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs new file mode 100644 index 0000000..8441fd9 --- /dev/null +++ b/src-tauri/src/main.rs @@ -0,0 +1,6 @@ +// Prevents additional console window on Windows in release, DO NOT REMOVE!! +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +fn main() { + metanos_lib::run() +} diff --git a/src-tauri/src/metadata.rs b/src-tauri/src/metadata.rs new file mode 100644 index 0000000..e69de29 diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json new file mode 100644 index 0000000..b5eeed1 --- /dev/null +++ b/src-tauri/tauri.conf.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://schema.tauri.app/config/2", + "productName": "metanos", + "version": "0.1.0", + "identifier": "metanos.malxte.de", + "build": { + "beforeDevCommand": "trunk serve", + "devUrl": "http://localhost:1420", + "beforeBuildCommand": "trunk build", + "frontendDist": "../dist" + }, + "app": { + "withGlobalTauri": true, + "windows": [ + { + "title": "metanos", + "width": 800, + "height": 600 + } + ], + "security": { + "csp": null + } + }, + "bundle": { + "active": true, + "targets": "all", + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ] + } +} diff --git a/src/app.rs b/src/app.rs new file mode 100644 index 0000000..0613ede --- /dev/null +++ b/src/app.rs @@ -0,0 +1,35 @@ +use crate::navbar::Navbar; +use crate::pages::{profile::Profile, settings::Settings}; +use yew::prelude::*; +use yew_router::prelude::*; + +#[derive(Clone, Routable, PartialEq)] +pub enum Route { + #[at("/")] + Profile, + #[at("/settings")] + Settings, + #[not_found] + #[at("/404")] + NotFound, +} + +fn switch(routes: Route) -> Html { + match routes { + Route::Settings => html! { }, + Route::Profile => html! { }, + Route::NotFound => html! {

{ "404 - Not Found" }

}, + } +} + +#[function_component(App)] +pub fn app() -> Html { + html! { + +
+ render={switch} /> +
+ +
+ } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..6a921bb --- /dev/null +++ b/src/main.rs @@ -0,0 +1,10 @@ +mod app; +mod navbar; +mod pages; + +use app::App; + +fn main() { + console_error_panic_hook::set_once(); + yew::Renderer::::new().render(); +} diff --git a/src/navbar/mod.rs b/src/navbar/mod.rs new file mode 100644 index 0000000..d5c0b44 --- /dev/null +++ b/src/navbar/mod.rs @@ -0,0 +1,2 @@ +pub mod navbar; +pub use navbar::Navbar; diff --git a/src/navbar/navbar.rs b/src/navbar/navbar.rs new file mode 100644 index 0000000..0114ee5 --- /dev/null +++ b/src/navbar/navbar.rs @@ -0,0 +1,26 @@ +use crate::app::Route; +use yew::prelude::*; +use yew_router::prelude::*; + +#[function_component(Navbar)] +pub fn navbar() -> Html { + let route = use_route::().unwrap_or(Route::Profile); + + html! { + + } +} diff --git a/src/pages/mod.rs b/src/pages/mod.rs new file mode 100644 index 0000000..6138539 --- /dev/null +++ b/src/pages/mod.rs @@ -0,0 +1,2 @@ +pub mod profile; +pub mod settings; diff --git a/src/pages/profile.rs b/src/pages/profile.rs new file mode 100644 index 0000000..1f1f432 --- /dev/null +++ b/src/pages/profile.rs @@ -0,0 +1,10 @@ +use yew::prelude::*; + +#[function_component(Profile)] +pub fn profile() -> Html { + html! { +
+

{"Profile"}

+
+ } +} diff --git a/src/pages/settings.rs b/src/pages/settings.rs new file mode 100644 index 0000000..3f3d31f --- /dev/null +++ b/src/pages/settings.rs @@ -0,0 +1,10 @@ +use yew::prelude::*; + +#[function_component(Settings)] +pub fn settings() -> Html { + html! { +
+

{"Settings"}

+
+ } +} diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..13f4649 --- /dev/null +++ b/styles.css @@ -0,0 +1,134 @@ +/* --- Root Variables & Reset --- */ +:root { + --bg-color: #0f0f13; + --card-bg: rgba(255, 255, 255, 0.03); + --card-border: rgba(255, 255, 255, 0.08); + --text-primary: #e2e2e7; + --text-secondary: #a0a0b0; + --accent-color: #4a90e2; + --nav-bg: rgba(30, 30, 46, 0.95); + /* Fallback for blur */ + --danger: #ef4444; +} + +* { + box-sizing: border-box; + -webkit-tap-highlight-color: transparent; + /* UX-Finishing: No blue flash */ +} + +/* --- Global & Layout --- */ +body { + background-color: var(--bg-color); + color: var(--text-primary); + font-family: + "Inter", + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + sans-serif; + margin: 0; + line-height: 1.5; + display: flex; + justify-content: center; + min-height: 100vh; + overflow-x: hidden; + /* Performance: Prevent horizontal scroll */ + -webkit-tap-highlight-color: transparent; + + /* Fix: Blurry text */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; +} + +/* --- Navigation Dock --- */ +.navbar-dock { + position: fixed; + /* Safe Areas: Bottom inset */ + bottom: calc(20px + env(safe-area-inset-bottom)); + left: 50%; + transform: translateX(-50%); + background-color: var(--nav-bg); + padding: 12px 24px; + border-radius: 50px; + border: 1px solid rgba(255, 255, 255, 0.1); + display: flex; + gap: 20px; + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); + z-index: 1000; + width: max-content; + max-width: 90%; + + /* Fix: Blurry text in transformed elements */ + backface-visibility: hidden; +} + +@supports (backdrop-filter: blur(12px)) or (-webkit-backdrop-filter: blur(12px)) { + .navbar-dock { + background-color: rgba(30, 30, 46, 0.85); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + } +} + +.nav-link { + color: var(--text-secondary); + text-decoration: none; + font-weight: 600; + font-size: 0.9rem; + transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); + /* Touch-Ergonomie: Min 44px effective height */ + padding: 10px 12px; + user-select: none; + /* UX-Finishing */ + display: flex; + align-items: center; + justify-content: center; + min-height: 44px; + position: relative; +} + +.nav-link:hover { + color: #ffffff; + transform: translateY(-3px); +} + +.nav-link.active { + color: var(--accent-color); +} + +/* --- Pages (Profile & Settings) --- */ +.profile-container, +.settings-container { + width: 100%; + max-width: 800px; + padding: 40px 24px 120px 24px; /* Bottom padding to clear navbar */ + display: flex; + flex-direction: column; + align-items: flex-start; + animation: fadeIn 0.4s ease-out; +} + +h1 { + font-size: 2rem; + font-weight: 700; + margin-bottom: 24px; + background: linear-gradient(135deg, #fff 0%, #a5a5a5 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +/* Animation */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +}