diff --git a/Cargo.toml b/Cargo.toml index 4e4fb81..a10d43d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,9 @@ gloo-timers = "0.3.0" # Umgestellt auf rustls, um OpenSSL-Fehler beim Cross-Compiling zu vermeiden reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } pulldown-cmark = "0.13.0" +rand = "0.9.2" +getrandom = { version = "0.3", features = ["wasm_js"] } +ron = "0.8" [workspace] members = ["src-tauri"] diff --git a/assets/data/greetings.ron b/assets/data/greetings.ron new file mode 100644 index 0000000..c75783c --- /dev/null +++ b/assets/data/greetings.ron @@ -0,0 +1,399 @@ +[ + "Du bist wie ein Engel auf Erden <3", + "Du machst die Welt ein Stück heller! ✨", + "Kopf hoch, du rockst das! 🚀", + "Du bist wertvoll und geliebt. ❤️", + "Ein kleiner Roboter-Knuddel für dich! 🤖", + "Du bist einzigartig und wunderbar.", + "Lass dich nicht unterkriegen! 💪", + "Ich liebe dich! ❤️", + "Das ist eine tolle Sache!", + "Dein Lächeln ist ansteckend! 😊", + "Du hast das Zeug zu Großartigem.", + "Heute ist ein guter Tag, um glücklich zu sein.", + "Glaube an dich selbst, so wie ich an dich glaube.", + "Du bist mutiger, als du denkst. 🦁", + "Kleine Schritte führen auch zum Ziel.", + "Du bist ein Geschenk für die Welt. 🎁", + "Lass dein Licht leuchten! 🌟", + "Du bist stärker, als du dich fühlst.", + "Jeder Tag ist eine neue Chance. 🌅", + "Du machst einen Unterschied.", + "Sei stolz auf dich!", + "Du wirst heute etwas Wunderbares erleben.", + "Vertraue auf deine Fähigkeiten.", + "Du bist klug und fähig. 🧠", + "Alles wird gut, hab Geduld.", + "Dein Herz ist aus Gold. ✨", + "Du bist wichtiger, als du glaubst.", + "Bleib genau so, wie du bist!", + "Du hast heute schon jemanden zum Lächeln gebracht.", + "Deine Träume sind wertvoll.", + "Du verdienst nur das Beste.", + "Ein Tag ohne Lächeln ist ein verlorener Tag.", + "Du bist ein echter Sonnenschein. ☀️", + "Nimm dir Zeit, um glücklich zu sein.", + "Du bist die Hauptrolle in deinem eigenen Abenteuer.", + "Dein Potenzial ist grenzenlos.", + "Lass die Sorgen von gestern hinter dir.", + "Du bist voller Energie und Tatendrang.", + "Dein Beitrag zählt. 🏆", + "Atme tief durch, du schaffst das. 🌬️", + "Schön, dass es dich gibt!", + "Du bist ein Magnet für gute Dinge.", + "Sei mutig und freundlich.", + "Du hast eine wunderbare Ausstrahlung.", + "Dein Weg ist das Ziel. 🛤️", + "Du bist Inspiration für andere.", + "Jeder Moment mit dir ist kostbar.", + "Du bist ein Problemlöser. 🧩", + "Deine Kreativität kennt keine Grenzen.", + "Sei du selbst, alle anderen gibt es schon. 🌈", + "Du hast die Kraft, Dinge zu verändern.", + "Ein kleines Lächeln bewirkt Wunder.", + "Du bist auf dem richtigen Weg.", + "Hab Vertrauen in die Zukunft.", + "Du bist ein Meisterwerk im Werden. 🎨", + "Deine Anwesenheit ist beruhigend. 🌊", + "Du bist voller Liebe.", + "Alles, was du brauchst, ist bereits in dir.", + "Dein Mut inspiriert mich.", + "Du bist ein wahrer Freund. 🤝", + "Schätze die kleinen Dinge im Leben.", + "Du bist so viel mehr als deine Fehler.", + "Dein Erfolg ist sicher.", + "Du bist wunderschön, von innen und außen.", + "Lass dich vom Wind der Begeisterung tragen.", + "Du bist die Ruhe im Sturm.", + "Deine Ideen sind brillant. 💡", + "Gönn dir heute etwas Gutes. ☕", + "Du bist der Schöpfer deines Glücks.", + "Wunder geschehen jeden Tag. ✨", + "Du hast eine tolle Energie!", + "Du bist unersetzbar. 💎", + "Sei geduldig mit dir selbst.", + "Dein Optimismus ist bewundernswert.", + "Du bist ein Champion! 🥇", + "Hör auf dein Herz. ❤️", + "Du bist geliebter, als du ahnst.", + "Deine Stimme hat Gewicht.", + "Du bist ein Lichtblick im Alltag.", + "Bleib neugierig! 🔍", + "Du hast das Herz am rechten Fleck.", + "Dein Einsatz wird belohnt.", + "Du bist bereit für neue Abenteuer.", + "Lass dich von deinen Träumen leiten.", + "Du bist ein echtes Original.", + "Deine Ausdauer ist beeindruckend.", + "Du machst unmögliche Dinge möglich.", + "Sei die Veränderung, die du dir wünscht.", + "Du bist ein Segen für deine Mitmenschen.", + "Glaube an Wunder, sie passieren.", + "Du bist der Kapitän deines Schiffes. ⚓", + "Dein Lächeln macht den Unterschied.", + "Du hast eine großartige Zukunft vor dir.", + "Du bist klüger als du denkst.", + "Lass deine Freude die Welt anstecken.", + "Du bist sicher und geborgen. 🏠", + "Dein Mut ist deine Superkraft. ⚡", + "Du bist einfach fantastisch! 🔥", + "Ein neuer Morgen, ein neues Glück.", + "Du bist perfekt in deiner Unvollkommenheit.", + "Du bist das Herz unserer Familie! ❤️", + "Heute ist ein wunderbarer Tag für ein Lächeln. 😊", + "Danke für deine unendliche Geduld.", + "Dein Lächeln ist ansteckend!", + "Du bist ein Geschenk für uns alle.", + "Ein Tag ohne dich ist wie ein Tag ohne Sonne. ☀️", + "Du bist mein Vorbild in so vielen Dingen.", + "Heute wartet eine kleine Überraschung auf dich! 🎁", + "Deine Umarmungen sind die besten der Welt. 🤗", + "Hab einen wundervollen Tag!", + "Deine Weisheit beeindruckt mich jeden Tag aufs Neue. 🧠", + "Du bist der Kleber, der uns alle zusammenhält. 🤝", + "Deine Stärke ist meine Inspiration.", + "Egal was passiert, bei dir fühle ich mich sicher. 🏠", + "Du hast die wunderbare Gabe, andere glücklich zu machen.", + "Ein kurzes Wort von dir reicht, um meinen Tag zu retten.", + "Danke, dass du immer an mich glaubst.", + "Du bist einzigartig und absolut unersetzlich.", + "Deine Lebensfreude ist eine echte Inspiration. 🌟", + "Ich schätze jeden Moment, den wir gemeinsam verbringen.", + "Du bist heute mein Lieblingsmensch! (Und morgen auch)", + "Deine Gelassenheit ist bewundernswert. 🌊", + "Danke für die Wurzeln und die Flügel, die du mir gegeben hast.", + "Deine positive Ausstrahlung ist einfach magisch. ✨", + "Ich bin so stolz darauf, dich zu kennen.", + "Deine Meinung bedeutet mir mehr als alles andere.", + "Du machst die Welt mit deiner Art zu einem besseren Ort.", + "Danke für all die kleinen Dinge, die du unauffällig tust.", + "Deine Begeisterung für das Leben ist ansteckend.", + "Du hast eine ganz besondere Art, die Welt zu sehen. 🌍", + "Dein Humor ist unschlagbar – danke für das Lachen!", + "Du bist mein persönlicher Superheld. 🦸", + "Danke, dass du immer ein offenes Ohr hast. 👂", + "Schön, dass wir diesen Weg gemeinsam gehen.", + "Deine Wärme erfüllt den ganzen Raum. 🕯️", + "Ich bewundere deinen Mut und deine Entschlossenheit.", + "Du bist die Definition von Liebe und Fürsorge.", + "Jeder Tag mit dir ist ein gewonnener Tag.", + "Danke für deine bedingungslose Unterstützung.", + "Du hast heute ein extra großes Dankeschön verdient! 🏆", + "Deine Art, Probleme zu lösen, ist einfach genial.", + "Du bist der beste Ratgeber, den ich kenne.", + "Danke für die unzähligen schönen Erinnerungen.", + "Du bist heute ein echter Lichtblick. ✨", + "Deine Ehrlichkeit ist eine deiner größten Stärken.", + "Ich genieße unsere Gespräche mehr als du denkst.", + "Du bist ein wahrer Herzensmensch. ❤️", + "Danke, dass du mich so akzeptierst, wie ich bin.", + "Deine Zuversicht gibt mir immer wieder Kraft.", + "Du bist mein Fels in der Brandung. 🌊", + "Ich liebe deine Art, Geschichten zu erzählen. 📚", + "Du hast einen ganz besonderen Platz in meinem Herzen.", + "Heute ist ein Tag, um dich einfach mal zu feiern! 🎉", + "Danke für deine endlose Energie. ⚡", + "Du bist die Ruhe in jedem Sturm.", + "Deine Kreativität hört niemals auf, mich zu überraschen.", + "Danke, dass du unser Zuhause so besonders machst. 🏡", + "Du bist viel klüger und stärker, als du selbst glaubst.", + "Deine Anwesenheit ist das schönste Geschenk.", + "Ich schätze deine Aufrichtigkeit sehr.", + "Du bist eine wunderbare Seele. ✨", + "Danke für all die Opfer, die du gebracht hast.", + "Deine Freundlichkeit kennt keine Grenzen.", + "Du bist heute mein Vorbild des Tages!", + "Dein Kaffee/Tee schmeckt einfach am besten, weil er von dir ist. ☕", + "Ich bin so froh, dich in meinem Leben zu haben.", + "Du hast eine unglaubliche Gabe zuzuhören.", + "Dein Optimismus ist ein echtes Geschenk für uns alle.", + "Danke, dass du mir immer den Rücken stärkst.", + "Du bist heute der Grund für mein Lächeln. 😊", + "Deine Bescheidenheit macht dich nur noch wertvoller.", + "Danke, dass du nie aufgegeben hast, an mich zu glauben.", + "Du hast heute einen wundervollen Tag verdient.", + "Deine Hilfsbereitschaft ist außergewöhnlich.", + "Ich bewundere, wie du dein Leben meisterst.", + "Du bist ein echter Schatz. 💎", + "Danke für deine Zeit – das Wertvollste, was man schenken kann.", + "Deine Anwesenheit allein macht alles besser.", + "Du hast eine tolle Ausstrahlung, heute ganz besonders!", + "Ich danke dir für jeden gemeinsamen Lacher. 😂", + "Du bist der Beweis, dass es Engel auf Erden gibt. 👼", + "Deine Gelassenheit ist meine größte Inspiration.", + "Danke, dass du immer für mich da bist, egal was kommt.", + "Du bist heute einfach unschlagbar! 🔥", + "Ich liebe deine kleinen Macken, sie machen dich perfekt.", + "Du hast eine Stimme, die mich sofort beruhigt.", + "Danke für die Geborgenheit, die du ausstrahlst.", + "Du bist heute die beste Version von dir selbst.", + "Deine Leidenschaft für die Dinge, die du liebst, ist toll.", + "Ich bin dankbar für jeden Ratschlag, den du mir gibst.", + "Du bist ein wunderbarer Mensch, vergiss das nie! ✨", + "Deine Großzügigkeit ist beispiellos.", + "Danke, dass du mir beigebracht hast, was wirklich zählt.", + "Du bist mein persönlicher Ruhepol. 🧘", + "Deine Spontaneität macht das Leben so viel schöner. 🎈", + "Ich schätze deine Meinung über alles.", + "Du hast heute ein riesiges Kompliment verdient! ✨", + "Danke, dass du mich immer wieder zum Lachen bringst.", + "Du bist die Seele unseres Teams.", + "Ich bewundere deinen Fleiß und deine Ausdauer.", + "Du bist heute mein Lichtblick am Horizont.", + "Deine Liebe ist das Fundament meines Lebens.", + "Danke für deine unermüdliche Kraft.", + "Du bist heute einfach fantastisch – genau so wie du bist!", + "Dein Rat ist wie ein Kompass für mich. 🧭", + "Danke für die kleinen Momente des Glücks, die du schenkst.", + "Du bist ein echter Gewinn für jeden, der dich kennt.", + "Deine Art, Dinge anzupacken, ist beeindruckend.", + "Ich schätze deine Loyalität mehr als Worte sagen können.", + "Du bist heute mein persönlicher Sonnenschein! ☀️", + "Danke für die Geduld, die du immer wieder aufbringst.", + "Deine Herzlichkeit ist einfach unbeschreiblich.", + "Du bist eine Inspiration für alle um dich herum.", + "Ich liebe es, wie du die Welt ein bisschen bunter machst. 🎨", + "Danke, dass du mir immer zeigst, was Zusammenhalt bedeutet.", + "Du hast heute alles Glück der Welt verdient. 🍀", + "Deine Worte haben eine heilende Wirkung.", + "Ich bin stolz auf alles, was du erreicht hast.", + "Du bist heute mein absoluter Favorit! ⭐", + "Danke für deine Offenheit und dein Vertrauen.", + "Deine bloße Gegenwart reicht aus, um mich glücklich zu machen.", + "Du hast heute ein strahlendes Lächeln verdient.", + "Ich bewundere deine Disziplin und deinen Charakter.", + "Du bist ein wahrer Segen für mich.", + "Danke, dass du mein Leben so bereichert hast.", + "Deine Tipps sind einfach Gold wert. ✨", + "Du bist heute der Mittelpunkt meiner guten Gedanken.", + "Ich schätze deinen Mut, immer du selbst zu sein.", + "Danke für die Wärme, die du in mein Leben bringst. 🕯️", + "Du bist ein Unikat – im allerbesten Sinne!", + "Deine Unterstützung ist mein größter Rückhalt.", + "Ich freue mich über jeden Tag, an dem wir uns sehen.", + "Du bist heute mein persönlicher Held des Tages! 🦸", + "Danke für die unzähligen Male, die du mir geholfen hast.", + "Deine Sicht auf die Dinge öffnet mir oft die Augen. 👀", + "Du hast heute einen Tag voller Freude verdient.", + "Ich liebe deine Energie und deinen Tatendrang.", + "Danke, dass du mein Leben so viel einfacher machst.", + "Du bist einfach wunderbar – heute und jeden Tag! ❤️", + "Du bist das Licht, das meinen Weg erhellt. 💡", + "Danke für dein Vertrauen in meine Träume.", + "Deine Anwesenheit ist wie eine warme Decke für die Seele.", + "Du machst jeden Raum heller, wenn du ihn betrittst.", + "Dein Mut inspiriert mich, selbst mutiger zu sein.", + "Deine Geschichten sind die besten der Welt. 📚", + "Du hast ein unglaubliches Gespür für das Wesentliche.", + "Ich bewundere, wie du auch in schwierigen Zeiten positiv bleibst.", + "Danke, dass du meine Welt sicherer machst.", + "Deine Gelassenheit ist mein Anker. ⚓", + "Ich schätze es so sehr, wie du dich um uns kümmerst.", + "Du hast eine Gabe, Menschen zusammenzubringen.", + "Danke für dein unendliches Verständnis.", + "Deine Fröhlichkeit ist ansteckend – danke dafür!", + "Ich bin so dankbar für unsere gemeinsame Zeit.", + "Du bist ein wunderbarer Teil meines Lebens.", + "Danke, dass du mich immer wieder zum Nachdenken anregst. 🧠", + "Deine Ehrlichkeit ist erfrischend und wichtig.", + "Du hast heute das Beste verdient, was der Tag zu bieten hat.", + "Ich schätze deinen Fleiß und deine Hingabe.", + "Du bist heute mein persönlicher Glücksbringer! 🍀", + "Danke für die Geborgenheit, die du uns allen schenkst.", + "Deine Art zu lachen ist mein Lieblingsgeräusch.", + "Ich bewundere deinen Blick für die kleinen Details.", + "Du bist ein echter Fels in meiner Brandung. 🌊", + "Danke, dass du mir immer wieder neue Perspektiven zeigst.", + "Deine Liebe ist das wertvollste Geschenk.", + "Du hast heute allen Grund, stolz auf dich zu sein.", + "Ich liebe es, wie du die Dinge beim Namen nennst.", + "Danke für deine Unermüdlichkeit.", + "Du bist heute mein ganz persönlicher Star! ⭐", + "Deine Herzlichkeit wärmt mehr als jeder Kamin.", + "Ich schätze deine Ruhe und Besonnenheit.", + "Du hast eine tolle Wirkung auf andere Menschen.", + "Danke, dass du immer das Beste in mir siehst.", + "Deine Kraft ist bewundernswert.", + "Ich danke dir für jeden Tag, an dem du mich unterstützt.", + "Deine Weisheit ist ein kostbarer Schatz. 💎", + "Du machst das Leben so viel lebenswerter.", + "Danke für dein offenes Herz.", + "Du bist heute mein persönliches Highlight.", + "Deine positive Energie ist ein echtes Kraftwerk. ⚡", + "Ich bewundere deine Beständigkeit.", + "Du bist einfach ein toller Mensch – danke dafür!", + "Deine Umarmungen sind wie Medizin. 🤗", + "Danke, dass du immer eine Lösung parat hast.", + "Du bist heute die Heldin / der Held des Alltags.", + "Dein Humor macht alles ein bisschen leichter. 😂", + "Ich schätze deine Zuverlässigkeit über alles.", + "Du hast heute einen Tag voller Lächeln verdient.", + "Danke, dass du mir zeigst, was wirklich wichtig ist.", + "Deine Intuition ist beeindruckend.", + "Du bist heute mein liebster Gedanke.", + "Ich bewundere, wie du dich für andere einsetzt.", + "Danke für deine ständige Begleitung auf meinem Weg.", + "Du bist einfach einzigartig! ✨", + "Deine Worte haben Gewicht und Bedeutung.", + "Ich danke dir für deine Liebe zum Detail.", + "Du bist heute mein persönlicher Motivator! 💪", + "Deine Sichtweise auf das Leben bereichert mich.", + "Danke für die Freiheit, ich selbst zu sein.", + "Du bist ein wunderbarer Zuhörer.", + "Dein Lächeln ist das schönste am ganzen Tag.", + "Ich schätze deine Offenheit sehr.", + "Du hast heute eine extra Portion Anerkennung verdient.", + "Danke für all die Jahre voller Liebe.", + "Du bist mein Ruhepol in einer hektischen Welt. 🧘", + "Deine Stärke gibt mir Mut.", + "Ich bewundere deine Authentizität.", + "Du bist heute mein absoluter Glückstreffer! 🎯", + "Danke, dass du mir immer wieder zeigst, wie man verzeiht.", + "Deine Art, das Leben zu meistern, ist vorbildlich.", + "Du bist einfach toll – vergiss das bitte nie!", + "Deine Liebe gibt mir Selbstvertrauen.", + "Danke für dein Verständnis, auch wenn es mal schwierig ist.", + "Du bist heute mein Licht im Dunkeln. 💡", + "Deine Begeisterungsfähigkeit ist so schön anzusehen.", + "Ich schätze deine Bodenständigkeit.", + "Du hast heute einen fantastischen Tag verdient.", + "Danke für deinen Schutz und deine Fürsorge.", + "Deine Ideen inspirieren mich immer wieder.", + "Du bist heute meine Nummer Eins! 🥇", + "Dein Charakter ist deine größte Schönheit.", + "Ich bewundere deinen Tatendrang.", + "Danke für die Sicherheit, die du mir vermittelst.", + "Du bist ein wunderbares Beispiel für Güte.", + "Deine Art zu trösten ist unnachahmlich.", + "Ich danke dir für deine unendliche Liebe.", + "Du bist heute mein persönliches Kraftpaket! 💪", + "Deine Herzlichkeit macht jeden Tag besser.", + "Ich schätze deine unvoreingenommene Art.", + "Du hast heute einen Moment der Ruhe verdient.", + "Danke, dass du mich immer wieder forderst und förderst.", + "Deine Präsenz ist ein echtes Geschenk. 🎁", + "Du bist heute mein persönlicher Schutzengel. 👼", + "Dein Humor rettet mir oft den Tag.", + "Ich bewundere deinen Gerechtigkeitssinn.", + "Danke für deine unermüdliche Geduld.", + "Du bist einfach fantastisch – bleib genau so!", + "Deine Tipps haben mich schon oft gerettet. ✨", + "Ich schätze deine Aufrichtigkeit in allen Dingen.", + "Du hast heute alles Gute dieser Welt verdient.", + "Deine Liebe ist mein sicherer Hafen. ⚓", + "Du bist heute meine größte Inspiration.", + "Dein Lächeln vertreibt jede Sorge. 😊", + "Ich bewundere dein Durchhaltevermögen.", + "Danke für dein Vertrauen in meine Fähigkeiten.", + "Du bist heute mein ganz persönlicher Herzensmensch.", + "Deine Ruhe ist ansteckend – danke dafür.", + "Ich schätze deine Hilfsbereitschaft sehr.", + "Du hast heute einen Tag voller positiver Überraschungen verdient.", + "Danke für das Fundament, auf dem ich stehen darf.", + "Deine Energie ist einfach bewundernswert.", + "Dein Charakter ist ein echtes Vorbild für mich.", + "Ich bewundere deine Disziplin.", + "Danke für deine Unterstützung bei jedem meiner Schritte.", + "Du bist ein wunderbarer Mensch durch und durch.", + "Deine Herzlichkeit ist das beste Parfüm.", + "Ich schätze deine Offenheit für neue Dinge. 🌈", + "Du hast heute allen Grund, glücklich zu sein.", + "Danke für die Wurzeln, die mich halten.", + "Deine Umarmung ist der beste Ort der Welt. 🤗", + "Du bist heute mein Lichtblick im Alltag.", + "Dein Optimismus ist meine tägliche Motivation. ☀️", + "Ich bewundere deinen Sinn für Ästhetik und Schönheit.", + "Danke für deine klugen Worte im richtigen Moment.", + "Du bist einfach großartig – heute ganz besonders!", + "Deine Art, anderen zu helfen, ist inspirierend.", + "Ich schätze deine Loyalität sehr.", + "Du hast heute ein riesiges Dankeschön verdient! 💐", + "Danke, dass du immer einen kühlen Kopf bewahrst.", + "Deine Leidenschaft ist dein schönstes Accessoire.", + "Du bist heute mein persönliches Glück! ✨", + "Dein Glaube an mich versetzt Berge. 🏔️", + "Ich bewundere deine Fähigkeit, Dinge zu verzeihen.", + "Danke für jeden gemeinsamen Moment des Schweigens.", + "Du bist ein Geschenk, das ich jeden Tag aufs Neue schätze. 🎁", + "Deine Art zu denken ist so erfrischend.", + "Ich schätze deine Besonnenheit sehr.", + "Du hast heute einen Tag voller Liebe verdient.", + "Danke für dein offenes Ohr und dein warmes Herz.", + "Deine Anwesenheit allein macht mich stolz.", + "Dein Lachen ist das beste Rezept gegen schlechte Laune. 😂", + "Ich bewundere deine Unabhängigkeit.", + "Danke für die vielen kleinen Aufmerksamkeiten.", + "Du bist einfach ein feiner Mensch – danke für alles!", + "Deine Stärke beeindruckt mich jedes Mal wieder.", + "Ich schätze deine Zuverlässigkeit in allen Lebenslagen.", + "Du hast heute einen Tag voller Freude verdient! 🎉", + "Danke für dein Durchhaltevermögen und deine Kraft.", + "Deine Herzlichkeit macht die Welt ein Stück besser.", + "Du bist heute mein ganz persönlicher Star! 🌟", + "Dein Rat ist mir unendlich wichtig.", + "Ich bewundere deinen Mut, neue Wege zu gehen.", + "Danke für die Zeit, die du mir schenkst.", + "Du wunderbarer Mensch, genau so wie du bist! ❤️", + "Heute ist ein Tag, um dir einfach mal 'Ich hab dich lieb' zu sagen.", + "Danke für deine Liebe, die mich jeden Tag begleitet." +] diff --git a/assets/greet.css b/assets/greet.css new file mode 100644 index 0000000..e69de29 diff --git a/assets/home.css b/assets/home.css new file mode 100644 index 0000000..e69de29 diff --git a/assets/navbar.css b/assets/navbar.css new file mode 100644 index 0000000..e69de29 diff --git a/assets/news.css b/assets/news.css new file mode 100644 index 0000000..e69de29 diff --git a/src-tauri/src/chat.rs b/src-tauri/src/chat.rs deleted file mode 100644 index d7b115e..0000000 --- a/src-tauri/src/chat.rs +++ /dev/null @@ -1,95 +0,0 @@ -use easy_nostr::EasyNostr; -use serde::Serialize; -use std::sync::Arc; -use tauri::State; -use tokio::sync::Mutex; -use tokio::time::{sleep, Duration}; - -pub struct NostrState(pub Mutex>>); - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -pub struct ChatMessage { - pub id: String, - pub content: String, - pub is_incoming: bool, - pub created_at: u64, -} - -async fn get_client(state: &State<'_, NostrState>) -> Result, String> { - let mut guard = state.0.lock().await; - if guard.is_none() { - println!("[BACKEND] Initializing EasyNostr..."); - // Use your private key - let easy = - EasyNostr::new("nsec1rz87pcjnhcl9yfkyq2pn3mlptluvxdgdgw6fyhhg3zmzw2zpwn0sm2q82f") - .await - .map_err(|e| e.to_string())?; - - easy.add_relays(vec![ - "wss://relay.damus.io", - "wss://nos.lol", - "wss://relay.snort.social", - "wss://relay.primal.net", - "wss://nostr.wine", - ]) - .await - .map_err(|e| e.to_string())?; - - *guard = Some(Arc::new(easy)); - - // Short sleep to allow initial connection - sleep(Duration::from_millis(1500)).await; - } - Ok(guard.as_ref().unwrap().clone()) -} - -#[tauri::command] -pub async fn get_nostr_messages( - receiver_npub: String, - state: State<'_, NostrState>, -) -> Result, String> { - let clean_npub = receiver_npub.trim().trim_matches('#').to_string(); - if clean_npub.is_empty() { - return Ok(vec![]); - } - - let client = get_client(&state).await?; - - // easy-nostr now handles the 10s timeout and heavy filtering internally - let messages = client - .get_private_messages(&clean_npub) - .await - .map_err(|e| e.to_string())?; - - // Map to frontend structure - let chat_msgs: Vec = messages - .into_iter() - .map(|m| ChatMessage { - id: m.id.to_string(), - content: m.content, - is_incoming: m.is_incoming, - created_at: m.created_at.as_secs(), // Convert Timestamp to u64 - }) - .collect(); - - // Sorting is already done in easy-nostr, but we ensure it here too - Ok(chat_msgs) -} - -#[tauri::command] -pub async fn send_nostr_message( - content: String, - receiver_npub: String, - state: State<'_, NostrState>, -) -> Result { - let clean_npub = receiver_npub.trim().trim_matches('#').to_string(); - let client = get_client(&state).await?; - - let event_id = client - .send_private_message(&clean_npub, &content) - .await - .map_err(|e| e.to_string())?; - - Ok(event_id.to_string()) -} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index e10ee1b..3882fe8 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1,21 +1,14 @@ -mod chat; mod home; mod news; -use tokio::sync::Mutex; - #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_opener::init()) // Registriert den Nostr-State - .manage(chat::NostrState(Mutex::new(None))) - // HINZUGEFÜGT: Registriert den News-State für den API-Key .manage(news::NewsState::default()) .invoke_handler(tauri::generate_handler![ home::fetch_nostr_posts, - chat::send_nostr_message, - chat::get_nostr_messages, news::save_openrouter_key, news::fetch_ai_news, ]) diff --git a/src/app.rs b/src/app.rs index 697ae40..ff894a0 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,5 +1,5 @@ use crate::navbar::Navbar; -use crate::pages::{chat::Chat, home::Home, news::News}; +use crate::pages::{greet::Greet, home::Home, news::News}; use yew::prelude::*; use yew_router::prelude::*; @@ -9,8 +9,8 @@ pub enum Route { Home, #[at("/news")] News, - #[at("/chat")] - Chat, + #[at("/greet")] + Greet, #[not_found] #[at("/404")] NotFound, @@ -20,7 +20,7 @@ fn switch(routes: Route) -> Html { match routes { Route::Home => html! { }, Route::News => html! { }, - Route::Chat => html! { }, + Route::Greet => html! { }, Route::NotFound => html! {

