New Greeting Tab + New File Structure
This commit is contained in:
@@ -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"]
|
||||
|
||||
399
assets/data/greetings.ron
Normal file
399
assets/data/greetings.ron
Normal file
@@ -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."
|
||||
]
|
||||
0
assets/greet.css
Normal file
0
assets/greet.css
Normal file
0
assets/home.css
Normal file
0
assets/home.css
Normal file
0
assets/navbar.css
Normal file
0
assets/navbar.css
Normal file
0
assets/news.css
Normal file
0
assets/news.css
Normal file
@@ -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<Option<Arc<EasyNostr>>>);
|
||||
|
||||
#[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<Arc<EasyNostr>, 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<Vec<ChatMessage>, 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<ChatMessage> = 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<String, String> {
|
||||
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())
|
||||
}
|
||||
@@ -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,
|
||||
])
|
||||
|
||||
@@ -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! { <Home /> },
|
||||
Route::News => html! { <News /> },
|
||||
Route::Chat => html! { <Chat /> },
|
||||
Route::Greet => html! { <Greet /> },
|
||||
Route::NotFound => html! { <h1 class="status-msg">{ "404 - Not Found" }</h1> },
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@ pub fn navbar() -> Html {
|
||||
</Link<Route>>
|
||||
|
||||
<Link<Route>
|
||||
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" }
|
||||
</Link<Route>>
|
||||
</nav>
|
||||
}
|
||||
|
||||
@@ -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<String>, // 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::<ChatMessage>::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::<HtmlInputElement>() {
|
||||
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::<Vec<ChatMessage>>(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::<web_sys::HtmlElement>() {
|
||||
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::<HtmlInputElement>().unwrap();
|
||||
let recipient = recipient_ref.cast::<HtmlInputElement>().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! {
|
||||
<div class="chat-wrapper">
|
||||
<header class="feed-header">
|
||||
<h1 class="feed-title">{"💬 Nostr Chat"}</h1>
|
||||
<div class="relay-status">
|
||||
<span class={if *relay_connected { "status-dot online" } else { "status-dot offline" }}></span>
|
||||
<small>{if *relay_connected { " Relays aktiv" } else { " Verbinde..." }}</small>
|
||||
</div>
|
||||
</header>
|
||||
<div class="recipient-box">
|
||||
<input ref={recipient_ref} type="text" placeholder="Empfänger npub..." class="recipient-input" />
|
||||
</div>
|
||||
<div class="chat-list">
|
||||
{ for (*messages).iter().map(|msg| html! {
|
||||
<div class={classes!(
|
||||
if msg.is_incoming { "chat-item incoming" } else { "chat-item outgoing" },
|
||||
if msg.id.is_none() { "pending" } else { "confirmed" } // Optional: CSS für "Sende..." Status
|
||||
)}>
|
||||
<div class="chat-meta">
|
||||
{ if msg.is_incoming { "Empfangen" } else { "Du" } }
|
||||
{ if msg.id.is_none() { " (sendet...)" } else { "" } }
|
||||
</div>
|
||||
<div class="chat-content">{ &msg.content }</div>
|
||||
</div>
|
||||
}) }
|
||||
<div ref={chat_bottom_ref}></div>
|
||||
</div>
|
||||
<form class="chat-input-container" onsubmit={on_send}>
|
||||
<input ref={input_ref} type="text" placeholder="Nachricht schreiben..." class="chat-input" autocomplete="off" />
|
||||
<button type="submit" class="chat-send-btn">{"↑"}</button>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
38
src/pages/greet.rs
Normal file
38
src/pages/greet.rs
Normal file
@@ -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<String> = 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! {
|
||||
<div class="robot-container" {onclick}>
|
||||
<div class="robot-icon">{"🤖"}</div>
|
||||
if !(*message).is_empty() {
|
||||
<p class="bubble">{ (*message).clone() }</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
pub mod chat;
|
||||
pub mod greet;
|
||||
pub mod home;
|
||||
pub mod news;
|
||||
|
||||
200
styles.css
200
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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user