diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index d112ebff..7dfabb8c 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -29,6 +29,7 @@ jobs: chmod +x .github/scripts/generate-version.sh .github/scripts/generate-version.sh env: + COMMIT_MESSAGE: ${{ github.event.head_commit.message }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: 'Display version info' diff --git a/src-tauri/android-templates/MainActivity.kt b/src-tauri/android-templates/MainActivity.kt index 9553dbe2..b957a2e8 100644 --- a/src-tauri/android-templates/MainActivity.kt +++ b/src-tauri/android-templates/MainActivity.kt @@ -2,29 +2,87 @@ package io.tohowabohu.librefit import android.os.Bundle import android.view.View +import android.webkit.JavascriptInterface +import android.webkit.WebView import androidx.activity.enableEdgeToEdge +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.webkit.WebViewCompat +import androidx.webkit.WebViewFeature class MainActivity : TauriActivity() { + + private val safeArea = SafeAreaProvider() + override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) } - override fun onResume() { - super.onResume() - // Disable WebView overscroll to prevent bouncing that reveals gaps behind system bars - val webView = findWebView(window.decorView) - webView?.overScrollMode = View.OVER_SCROLL_NEVER - } + override fun onWebViewCreate(webView: WebView) { + super.onWebViewCreate(webView) + webView.overScrollMode = View.OVER_SCROLL_NEVER + + // CSS env(safe-area-inset-*) is broken on WebView < 140 and unreliable for + // navigation bars even on newer versions. Instead, expose insets via a + // JavaScript interface and inject them as CSS custom properties. + webView.addJavascriptInterface(safeArea, "__SAFE_AREA__") + + // Runs at document start on every page load — reads insets from the bridge + // and sets CSS custom properties before the page renders. + if (WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) { + WebViewCompat.addDocumentStartJavaScript(webView, APPLY_INSETS_JS, setOf("*")) + } + + // Update bridge values whenever system insets change (layout, keyboard, rotation). + ViewCompat.setOnApplyWindowInsetsListener(webView) { _, windowInsets -> + val systemBars = windowInsets.getInsets( + WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() + ) + val ime = windowInsets.getInsets(WindowInsetsCompat.Type.ime()) + val keyboardVisible = windowInsets.isVisible(WindowInsetsCompat.Type.ime()) + val density = resources.displayMetrics.density + + safeArea.update( + top = systemBars.top / density, + bottom = (if (keyboardVisible) ime.bottom else systemBars.bottom) / density, + left = systemBars.left / density, + right = systemBars.right / density + ) - private fun findWebView(view: View): View? { - if (view is android.webkit.WebView) return view - if (view is android.view.ViewGroup) { - for (i in 0 until view.childCount) { - val found = findWebView(view.getChildAt(i)) - if (found != null) return found - } + // Re-inject for dynamic changes (keyboard, rotation) — the document start + // script only runs on page load, not on inset changes. + webView.evaluateJavascript(APPLY_INSETS_JS, null) + windowInsets } - return null } + + companion object { + private const val APPLY_INSETS_JS = + "(function(){try{var i=JSON.parse(__SAFE_AREA__.getInsets());" + + "var s=document.documentElement.style;" + + "s.setProperty('--safe-area-top',i.top+'px');" + + "s.setProperty('--safe-area-bottom',i.bottom+'px');" + + "s.setProperty('--safe-area-left',i.left+'px');" + + "s.setProperty('--safe-area-right',i.right+'px');}catch(e){}})()" + } +} + +/** Thread-safe bridge providing system bar inset values to JavaScript. */ +class SafeAreaProvider { + @Volatile private var top: Float = 0f + @Volatile private var bottom: Float = 0f + @Volatile private var left: Float = 0f + @Volatile private var right: Float = 0f + + fun update(top: Float, bottom: Float, left: Float, right: Float) { + this.top = top + this.bottom = bottom + this.left = left + this.right = right + } + + @JavascriptInterface + fun getInsets(): String = + """{"top":$top,"bottom":$bottom,"left":$left,"right":$right}""" } diff --git a/src-tauri/android-templates/colors.xml b/src-tauri/android-templates/colors.xml deleted file mode 100644 index b5cfac42..00000000 --- a/src-tauri/android-templates/colors.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - #FFBB86FC - #FF6200EE - #FF3700B3 - #FF03DAC5 - #FF018786 - #FF000000 - #FFFFFFFF - #FF1A7A8A - #FFF9F8F6 - diff --git a/src-tauri/android-templates/setup-android.sh b/src-tauri/android-templates/setup-android.sh index e0cfb2f0..795bf9aa 100755 --- a/src-tauri/android-templates/setup-android.sh +++ b/src-tauri/android-templates/setup-android.sh @@ -97,16 +97,7 @@ else echo " ⚠️ themes.xml template not found" fi -# 7. Apply custom colors.xml (app color definitions) -if [ -f "$SCRIPT_DIR/colors.xml" ]; then - echo "🎨 Applying custom colors.xml..." - cp "$SCRIPT_DIR/colors.xml" "$ANDROID_DIR/app/src/main/res/values/colors.xml" - echo " ✅ colors.xml applied (includes primary color)" -else - echo " ⚠️ colors.xml template not found" -fi - -# 8. Force correct NDK path and version in local.properties and build.gradle.kts +# 7. Force correct NDK path and version in local.properties and build.gradle.kts if [ -n "$NDK_PATH" ]; then echo "🔧 Setting NDK path in local.properties..." diff --git a/src-tauri/android-templates/themes.xml b/src-tauri/android-templates/themes.xml index 1893944c..684e0811 100644 --- a/src-tauri/android-templates/themes.xml +++ b/src-tauri/android-templates/themes.xml @@ -1,8 +1,6 @@ diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 3e334d23..7be191ed 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -10,8 +10,7 @@ "height": 800, "resizable": true, "title": "librefit", - "width": 420, - "backgroundColor": [249, 248, 246, 255] + "width": 420 } ] }, diff --git a/src/routes/(app)/+page.svelte b/src/routes/(app)/+page.svelte index dc5572c7..b9d4473e 100644 --- a/src/routes/(app)/+page.svelte +++ b/src/routes/(app)/+page.svelte @@ -164,23 +164,6 @@ debug(`user profile=${JSON.stringify(userContext.user)}`); useRefresh(() => invalidate('data:dashboardData')); - - const cubicOut = 'cubic-bezier(0.33, 1, 0.68, 1)'; - - // FAB transitioning effect - const portal = (node: HTMLElement) => { - document.body.appendChild(node); - node.style.opacity = '0'; - node.style.transition = `opacity 150ms ${cubicOut}`; - setTimeout(() => (node.style.opacity = '1'), 100); - return { - destroy() { - node.style.transition = `opacity 100ms ${cubicOut}`; - node.style.opacity = '0'; - setTimeout(() => node.remove(), 100); - } - }; - };
@@ -313,11 +296,7 @@
- @@ -408,6 +387,15 @@