From 0946465c5085060c5aaf14b9464431bdcbda6a66 Mon Sep 17 00:00:00 2001 From: Bytemalte Date: Thu, 22 Jan 2026 14:57:42 +0100 Subject: [PATCH] Android UI Fix --- src-tauri/.gitignore | 1 + src-tauri/gen/android/app/build.gradle.kts | 40 +- src-tauri/gen/android/build.gradle.kts | 9 +- .../main/java/malxte/de/kotlin/BuildTask.kt | 18 +- styles.css | 575 ++++++++---------- 5 files changed, 288 insertions(+), 355 deletions(-) diff --git a/src-tauri/.gitignore b/src-tauri/.gitignore index b21bd68..fff94a5 100644 --- a/src-tauri/.gitignore +++ b/src-tauri/.gitignore @@ -5,3 +5,4 @@ # Generated by Tauri # will have schema files for capabilities auto-completion /gen/schemas +/gen/android/ diff --git a/src-tauri/gen/android/app/build.gradle.kts b/src-tauri/gen/android/app/build.gradle.kts index 99418bb..b5cd7e2 100644 --- a/src-tauri/gen/android/app/build.gradle.kts +++ b/src-tauri/gen/android/app/build.gradle.kts @@ -14,23 +14,31 @@ val tauriProperties = Properties().apply { } android { - compileSdk = 36 + compileSdk = 35 // Empfohlen: 35 (Android 15), da 36 noch im Preview-Status sein könnte namespace = "malxte.de" + defaultConfig { manifestPlaceholders["usesCleartextTraffic"] = "false" applicationId = "malxte.de" - minSdk = 24 - targetSdk = 36 + + // WICHTIG: Korrektur für dein Gerät (vorher 21) + minSdk = 24 + + targetSdk = 35 versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt() versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0") + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } + buildTypes { getByName("debug") { manifestPlaceholders["usesCleartextTraffic"] = "true" isDebuggable = true isJniDebuggable = true isMinifyEnabled = false - packaging { jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so") + packaging { + jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so") jniLibs.keepDebugSymbols.add("*/armeabi-v7a/*.so") jniLibs.keepDebugSymbols.add("*/x86/*.so") jniLibs.keepDebugSymbols.add("*/x86_64/*.so") @@ -45,26 +53,36 @@ android { ) } } - kotlinOptions { - jvmTarget = "1.8" + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } + + kotlinOptions { + jvmTarget = "17" // Angepasst auf Java 17 passend zu Gradle 8.14 + } + buildFeatures { buildConfig = true } } rust { + // Pfad zu deinem src-tauri Verzeichnis (wo die Cargo.toml liegt) rootDirRel = "../../../" } dependencies { - implementation("androidx.webkit:webkit:1.14.0") - implementation("androidx.appcompat:appcompat:1.7.1") - implementation("androidx.activity:activity-ktx:1.10.1") + implementation("androidx.webkit:webkit:1.12.0") + implementation("androidx.appcompat:appcompat:1.7.0") + implementation("androidx.activity:activity-ktx:1.9.3") implementation("com.google.android.material:material:1.12.0") + testImplementation("junit:junit:4.13.2") - androidTestImplementation("androidx.test.ext:junit:1.1.4") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0") + androidTestImplementation("androidx.test.ext:junit:1.2.1") + androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1") } +// Dies bindet die Tauri-Logik für Android ein (generierte Files) apply(from = "tauri.build.gradle.kts") \ No newline at end of file diff --git a/src-tauri/gen/android/build.gradle.kts b/src-tauri/gen/android/build.gradle.kts index 607240b..02b9a1d 100644 --- a/src-tauri/gen/android/build.gradle.kts +++ b/src-tauri/gen/android/build.gradle.kts @@ -4,7 +4,9 @@ buildscript { mavenCentral() } dependencies { - classpath("com.android.tools.build:gradle:8.11.0") + // Hier wird das Android-Plugin definiert + classpath("com.android.tools.build:gradle:8.2.1") + // Hier wird das Kotlin-Plugin definiert classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.25") } } @@ -17,6 +19,5 @@ allprojects { } tasks.register("clean").configure { - delete("build") -} - + delete(layout.buildDirectory) +} \ No newline at end of file diff --git a/src-tauri/gen/android/buildSrc/src/main/java/malxte/de/kotlin/BuildTask.kt b/src-tauri/gen/android/buildSrc/src/main/java/malxte/de/kotlin/BuildTask.kt index a1b43c0..0983396 100644 --- a/src-tauri/gen/android/buildSrc/src/main/java/malxte/de/kotlin/BuildTask.kt +++ b/src-tauri/gen/android/buildSrc/src/main/java/malxte/de/kotlin/BuildTask.kt @@ -21,23 +21,7 @@ open class BuildTask : DefaultTask() { runTauriCli(executable) } catch (e: Exception) { if (Os.isFamily(Os.FAMILY_WINDOWS)) { - // Try different Windows-specific extensions - val fallbacks = listOf( - "$executable.exe", - "$executable.cmd", - "$executable.bat", - ) - - var lastException: Exception = e - for (fallback in fallbacks) { - try { - runTauriCli(fallback) - return - } catch (fallbackException: Exception) { - lastException = fallbackException - } - } - throw lastException + runTauriCli("$executable.cmd") } else { throw e; } diff --git a/styles.css b/styles.css index a4f7a40..79ca18a 100644 --- a/styles.css +++ b/styles.css @@ -2,53 +2,102 @@ @import url("assets/news.css"); @import url("assets/greet.css"); +/* --- 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: #0f0f13; - color: #e2e2e7; + 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; } html { scroll-behavior: smooth; + overflow-x: hidden; } .feed-container { width: 100%; max-width: 600px; - padding: 40px 20px 150px 20px; + /* Safe Areas: Top inset and mobile-friendly padding */ + padding: calc(20px + env(safe-area-inset-top)) 16px + calc(120px + env(safe-area-inset-bottom)) 16px; +} + +@media (min-width: 768px) { + .feed-container { + padding: 40px 20px 150px 20px; + } } /* --- Navigation Dock --- */ .navbar-dock { position: fixed; - bottom: 30px; + /* Safe Areas: Bottom inset */ + bottom: calc(20px + env(safe-area-inset-bottom)); left: 50%; transform: translateX(-50%); - background-color: rgba(30, 30, 46, 0.85); - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - padding: 15px 30px; + background-color: var(--nav-bg); + padding: 12px 24px; border-radius: 50px; border: 1px solid rgba(255, 255, 255, 0.1); display: flex; - gap: 30px; + gap: 20px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); z-index: 1000; + width: max-content; + max-width: 90%; +} + +@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: #a0a0b0; + 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; } .nav-link:hover { @@ -57,228 +106,22 @@ html { } .nav-link.active { - color: #4a90e2; -} - -/* --- Content & Cards --- */ -.feed-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 30px; -} - -.post-card { - background: rgba(255, 255, 255, 0.03); - border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 16px; - padding: 20px; - margin-bottom: 16px; -} - -.post-author { - color: #4a90e2; - font-weight: 700; - font-size: 0.85rem; -} - -.post-content { - white-space: pre-wrap; - word-wrap: break-word; - margin-top: 10px; -} - -/* --- Interaction Elements --- */ -.reload-btn-large { - cursor: pointer; - background: rgba(74, 144, 226, 0.1); - color: #4a90e2; - padding: 14px; - border-radius: 16px; - width: 100%; - font-weight: 600; - border: 1px solid rgba(74, 144, 226, 0.3); - transition: all 0.2s ease; -} - -.reload-btn-large:hover { - background: rgba(74, 144, 226, 0.2); - transform: translateY(-2px); -} - -/* --- Markdown Styling für KI News --- */ -.markdown-body { - font-size: 0.95rem; - line-height: 1.6; - color: #e2e2e7; -} - -/* Fettgedruckter Text in Blau-Weiß-Verlauf Optik */ -.markdown-body strong { - color: #ffffff; - font-weight: 700; -} - -/* Kursiv für Akzente */ -.markdown-body em { - color: #a0a0b0; - font-style: italic; -} - -/* Links im KI-Text */ -.markdown-body a { - color: #4a90e2; - text-decoration: none; - border-bottom: 1px solid rgba(74, 144, 226, 0.3); - transition: all 0.2s ease; -} - -.markdown-body a:hover { - color: #5294e2; - border-bottom-color: #5294e2; -} - -/* Listen-Design */ -.markdown-body ul, -.markdown-body ol { - padding-left: 20px; - margin: 10px 0; -} - -.markdown-body li { - margin-bottom: 6px; -} - -/* Code-Blöcke (falls die KI Code generiert) */ -.markdown-body code { - background: rgba(255, 255, 255, 0.05); - padding: 2px 6px; - border-radius: 6px; - font-family: "JetBrains Mono", monospace; - font-size: 0.85rem; - border: 1px solid rgba(255, 255, 255, 0.1); -} - -/* Überschriften innerhalb der Post-Card */ -.markdown-body h1, -.markdown-body h2, -.markdown-body h3 { - color: #4a90e2; - margin-top: 15px; - margin-bottom: 8px; - font-weight: 700; -} - -.markdown-body h3 { - font-size: 1.1rem; -} - -/* Zitate / Blockquotes */ -.markdown-body blockquote { - margin: 10px 0; - padding-left: 15px; - border-left: 3px solid #4a90e2; - 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); - } -} - -/* --- Mode Switcher (KI / RSS) --- */ -@import url("assets/home.css"); -@import url("assets/news.css"); -@import url("assets/greet.css"); - -/* --- Global & Layout --- */ -body { - background-color: #0f0f13; - color: #e2e2e7; - font-family: - "Inter", - -apple-system, - sans-serif; - margin: 0; - line-height: 1.5; - display: flex; - justify-content: center; -} - -html { - scroll-behavior: smooth; -} - -.feed-container { - width: 100%; - max-width: 600px; - padding: 40px 20px 150px 20px; + color: var(--accent-color); } /* --- Header & Navigation --- */ .feed-header { display: flex; justify-content: space-between; - align-items: center; - margin-bottom: 30px; -} - -.header-main { - display: flex; - flex-direction: column; - gap: 8px; + align-items: flex-start; + margin-bottom: 24px; + flex-wrap: wrap; + gap: 16px; } .header-main h1 { margin: 0; - font-size: 1.8rem; + font-size: 1.5rem; } .mode-toggle { @@ -286,7 +129,6 @@ html { background: rgba(255, 255, 255, 0.05); border-radius: 12px; padding: 3px; - width: fit-content; border: 1px solid rgba(255, 255, 255, 0.08); } @@ -294,198 +136,237 @@ html { border: none; background: transparent; color: #8e8e93; - padding: 4px 12px; + padding: 8px 16px; border-radius: 9px; cursor: pointer; - font-size: 0.75rem; + font-size: 0.8rem; font-weight: 700; - transition: all 0.2s ease; + user-select: none; + min-height: 36px; } .toggle-btn.active { - background: #4a90e2; + background: var(--accent-color); color: white; } -.header-actions { - display: flex; - gap: 10px; -} - .action-btn { background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 12px; - padding: 10px; + padding: 12px; cursor: pointer; font-size: 1.1rem; - transition: all 0.2s; + user-select: none; + min-width: 44px; + min-height: 44px; + display: flex; + align-items: center; + justify-content: center; } -.action-btn:hover { - background: rgba(255, 255, 255, 0.1); - transform: translateY(-2px); -} - -/* --- Config Panel & RSS Management --- */ +/* --- Config Panel --- */ .config-panel { background: rgba(30, 30, 46, 0.6); - backdrop-filter: blur(20px); border: 1px solid rgba(74, 144, 226, 0.3); border-radius: 20px; - padding: 25px; + padding: 20px; margin-bottom: 30px; box-shadow: 0 15px 35px rgba(0, 0, 0, 0.4); - animation: slideIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); + animation: slideIn 0.3s ease-out; } -.config-section { - margin-bottom: 20px; -} - -.config-section label { - display: block; - font-size: 0.7rem; - font-weight: 800; - color: #4a90e2; - margin-bottom: 8px; - letter-spacing: 0.05rem; +@supports (backdrop-filter: blur(20px)) { + .config-panel { + backdrop-filter: blur(20px); + } } .config-input { - width: 100%; - padding: 12px 16px; + flex: 1; + padding: 14px 16px; background: rgba(0, 0, 0, 0.3); border: 1px solid rgba(255, 255, 255, 0.1); color: white; border-radius: 12px; - box-sizing: border-box; + /* Input-Fix: Prevent Android Auto-Zoom */ + font-size: 16px; font-family: inherit; + transition: border-color 0.2s; +} + +.config-input:focus { + outline: none; + border-color: var(--accent-color); } .rss-input-row { display: flex; - gap: 8px; - margin-bottom: 12px; + gap: 10px; + margin-bottom: 16px; } .add-btn { - background: #4a90e2; + background: var(--accent-color); color: white; border: none; border-radius: 12px; - width: 45px; + width: 50px; + min-width: 50px; cursor: pointer; - font-weight: bold; - font-size: 1.2rem; + font-weight: 700; + font-size: 1.4rem; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275); +} + +.add-btn:active { + transform: scale(0.9); } -/* Scrollbereich für viele RSS Feeds */ .rss-list-scroll { - max-height: 150px; + max-height: 180px; overflow-y: auto; background: rgba(0, 0, 0, 0.2); border-radius: 12px; padding: 8px; border: 1px solid rgba(255, 255, 255, 0.05); + margin-bottom: 16px; } .rss-url-entry { display: flex; justify-content: space-between; align-items: center; - padding: 8px 12px; + padding: 10px 14px; background: rgba(255, 255, 255, 0.03); - border-radius: 8px; - margin-bottom: 4px; - font-size: 0.8rem; + border-radius: 10px; + margin-bottom: 6px; + font-size: 0.85rem; + border: 1px solid transparent; + transition: all 0.2s; +} + +.rss-url-entry:hover { + background: rgba(255, 255, 255, 0.05); + border-color: rgba(255, 255, 255, 0.1); } .url-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - margin-right: 10px; - color: #a0a0b0; + margin-right: 12px; + color: var(--text-secondary); } .delete-btn { - background: transparent; - border: none; - color: #ef4444; + background: rgba(239, 68, 68, 0.1); + border: 1px solid rgba(239, 68, 68, 0.2); + color: var(--danger); cursor: pointer; - padding: 4px; - font-weight: bold; + padding: 8px 12px; + border-radius: 8px; + font-weight: 700; + font-size: 0.8rem; + transition: all 0.2s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 44px; + min-height: 36px; +} + +.delete-btn:active { + transform: scale(0.95); +} + +.delete-btn:hover { + background: var(--danger); + color: white; } .save-master-btn { background: linear-gradient(135deg, #4a90e2, #357abd); color: white; border: none; - padding: 14px; + padding: 16px; border-radius: 12px; cursor: pointer; width: 100%; font-weight: 700; + font-size: 1rem; + user-select: none; + min-height: 48px; margin-top: 10px; - box-shadow: 0 4px 15px rgba(74, 144, 226, 0.3); } -/* --- Post Cards & Markdown --- */ +/* --- Post Cards --- */ .post-card { - background: rgba(255, 255, 255, 0.03); - border: 1px solid rgba(255, 255, 255, 0.08); + background: var(--card-bg); + border: 1px solid var(--card-border); border-radius: 18px; - padding: 22px; - margin-bottom: 18px; - transition: transform 0.2s ease; -} - -.post-card:hover { - background: rgba(255, 255, 255, 0.05); -} - -.post-header { - display: flex; - justify-content: space-between; - font-size: 0.75rem; - margin-bottom: 12px; + padding: 16px; + margin-bottom: 16px; + word-wrap: break-word; } .post-author { - color: #4a90e2; + color: var(--accent-color); font-weight: 800; + font-size: 0.85rem; } -.post-date { - color: #636366; +/* --- Greet Page --- */ +.robot-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + cursor: pointer; + margin: 40px auto; + width: 100%; + user-select: none; } -.markdown-body h3 { - margin: 0 0 10px 0; +.robot-icon { + font-size: 5rem; + filter: drop-shadow(0 0 20px rgba(74, 144, 226, 0.3)); + animation: float 3s ease-in-out infinite; +} + +.bubble { + margin-top: 20px; + padding: 16px 24px; + background: rgba(30, 30, 46, 0.8); + border-radius: 20px; + border: 1px solid rgba(255, 173, 210, 0.3); color: #ffffff; - font-size: 1.15rem; + font-weight: 600; + font-size: 1rem; + text-align: center; + max-width: 90%; } -/* --- Status Messages --- */ -.loading-spinner, -.status-msg { - text-align: center; - padding: 40px; - color: #8e8e93; - font-style: italic; -} - -.error-box { - background: rgba(239, 68, 68, 0.1); - border: 1px solid rgba(239, 68, 68, 0.3); - color: #ef4444; - padding: 15px; - border-radius: 12px; - text-align: center; +@supports (backdrop-filter: blur(12px)) { + .bubble { + backdrop-filter: blur(12px); + } } /* --- Animations --- */ +@keyframes float { + 0%, + 100% { + transform: translateY(0px); + } + 50% { + transform: translateY(-15px); + } +} + @keyframes slideIn { from { opacity: 0; @@ -497,11 +378,59 @@ html { } } -/* Scrollbar Styling für die RSS Liste */ -.rss-list-scroll::-webkit-scrollbar { - width: 6px; +/* --- Utilities --- */ +.reload-btn-large { + cursor: pointer; + background: linear-gradient( + 135deg, + rgba(74, 144, 226, 0.15), + rgba(74, 144, 226, 0.05) + ); + color: var(--accent-color); + padding: 16px; + border-radius: 16px; + width: 100%; + font-weight: 700; + border: 1px solid rgba(74, 144, 226, 0.3); + user-select: none; + min-height: 52px; + transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); } -.rss-list-scroll::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.1); - border-radius: 10px; + +.reload-btn-large:hover { + background: rgba(74, 144, 226, 0.2); + border-color: var(--accent-color); + box-shadow: 0 6px 20px rgba(74, 144, 226, 0.2); + transform: translateY(-2px); +} + +.reload-btn-large:active { + transform: scale(0.96) translateY(0); +} + +/* Optional: Add a subtle pulse animation when content is old */ +@keyframes pulse-subtle { + 0% { + box-shadow: 0 0 0 0 rgba(74, 144, 226, 0.4); + } + 70% { + box-shadow: 0 0 0 10px rgba(74, 144, 226, 0); + } + 100% { + box-shadow: 0 0 0 0 rgba(74, 144, 226, 0); + } +} + +.error-box { + background: rgba(239, 68, 68, 0.1); + border: 1px solid rgba(239, 68, 68, 0.3); + color: var(--danger); + padding: 15px; + border-radius: 12px; + text-align: center; }