{ "404 - Not Found" }

}, } } diff --git a/src/navbar/navbar.rs b/src/navbar/navbar.rs index 5fd35e1..63fab00 100644 --- a/src/navbar/navbar.rs +++ b/src/navbar/navbar.rs @@ -23,10 +23,10 @@ pub fn navbar() -> Html { > - to={Route::Chat} - classes={classes!("nav-link", if route == Route::Chat { "active" } else { "" })} + to={Route::Greet} + classes={classes!("nav-link", if route == Route::Greet { "active" } else { "" })} > - { "Chat" } + { "Greet" } > } diff --git a/src/pages/chat.rs b/src/pages/chat.rs deleted file mode 100644 index 411c18d..0000000 --- a/src/pages/chat.rs +++ /dev/null @@ -1,190 +0,0 @@ -use gloo_timers::callback::Interval; -use js_sys::Date; -use serde::{Deserialize, Serialize}; -use wasm_bindgen::prelude::*; -use wasm_bindgen_futures::spawn_local; -use web_sys::HtmlInputElement; -use yew::prelude::*; - -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(js_namespace = ["window", "__TAURI__", "core"])] - async fn invoke(cmd: &str, args: JsValue) -> JsValue; -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)] -#[serde(rename_all = "camelCase")] -pub struct ChatMessage { - pub id: Option, // ID ist None für optimistische Nachrichten - pub content: String, - pub is_incoming: bool, - pub created_at: u64, -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -struct ChatArgs { - content: String, - receiver_npub: String, -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -struct GetArgs { - receiver_npub: String, -} - -#[function_component(Chat)] -pub fn chat() -> Html { - let messages = use_state(|| Vec::::new()); - let relay_connected = use_state(|| false); - let recipient_ref = use_node_ref(); - let input_ref = use_node_ref(); - let chat_bottom_ref = use_node_ref(); - - // --- Polling Logic mit Smart Merge --- - { - let messages = messages.clone(); - let relay_connected = relay_connected.clone(); - let recipient_ref = recipient_ref.clone(); - - use_effect(move || { - let interval = Interval::new(3000, move || { - let messages = messages.clone(); - let relay_connected = relay_connected.clone(); - - if let Some(recipient) = recipient_ref.cast::() { - let npub = recipient.value().trim().to_string(); - if npub.is_empty() { - return; - } - - spawn_local(async move { - let args = serde_wasm_bindgen::to_value(&GetArgs { - receiver_npub: npub, - }) - .unwrap(); - let fetched: JsValue = invoke("get_nostr_messages", args).await; - - if let Ok(relay_msgs) = - serde_wasm_bindgen::from_value::>(fetched) - { - if !relay_msgs.is_empty() { - relay_connected.set(true); - } - - let current_local_msgs = (*messages).clone(); - - // SMART MERGE LOGIC: - // 1. Take all messages from the relay. - // 2. Add local "optimistic" messages (id == None) that haven't appeared in relay_msgs yet. - let mut merged = relay_msgs.clone(); - - for local_msg in current_local_msgs.iter().filter(|m| m.id.is_none()) { - // Check if this message is now confirmed (by matching content) - let already_confirmed = - relay_msgs.iter().any(|rm| rm.content == local_msg.content); - if !already_confirmed { - merged.push(local_msg.clone()); - } - } - - merged.sort_by_key(|m| m.created_at); - - // Only update state if something actually changed to avoid flickering - if merged.len() != current_local_msgs.len() - || merged.last().map(|m| &m.id) - != current_local_msgs.last().map(|m| &m.id) - { - messages.set(merged); - } - } - }); - } - }); - move || drop(interval) - }); - } - - // --- Autoscroll --- - { - let chat_bottom_ref = chat_bottom_ref.clone(); - let messages_len = messages.len(); - use_effect_with(messages_len, move |_| { - if let Some(element) = chat_bottom_ref.cast::() { - element.scroll_into_view(); - } - || () - }); - } - - let on_send = { - let messages = messages.clone(); - let input_ref = input_ref.clone(); - let recipient_ref = recipient_ref.clone(); - Callback::from(move |e: SubmitEvent| { - e.prevent_default(); - let input = input_ref.cast::().unwrap(); - let recipient = recipient_ref.cast::().unwrap(); - - let content = input.value(); - let receiver_npub = recipient.value(); - - if !content.trim().is_empty() && !receiver_npub.trim().is_empty() { - // Optimistic UI Update: Nachricht sofort ohne ID anzeigen - let mut current = (*messages).clone(); - current.push(ChatMessage { - id: None, - content: content.clone(), - is_incoming: false, - created_at: (Date::now() / 1000.0) as u64, - }); - messages.set(current); - input.set_value(""); - - spawn_local(async move { - let args = serde_wasm_bindgen::to_value(&ChatArgs { - content, - receiver_npub, - }) - .unwrap(); - let _ = invoke("send_nostr_message", args).await; - }); - } - }) - }; - - html! { -
-
-

{"💬 Nostr Chat"}

-
- - {if *relay_connected { " Relays aktiv" } else { " Verbinde..." }} -
-
-
- -
-
- { for (*messages).iter().map(|msg| html! { -
-
- { if msg.is_incoming { "Empfangen" } else { "Du" } } - { if msg.id.is_none() { " (sendet...)" } else { "" } } -
-
{ &msg.content }
-
- }) } -
-
-
- - -
-
- } -} diff --git a/src/pages/greet.rs b/src/pages/greet.rs new file mode 100644 index 0000000..e0cf79a --- /dev/null +++ b/src/pages/greet.rs @@ -0,0 +1,38 @@ +use js_sys::Math; +use ron::de::from_str; +use yew::prelude::*; // Nutzt die Browser-API für Zufall + +#[function_component(Greet)] +pub fn greet() -> Html { + let message = use_state(|| "".to_string()); + + // Inkludiert die RON-Daten direkt in die .wasm Datei + let greetings_data = include_str!("../../assets/data/greetings.ron"); + + // Wir parsen die Daten einmalig beim Rendern der Komponente + let messages: Vec = from_str(greetings_data) + .unwrap_or_else(|_| vec!["Fehler beim Laden der Sprüche...".to_string()]); + + let onclick = { + let message = message.clone(); + let messages = messages.clone(); + Callback::from(move |_| { + if !messages.is_empty() { + // Sicherer Zufall via JavaScript Math API (funktioniert immer in WASM) + let idx = (Math::random() * messages.len() as f64).floor() as usize; + if let Some(new_msg) = messages.get(idx) { + message.set(new_msg.clone()); + } + } + }) + }; + + html! { +
+
{"🤖"}
+ if !(*message).is_empty() { +

{ (*message).clone() }

+ } +
+ } +} diff --git a/src/pages/mod.rs b/src/pages/mod.rs index 6d5e542..ddde721 100644 --- a/src/pages/mod.rs +++ b/src/pages/mod.rs @@ -1,3 +1,3 @@ -pub mod chat; +pub mod greet; pub mod home; pub mod news; diff --git a/styles.css b/styles.css index 536e7e1..b46f5c1 100644 --- a/styles.css +++ b/styles.css @@ -1,3 +1,7 @@ +@import url("assets/home.css"); +@import url("assets/news.css"); +@import url("assets/greet.css"); + /* --- Global & Layout --- */ body { background-color: #0f0f13; @@ -102,151 +106,6 @@ html { transform: translateY(-2px); } -/* --- Chat Layout (Neu & Verbessert) --- */ -.chat-wrapper { - display: flex; - flex-direction: column; - min-height: 70vh; -} - -.chat-list { - display: flex; - flex-direction: column; - gap: 12px; - margin-bottom: 180px; /* Platz für Input-Container */ - padding: 10px 0; -} - -.chat-item { - max-width: 85%; - padding: 12px 16px; - border-radius: 18px; - display: flex; - flex-direction: column; -} - -/* Ausrichtung der Bubbles */ -.chat-item.outgoing { - align-self: flex-end; - background: rgba(74, 144, 226, 0.2); - border: 1px solid rgba(74, 144, 226, 0.3); - border-bottom-right-radius: 4px; -} - -.chat-item.incoming { - align-self: flex-start; - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.1); - border-bottom-left-radius: 4px; -} - -.chat-meta { - font-size: 0.65rem; - color: #63636e; - text-transform: uppercase; - margin-bottom: 4px; - font-weight: 700; -} - -.chat-item.outgoing .chat-meta { - color: #4a90e2; - text-align: right; -} - -.chat-content { - font-size: 1rem; - color: #e2e2e7; - word-wrap: break-word; -} - -/* --- Floating Chat Input --- */ -.chat-input-container { - position: fixed; - bottom: 110px; - left: 50%; - transform: translateX(-50%); - width: 90%; - max-width: 500px; - display: flex; - gap: 10px; - background: rgba(20, 20, 25, 0.9); - backdrop-filter: blur(15px); - padding: 12px; - border-radius: 24px; - border: 1px solid rgba(255, 255, 255, 0.1); - z-index: 900; -} - -.chat-input { - flex: 1; - background: transparent; - border: none; - color: white; - padding: 0 10px; - outline: none; -} - -.chat-send-btn { - background: #4a90e2; - color: white; - border: none; - width: 40px; - height: 40px; - border-radius: 50%; - cursor: pointer; - font-weight: bold; -} - -/* --- Recipient UI --- */ -.recipient-box { - position: sticky; - top: 0; - background: #0f0f13; - z-index: 100; - padding-bottom: 10px; - border-bottom: 1px solid rgba(255, 255, 255, 0.05); -} - -.recipient-input { - background: rgba(255, 255, 255, 0.03); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 12px; - color: #4a90e2; - font-family: monospace; - font-size: 0.85rem; - width: 100%; - padding: 10px 15px; - outline: none; - box-sizing: border-box; -} - -.relay-status { - display: flex; - align-items: center; - gap: 8px; - background: rgba(255, 255, 255, 0.05); - padding: 4px 12px; - border-radius: 20px; - font-size: 0.7rem; -} - -.status-dot { - width: 8px; - height: 8px; - border-radius: 50%; - display: inline-block; -} - -.status-dot.online { - background-color: #4ade80; /* Grün */ - box-shadow: 0 0 8px #4ade80; -} - -.status-dot.offline { - background-color: #facc15; /* Gelb/Orange für "Connecting" */ - box-shadow: 0 0 8px #facc15; -} - /* --- Markdown Styling für KI News --- */ .markdown-body { font-size: 0.95rem; @@ -322,3 +181,54 @@ html { color: #8e8e93; font-style: italic; } + +/* Greet */ +.robot-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + cursor: pointer; + transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); + margin: 60px auto; + width: fit-content; +} + +.robot-container:hover { + transform: scale(1.05); +} + +.robot-icon { + font-size: 6rem; + filter: drop-shadow(0 0 20px rgba(74, 144, 226, 0.3)); + animation: float 3s ease-in-out infinite; +} + +.bubble { + margin-top: 25px; + padding: 20px 30px; + background: rgba(30, 30, 46, 0.7); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border-radius: 24px; + border: 1px solid rgba(255, 173, 210, 0.4); + color: #ffffff; + font-weight: 600; + font-size: 1.1rem; + text-align: center; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); + max-width: 320px; + line-height: 1.4; +} + +@keyframes float { + 0% { + transform: translateY(0px); + } + 50% { + transform: translateY(-10px); + } + 100% { + transform: translateY(0px); + } +}