From c109fb66b94eb814ee1c0e3b3a3b33f0910bb4e0 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Sat, 14 Mar 2026 21:23:33 -0700 Subject: [PATCH 01/26] profile switcher button uses profile photo on mobile --- src/components/header.ts | 55 +++++++++++++++++++++++++++++++++++++++- src/pages/app-home.ts | 19 ++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/components/header.ts b/src/components/header.ts index 44e3a4e..84319be 100644 --- a/src/components/header.ts +++ b/src/components/header.ts @@ -27,6 +27,10 @@ export class AppHeader extends LitElement { @property({ type: Boolean }) showAccountSwitcher: boolean = false; + @property({ type: String }) currentAccountAvatar: string = ''; + + @property({ type: String }) currentAccountLabel: string = ''; + static get styles() { return css` header { @@ -60,6 +64,35 @@ export class AppHeader extends LitElement { gap: 0px; } + #account-switcher-button { + overflow: hidden; + } + + .account-avatar, + .avatar-placeholder { + width: 24px; + height: 24px; + border-radius: 999px; + } + + .account-avatar { + display: block; + object-fit: cover; + background: var(--md-sys-color-surface-container-high); + } + + .avatar-placeholder { + display: inline-flex; + align-items: center; + justify-content: center; + background: var(--md-sys-color-secondary-container); + color: var(--md-sys-color-on-secondary-container); + font-size: 0.75rem; + font-weight: 700; + line-height: 1; + text-transform: uppercase; + } + header img { view-transition-name: main-header-icon; contain: layout; @@ -168,6 +201,25 @@ export class AppHeader extends LitElement { import('../router/routes').then((m) => m.router.navigate('/messages')); } + private getCurrentAccountInitial(): string { + const source = this.currentAccountLabel.trim(); + return source.slice(0, 1) || '?'; + } + + private renderAccountSwitcherContent() { + if (this.currentAccountAvatar) { + return html`${this.currentAccountLabel || msg('Current account avatar')}`; + } + + return html``; + } + render() { return html`
@@ -226,11 +278,12 @@ export class AppHeader extends LitElement { ${this.showAccountSwitcher ? html` - + ${this.renderAccountSwitcherContent()} ` : nothing} ${this.guestMode diff --git a/src/pages/app-home.ts b/src/pages/app-home.ts index 878d007..6033d6f 100644 --- a/src/pages/app-home.ts +++ b/src/pages/app-home.ts @@ -35,6 +35,7 @@ import { saveSidebarTrending, } from '../services/sidebar-cache'; import { getLatestReadStorageKey } from '../services/account'; +import { getActiveAccount } from '../services/auth-session'; import type { OtterDrawer } from '../components/otter-drawer'; import type { MdDialog } from '../components/md/md-dialog'; @@ -162,6 +163,20 @@ export class AppHome extends LitElement { @query('scheduled-statuses-dialog') private scheduledStatusesDialog!: ScheduledStatusesDialog; + private getHeaderAccountIdentity(): { avatar: string; label: string } { + const activeAccount = getActiveAccount(); + + return { + avatar: this.user?.avatar || activeAccount?.avatar || '', + label: + this.user?.display_name || + this.user?.acct || + activeAccount?.displayName || + activeAccount?.acct || + '', + }; + } + static get styles() { return [styles, homeStyles, fadeInAnimation]; } @@ -824,6 +839,8 @@ export class AppHome extends LitElement { } render() { + const headerAccount = this.getHeaderAccountIdentity(); + return html` ${this.rightClickLoaded ? html` @@ -894,6 +911,8 @@ export class AppHome extends LitElement { .guestMode="${this.isGuestMode}" .showMessages="${!this.isGuestMode}" .showAccountSwitcher="${this.isMobile && !this.isGuestMode}" + .currentAccountAvatar="${headerAccount.avatar}" + .currentAccountLabel="${headerAccount.label}" > From c223de497c217c8e172c0b280c8e9d013c099a5a Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Sat, 14 Mar 2026 21:57:07 -0700 Subject: [PATCH 02/26] localize --- xliff/de.xlf | 3 +++ xliff/es.xlf | 3 +++ 2 files changed, 6 insertions(+) diff --git a/xliff/de.xlf b/xliff/de.xlf index 5b604da..e5fc1d1 100644 --- a/xliff/de.xlf +++ b/xliff/de.xlf @@ -1895,6 +1895,9 @@ more replies + + Current account avatar + diff --git a/xliff/es.xlf b/xliff/es.xlf index 5ecf0d3..e96658d 100644 --- a/xliff/es.xlf +++ b/xliff/es.xlf @@ -1895,6 +1895,9 @@ more replies + + Current account avatar + From 97843c8a460eaa3c0c736857fcb5020afbd91c34 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Sun, 15 Mar 2026 01:28:13 -0700 Subject: [PATCH 03/26] android capacitor --- .gitignore | 5 + android/.gitignore | 101 +++ android/app/.gitignore | 2 + android/app/build.gradle | 54 ++ android/app/capacitor.build.gradle | 20 + android/app/proguard-rules.pro | 21 + .../myapp/ExampleInstrumentedTest.java | 26 + android/app/src/main/AndroidManifest.xml | 49 + .../java/place/coho/app/MainActivity.java | 5 + .../main/res/drawable-land-hdpi/splash.png | Bin 0 -> 7705 bytes .../main/res/drawable-land-mdpi/splash.png | Bin 0 -> 4040 bytes .../main/res/drawable-land-xhdpi/splash.png | Bin 0 -> 9251 bytes .../main/res/drawable-land-xxhdpi/splash.png | Bin 0 -> 13984 bytes .../main/res/drawable-land-xxxhdpi/splash.png | Bin 0 -> 17683 bytes .../main/res/drawable-port-hdpi/splash.png | Bin 0 -> 7934 bytes .../main/res/drawable-port-mdpi/splash.png | Bin 0 -> 4096 bytes .../main/res/drawable-port-xhdpi/splash.png | Bin 0 -> 9875 bytes .../main/res/drawable-port-xxhdpi/splash.png | Bin 0 -> 13346 bytes .../main/res/drawable-port-xxxhdpi/splash.png | Bin 0 -> 17489 bytes .../drawable-v24/ic_launcher_foreground.xml | 34 + .../res/drawable/ic_launcher_background.xml | 170 ++++ android/app/src/main/res/drawable/splash.png | Bin 0 -> 4040 bytes .../app/src/main/res/layout/activity_main.xml | 12 + .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 2786 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 0 -> 3450 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 4341 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 1869 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 0 -> 2110 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2725 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 3981 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 0 -> 5036 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 6593 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6644 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 0 -> 9793 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10455 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9441 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 0 -> 15529 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15916 bytes .../res/values/ic_launcher_background.xml | 4 + android/app/src/main/res/values/strings.xml | 7 + android/app/src/main/res/values/styles.xml | 22 + android/app/src/main/res/xml/file_paths.xml | 5 + .../getcapacitor/myapp/ExampleUnitTest.java | 18 + android/build.gradle | 29 + android/capacitor.settings.gradle | 9 + android/gradle.properties | 22 + android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43764 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 + android/gradlew | 251 ++++++ android/gradlew.bat | 94 ++ android/settings.gradle | 5 + android/variables.gradle | 16 + capacitor.config.ts | 19 + firebase.json | 13 + functions/src/index.ts | 2 + package-lock.json | 844 ++++++++++++++++++ package.json | 5 + public/.well-known/assetlinks.json | 10 + src/app-index.ts | 37 +- src/components/header.ts | 2 +- src/config/firebase.ts | 4 +- src/generated/locales/de.ts | 3 + src/generated/locales/es.ts | 3 + src/pages/app-home.ts | 4 + src/pages/app-login.ts | 14 +- src/pages/auth-callback.ts | 96 ++ src/router/routes.ts | 6 + src/services/account.ts | 11 +- src/services/auth-platform.ts | 128 +++ src/utils/platform.ts | 16 + 72 files changed, 2206 insertions(+), 9 deletions(-) create mode 100644 android/.gitignore create mode 100644 android/app/.gitignore create mode 100644 android/app/build.gradle create mode 100644 android/app/capacitor.build.gradle create mode 100644 android/app/proguard-rules.pro create mode 100644 android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java create mode 100644 android/app/src/main/AndroidManifest.xml create mode 100644 android/app/src/main/java/place/coho/app/MainActivity.java create mode 100644 android/app/src/main/res/drawable-land-hdpi/splash.png create mode 100644 android/app/src/main/res/drawable-land-mdpi/splash.png create mode 100644 android/app/src/main/res/drawable-land-xhdpi/splash.png create mode 100644 android/app/src/main/res/drawable-land-xxhdpi/splash.png create mode 100644 android/app/src/main/res/drawable-land-xxxhdpi/splash.png create mode 100644 android/app/src/main/res/drawable-port-hdpi/splash.png create mode 100644 android/app/src/main/res/drawable-port-mdpi/splash.png create mode 100644 android/app/src/main/res/drawable-port-xhdpi/splash.png create mode 100644 android/app/src/main/res/drawable-port-xxhdpi/splash.png create mode 100644 android/app/src/main/res/drawable-port-xxxhdpi/splash.png create mode 100644 android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 android/app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 android/app/src/main/res/drawable/splash.png create mode 100644 android/app/src/main/res/layout/activity_main.xml create mode 100644 android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 android/app/src/main/res/values/ic_launcher_background.xml create mode 100644 android/app/src/main/res/values/strings.xml create mode 100644 android/app/src/main/res/values/styles.xml create mode 100644 android/app/src/main/res/xml/file_paths.xml create mode 100644 android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java create mode 100644 android/build.gradle create mode 100644 android/capacitor.settings.gradle create mode 100644 android/gradle.properties create mode 100644 android/gradle/wrapper/gradle-wrapper.jar create mode 100644 android/gradle/wrapper/gradle-wrapper.properties create mode 100755 android/gradlew create mode 100644 android/gradlew.bat create mode 100644 android/settings.gradle create mode 100644 android/variables.gradle create mode 100644 capacitor.config.ts create mode 100644 src/pages/auth-callback.ts create mode 100644 src/services/auth-platform.ts create mode 100644 src/utils/platform.ts diff --git a/.gitignore b/.gitignore index 56df3da..2da37bb 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,8 @@ stats.html # Service worker build artifact (generated from src/sw.ts) public/sw.js + +# Capacitor native build artifacts (projects themselves are committed) +android/app/build/ +android/.gradle/ +android/build/ diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..48354a3 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,101 @@ +# Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore + +# Built application files +*.apk +*.aar +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ +# Uncomment the following line in case you need and you don't have the release build type files in your app +# release/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml + +# Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. +#*.jks +#*.keystore + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild +.cxx/ + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +# lint/reports/ + +# Android Profiling +*.hprof + +# Cordova plugins for Capacitor +capacitor-cordova-android-plugins + +# Copied web assets +app/src/main/assets/public + +# Generated Config files +app/src/main/assets/capacitor.config.json +app/src/main/assets/capacitor.plugins.json +app/src/main/res/xml/config.xml diff --git a/android/app/.gitignore b/android/app/.gitignore new file mode 100644 index 0000000..043df80 --- /dev/null +++ b/android/app/.gitignore @@ -0,0 +1,2 @@ +/build/* +!/build/.npmkeep diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..73b57a7 --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,54 @@ +apply plugin: 'com.android.application' + +android { + namespace = "place.coho.app" + compileSdk = rootProject.ext.compileSdkVersion + defaultConfig { + applicationId "place.coho.app" + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + aaptOptions { + // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. + // Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61 + ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~' + } + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +repositories { + flatDir{ + dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs' + } +} + +dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion" + implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion" + implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion" + implementation project(':capacitor-android') + testImplementation "junit:junit:$junitVersion" + androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" + androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" + implementation project(':capacitor-cordova-android-plugins') +} + +apply from: 'capacitor.build.gradle' + +try { + def servicesJSON = file('google-services.json') + if (servicesJSON.text) { + apply plugin: 'com.google.gms.google-services' + } +} catch(Exception e) { + logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work") +} diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle new file mode 100644 index 0000000..70f93fc --- /dev/null +++ b/android/app/capacitor.build.gradle @@ -0,0 +1,20 @@ +// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN + +android { + compileOptions { + sourceCompatibility JavaVersion.VERSION_21 + targetCompatibility JavaVersion.VERSION_21 + } +} + +apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" +dependencies { + implementation project(':capacitor-app') + implementation project(':capacitor-browser') + +} + + +if (hasProperty('postBuildExtras')) { + postBuildExtras() +} diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/android/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java b/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java new file mode 100644 index 0000000..f2c2217 --- /dev/null +++ b/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.getcapacitor.myapp; + +import static org.junit.Assert.*; + +import android.content.Context; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.getcapacitor.app", appContext.getPackageName()); + } +} diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..ac283f4 --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/java/place/coho/app/MainActivity.java b/android/app/src/main/java/place/coho/app/MainActivity.java new file mode 100644 index 0000000..16a16ee --- /dev/null +++ b/android/app/src/main/java/place/coho/app/MainActivity.java @@ -0,0 +1,5 @@ +package place.coho.app; + +import com.getcapacitor.BridgeActivity; + +public class MainActivity extends BridgeActivity {} diff --git a/android/app/src/main/res/drawable-land-hdpi/splash.png b/android/app/src/main/res/drawable-land-hdpi/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..e31573b4fc93e60d171f4046c0220e1463075d9e GIT binary patch literal 7705 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 wKmFJ0_JHhk1&0B>;%YXATM literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-land-mdpi/splash.png b/android/app/src/main/res/drawable-land-mdpi/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a64923ea1a0565d25fa139c176d6bf42184e48 GIT binary patch literal 4040 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 XyOn+%7f`N3b2T^T3uj5+eShz7v)7qy literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-land-xhdpi/splash.png b/android/app/src/main/res/drawable-land-xhdpi/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..807725501bdd92e94e51e7b2b0006f69e0083a0b GIT binary patch literal 9251 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-land-xxhdpi/splash.png b/android/app/src/main/res/drawable-land-xxhdpi/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..14c6c8fe39fcd51a0414866ad28cbe8ff3acb060 GIT binary patch literal 13984 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®q@N z14_H8ofW)l{|J8q+a)eH)I0r)>WXdzV%7J>PA~6_J)KLT90iYa^K=Wz7D!OybzqSru=f4?|KFl;Y)gP_H6V4x`~kZ6fE(xM1&;?72-TZNk+0 zr+Crr5yl%Iy@vfmt3eYFl!jIvPGFz^8Ek+2`48O1_pCX3xNWh-zBa{rIcc%+=|XVj zANYTg&s}TKb#OztQrCW(Xk?V^i{`q~%HtcveTxq(_HKeC9GzrtguMT4Nvs@KakPTA z9>*8bBZmLz`lK5=l)=b|=dT3a5ag^a1^znZyx5QKfUb1b9yacArRp%3@QWo(hrsCU z-K!-=jDmv!zb7XT>)r|-Z0Ry}lk2;dk-ECqMwr_nKN#x*X6~B5hVIN>6$1HwBz3Of z=Pk){AL5*=d90f17_qZEJLm;Q%WMdX=*N&!ki@E&cy7?>{1ssAH(tACtp*r@d^til z)x(1#6(kPD+joSF&J3sxJU@{-sWCS+pZq{Gsx=?z4wP;>?)1yHv0?X?VP{}cX4~aH zxeBPKw_rgW8rvewS1W2#^y+c>-183iMbJCqc38RN_o~__9-n|jcd&oA`m7*&Fqqpc z;Tev*0LS-ZK47Sq1unfvP1S43uA12P?PJmI8BeTYPr~R*tYUm^0;U%Hmu?bSZHEK6 zPjsW=E67Kq-&trmf;)UkmRABH2U)V)-eRT$j(%G12lLMsThSsU10iP#{)ZnvjzN$d z*K%P3`}oqyvpWP~venr>3viH8^`)Ma*=B31hw*Q+tqE>i2y7w!(o^lI^Yss^=tHW( z;cnCT(%B1gLz+TRGW9roFjI1EQTu-u`(f#RmZ8;FSN(bsC1J;+(i_R6mrW=yYx$cy z#%QKVrEx~kVMg~yo?^N28Wnk6x%L;J8i|*|ANEiNjq(Vhzuzl3ikpA*G!Z}kLAzAI z9qnySo%D|AuJj12%h;Otqjs(>LPj?rNdeU8so>P(C>XMzlho94ZD#w=cCOOU;=3&^ zsqAG!i{~lY271D|m>ztPV`)X@FO_;`wPjppYNQpM+ncvtz1lZjN>!Q^*I}T%uP78Z7tbV2$q3W_)14=kLFyJ z1GqL6T>ClgeZorL!}xP4f%OB_EsmJ`uw7dGWNV9OLlhb|UMpVhc{4@Bhh`tO!ZqzD zhusd<=K^ah!L@gQ?6dOpI-ge^e>S5W9eII57Zu16eU?GRbgKTeVk9yS{iK|O(zLR> zheb?;jwGCHS80NCn=jKxgJ>}qu4l%5NPihjzazGv#J?Jcyl;<#IW&x4mm>nrW8>}C z3U@aeD~)*F(0o^2{GnKVm$Jr#aZE ztl~TOkM^SdzJapQ((!-i8b!RkVQBKkL`2ZCBuy!qI1L{3Er526plVols~68U-^9Px zR(3{j;Z9RHX^muc0dUywJ|`yyZFf=k&-Gb#m4u73Lm5Ks%BfHj%2|gjn#i> zLC5pO$2Em9H;qoKQmMtl<@wgtPF1%2HariD5O~u>8=^*J&au~JH%Ih@&2Uging3U_ z0bzfKucW$ZHSx}!#buB?+-J)%RQbbXM-!BJTS&#dU_@lxU6>te2O+9 z@F{F{Nb!;{Cd`Gx+$G?11aB~S#wIH%D=*=7f7H@D@%B1)&bF$@t3JDq4l*%(wJTlh zo`?uMq{YilKUewPNaC)GuOr<8j9&ofqRU__BRUX^x8Cj3a;a$rXzgXqW>LR#CUn%~m)t zYC&ol(gAkbc^fd`xWU&bk5vT6KbFmsR=O78Bn%t7 znbw&=c+|T&#r+bls5rU6D#HMvqA<|;)BV%jOMonkm^p$7Vcel-Wwn$=uAJv&(8W>% z9))Fxpl*(%E#wFm_m!U~2HqgZs^2vaGeY(UfYKrSHV}w^D0N6!se5Ewy)Yy-!(2

aKj2hWG7>znxs|SE zN4rHtiSPqLskWp(?(_YYwgq+1@8v+~8As|(bC>$D(atG3ZE8-ZM3SVcg|vHQz$I=!(A`k`5= zOqR>&%G)$)k*QLz7MTB9wleWpv&N9Sta64wy}3Ytd?x!Ja8z>(z~(3UNFu^eFmn#6 zw!!gUxOuZi$PQIs*ixfZR3iLyADJ z5&s%tPfk>V!x|A-;oq%1!yk9H$UBP0ToA*EDtz(^!_AnF1bBQ7joj|? z5b)gSI8c8O$PYFE!vXJ<4gebg*9G9P2wcB{#kv0FItc5T@PDNo)}Rh4Us}L{e}xzW zhwt`)j`M)mP=G6H0;^&q=I0{jU%bIRkF#uLF;{vVC&H|_uc literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-land-xxxhdpi/splash.png b/android/app/src/main/res/drawable-land-xxxhdpi/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..244ca2506dbe0fd8f6a05520ac7d1a629ea81438 GIT binary patch literal 17683 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-port-xxhdpi/splash.png b/android/app/src/main/res/drawable-port-xxhdpi/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..bfabe6871a17a5e95b78fb30d49b7d2b4d2fe4c0 GIT binary patch literal 13346 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

VwO4Hu8X}%XHUAz_J@50rzbkIsat>4oWtQt< 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-port-xxxhdpi/splash.png b/android/app/src/main/res/drawable-port-xxxhdpi/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..6929071268eb03ee0f088142b6523566b78550e2 GIT binary patch literal 17489 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 KR&><$`~L^lv%S~= literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..c7bd21d --- /dev/null +++ b/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/ic_launcher_background.xml b/android/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..d5fccc5 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/splash.png b/android/app/src/main/res/drawable/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a64923ea1a0565d25fa139c176d6bf42184e48 GIT binary patch literal 4040 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 XyOn+%7f`N3b2T^T3uj5+eShz7v)7qy literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..b5ad138 --- /dev/null +++ b/android/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..c023e50595074292c7361183a64de08cf9686c9c GIT binary patch literal 2786 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..2127973b2d318df7085734d236d0ec649a2b0292 GIT binary patch literal 3450 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d1e077104cd61e6a4c3707e87363b523077245a GIT binary patch literal 3981 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 nm0GElTB(&OnKI&V600000NkvXXu0mjff+~0a literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..df0f15880bee46332dfc6622583215194f948b0f GIT binary patch literal 5036 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..6cdf97c1196d48e9833487ff6de7c4cfc4e1232d GIT binary patch literal 6644 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..2960cbb6104b915c84760f889deed9bff2b3e17a GIT binary patch literal 9793 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 y3vD~Wi9;mL_v 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..a40d73e9c68ea638c28c7b13e4bcd1e179a3a102 GIT binary patch literal 15916 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 + + #FFFFFF + \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..5e13a05 --- /dev/null +++ b/android/app/src/main/res/values/strings.xml @@ -0,0 +1,7 @@ + + + Coho + Coho + place.coho.app + place.coho.app + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..be874e5 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/xml/file_paths.xml b/android/app/src/main/res/xml/file_paths.xml new file mode 100644 index 0000000..bd0c4d8 --- /dev/null +++ b/android/app/src/main/res/xml/file_paths.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java b/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java new file mode 100644 index 0000000..0297327 --- /dev/null +++ b/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java @@ -0,0 +1,18 @@ +package com.getcapacitor.myapp; + +import static org.junit.Assert.*; + +import org.junit.Test; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..f8f0e43 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,29 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + google() + mavenCentral() + } + dependencies { + classpath 'com.android.tools.build:gradle:8.13.0' + classpath 'com.google.gms:google-services:4.4.4' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +apply from: "variables.gradle" + +allprojects { + repositories { + google() + mavenCentral() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle new file mode 100644 index 0000000..fde830c --- /dev/null +++ b/android/capacitor.settings.gradle @@ -0,0 +1,9 @@ +// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN +include ':capacitor-android' +project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') + +include ':capacitor-app' +project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/android') + +include ':capacitor-browser' +project(':capacitor-browser').projectDir = new File('../node_modules/@capacitor/browser/android') diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..2e87c52 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,22 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..1b33c55baabb587c669f562ae36f953de2481846 GIT binary patch literal 43764 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH="\\\"\\\"" + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat new file mode 100644 index 0000000..5eed7ee --- /dev/null +++ b/android/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH= + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..3b4431d --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,5 @@ +include ':app' +include ':capacitor-cordova-android-plugins' +project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') + +apply from: 'capacitor.settings.gradle' \ No newline at end of file diff --git a/android/variables.gradle b/android/variables.gradle new file mode 100644 index 0000000..ee4ba41 --- /dev/null +++ b/android/variables.gradle @@ -0,0 +1,16 @@ +ext { + minSdkVersion = 24 + compileSdkVersion = 36 + targetSdkVersion = 36 + androidxActivityVersion = '1.11.0' + androidxAppCompatVersion = '1.7.1' + androidxCoordinatorLayoutVersion = '1.3.0' + androidxCoreVersion = '1.17.0' + androidxFragmentVersion = '1.8.9' + coreSplashScreenVersion = '1.2.0' + androidxWebkitVersion = '1.14.0' + junitVersion = '4.13.2' + androidxJunitVersion = '1.3.0' + androidxEspressoCoreVersion = '3.7.0' + cordovaAndroidVersion = '14.0.1' +} \ No newline at end of file diff --git a/capacitor.config.ts b/capacitor.config.ts new file mode 100644 index 0000000..50578b4 --- /dev/null +++ b/capacitor.config.ts @@ -0,0 +1,19 @@ +import type { CapacitorConfig } from '@capacitor/cli'; + +const config: CapacitorConfig = { + appId: 'place.coho.app', + appName: 'Coho', + webDir: 'dist', + server: { + // Use HTTPS scheme so the WebView origin matches typical browser behavior. + // This affects CORS: requests from the WebView will have origin "https://localhost". + androidScheme: 'https', + }, + plugins: { + App: { + // Keep default back-button handling so hardware back navigates the router + }, + }, +}; + +export default config; diff --git a/firebase.json b/firebase.json index dc85fdd..6f95a23 100644 --- a/firebase.json +++ b/firebase.json @@ -67,6 +67,19 @@ "value": "no-cache" } ] + }, + { + "source": "/.well-known/assetlinks.json", + "headers": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Cache-Control", + "value": "no-cache" + } + ] } ], "rewrites": [ diff --git a/functions/src/index.ts b/functions/src/index.ts index 25939d6..ef2003c 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -18,6 +18,8 @@ const allowedOrigins = [ 'https://coho.place', 'https://coho-mastodon.web.app', 'http://localhost:3000', + // Capacitor Android WebView origin (androidScheme: 'https' in capacitor.config.ts) + 'https://localhost', ]; const applyCors = ( diff --git a/package-lock.json b/package-lock.json index 34520c8..9318067 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,9 @@ "version": "0.0.1", "license": "ISC", "dependencies": { + "@capacitor/app": "^8.0.1", + "@capacitor/browser": "^8.0.2", + "@capacitor/core": "^8.2.0", "@huggingface/transformers": "^4.0.0-next.2", "@lit-labs/compiler": "^1.1.2", "@lit-labs/virtualizer": "^2.1.1", @@ -24,6 +27,8 @@ "web-router": "^0.5.0" }, "devDependencies": { + "@capacitor/android": "^8.2.0", + "@capacitor/cli": "^8.2.0", "@eslint/eslintrc": "^3.3.3", "@eslint/js": "^9.39.1", "@lit-labs/ssr": "^4.0.0", @@ -135,6 +140,102 @@ "node": ">=18" } }, + "node_modules/@capacitor/android": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@capacitor/android/-/android-8.2.0.tgz", + "integrity": "sha512-XLm5OsWLPfXQxDxzFS7SOdMEgGvW+2c7TGLXkTR2cSKdkWK5Abns4imlT5qghKYhjM9r74IrDkBWg/9ALUGNKQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@capacitor/core": "^8.2.0" + } + }, + "node_modules/@capacitor/app": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@capacitor/app/-/app-8.0.1.tgz", + "integrity": "sha512-yeG3yyA0ETKqvgqexwHMBlmVOF13A1hRXzv/km0Ptv5TrNIZvZJK4MTI3uiqvnbHrzoJGP5DwWAjEXEfi90v3Q==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=8.0.0" + } + }, + "node_modules/@capacitor/browser": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@capacitor/browser/-/browser-8.0.2.tgz", + "integrity": "sha512-oJEtVP5huwPJ8GgOCH3OewhsBPTW6aVtWg8hU6g65MxBdhkcAKyzYrhsyXupC5GaMxltqLf1JzKETMmGkh6tDw==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=8.0.0" + } + }, + "node_modules/@capacitor/cli": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-8.2.0.tgz", + "integrity": "sha512-1cMEk0d/I6tl1U+v/lnJR5Oylpx8ZBIHrvQxD5zK0MkjYOUyQAAGJgh97rkhGJqjAUvrGpa8H4BmyhNQN9a17A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/cli-framework-output": "^2.2.8", + "@ionic/utils-subprocess": "^3.0.1", + "@ionic/utils-terminal": "^2.3.5", + "commander": "^12.1.0", + "debug": "^4.4.0", + "env-paths": "^2.2.0", + "fs-extra": "^11.2.0", + "kleur": "^4.1.5", + "native-run": "^2.0.3", + "open": "^8.4.0", + "plist": "^3.1.0", + "prompts": "^2.4.2", + "rimraf": "^6.0.1", + "semver": "^7.6.3", + "tar": "^7.5.3", + "tslib": "^2.8.1", + "xml2js": "^0.6.2" + }, + "bin": { + "cap": "bin/capacitor", + "capacitor": "bin/capacitor" + }, + "engines": { + "node": ">=22.0.0" + } + }, + "node_modules/@capacitor/cli/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@capacitor/cli/node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@capacitor/core": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-8.2.0.tgz", + "integrity": "sha512-oKaoNeNtH2iIZMDFVrb1atoyRECDGHcfLMunJ5KWN8DtvpVBeeA4c41e20NTuhMxw1cSYbpq2PV2hb+/9CJxlQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/@emnapi/runtime": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", @@ -1457,6 +1558,251 @@ } } }, + "node_modules/@ionic/cli-framework-output": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@ionic/cli-framework-output/-/cli-framework-output-2.2.8.tgz", + "integrity": "sha512-TshtaFQsovB4NWRBydbNFawql6yul7d5bMiW1WYYf17hd99V6xdDdk3vtF51bw6sLkxON3bDQpWsnUc9/hVo3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-terminal": "2.3.5", + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-array": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.6.tgz", + "integrity": "sha512-0JZ1Zkp3wURnv8oq6Qt7fMPo5MpjbLoUoa9Bu2Q4PJuSDWM8H8gwF3dQO7VTeUj3/0o1IB1wGkFWZZYgUXZMUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-fs": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.7.tgz", + "integrity": "sha512-2EknRvMVfhnyhL1VhFkSLa5gOcycK91VnjfrTB0kbqkTFCOXyXgVLI5whzq7SLrgD9t1aqos3lMMQyVzaQ5gVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^8.0.0", + "debug": "^4.0.0", + "fs-extra": "^9.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-fs/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@ionic/utils-object": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.6.tgz", + "integrity": "sha512-vCl7sl6JjBHFw99CuAqHljYJpcE88YaH2ZW4ELiC/Zwxl5tiwn4kbdP/gxi2OT3MQb1vOtgAmSNRtusvgxI8ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-process": { + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.12.tgz", + "integrity": "sha512-Jqkgyq7zBs/v/J3YvKtQQiIcxfJyplPgECMWgdO0E1fKrrH8EF0QGHNJ9mJCn6PYe2UtHNS8JJf5G21e09DfYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-object": "2.1.6", + "@ionic/utils-terminal": "2.3.5", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "tree-kill": "^1.2.2", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@ionic/utils-stream/-/utils-stream-3.1.7.tgz", + "integrity": "sha512-eSELBE7NWNFIHTbTC2jiMvh1ABKGIpGdUIvARsNPMNQhxJB3wpwdiVnoBoTYp+5a6UUIww4Kpg7v6S7iTctH1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-subprocess": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@ionic/utils-subprocess/-/utils-subprocess-3.0.1.tgz", + "integrity": "sha512-cT4te3AQQPeIM9WCwIg8ohroJ8TjsYaMb2G4ZEgv9YzeDqHZ4JpeIKqG2SoaA3GmVQ3sOfhPM6Ox9sxphV/d1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-array": "2.1.6", + "@ionic/utils-fs": "3.1.7", + "@ionic/utils-process": "2.1.12", + "@ionic/utils-stream": "3.1.7", + "@ionic/utils-terminal": "2.3.5", + "cross-spawn": "^7.0.3", + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-terminal": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.5.tgz", + "integrity": "sha512-3cKScz9Jx2/Pr9ijj1OzGlBDfcmx7OMVBt4+P1uRR0SSW4cm1/y3Mo4OY3lfkuaYifMNBW8Wz6lQHbs1bihr7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/slice-ansi": "^4.0.0", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "slice-ansi": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "tslib": "^2.0.1", + "untildify": "^4.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-terminal/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@ionic/utils-terminal/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@ionic/utils-terminal/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/@ionic/utils-terminal/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@ionic/utils-terminal/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@ionic/utils-terminal/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -2597,6 +2943,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/statuses": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.6.tgz", @@ -3428,6 +3781,16 @@ "node": ">=8" } }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/axe-core": { "version": "4.11.0", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz", @@ -3445,6 +3808,37 @@ "dev": true, "license": "MIT" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">=0.6" + } + }, "node_modules/boolean": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", @@ -3452,6 +3846,19 @@ "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "license": "MIT" }, + "node_modules/bplist-parser": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", + "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "big-integer": "1.6.x" + }, + "engines": { + "node": ">= 5.10.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -3482,6 +3889,16 @@ "integrity": "sha512-JveqW2w6pEZqFEEfMgCszXzYpE89dG+nPsmOdcs741mFFAROeL+iqjGEpR07RI+s0YY0EFr+4KnOoACprJTpOw==", "license": "Apache-2.0" }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -3607,6 +4024,16 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -4077,6 +4504,19 @@ "dev": true, "license": "MIT" }, + "node_modules/elementtree": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", + "integrity": "sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "sax": "1.1.4" + }, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -4120,6 +4560,16 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/environment": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", @@ -4612,6 +5062,16 @@ "reusify": "^1.0.4" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/fetch-blob": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", @@ -5250,6 +5710,16 @@ "dev": true, "license": "ISC" }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/internal-ip": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-6.2.0.tgz", @@ -5657,6 +6127,16 @@ "json-buffer": "3.0.1" } }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/koa": { "version": "2.16.3", "resolved": "https://registry.npmjs.org/koa/-/koa-2.16.3.tgz", @@ -6269,6 +6749,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -6419,6 +6922,32 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/native-run": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/native-run/-/native-run-2.0.3.tgz", + "integrity": "sha512-U1PllBuzW5d1gfan+88L+Hky2eZx+9gv3Pf6rNBxKbORxi7boHzqiA6QFGSnqMem4j0A9tZ08NMIs5+0m/VS1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-fs": "^3.1.7", + "@ionic/utils-terminal": "^2.3.4", + "bplist-parser": "^0.3.2", + "debug": "^4.3.4", + "elementtree": "^0.1.7", + "ini": "^4.1.1", + "plist": "^3.1.0", + "split2": "^4.2.0", + "through2": "^4.0.2", + "tslib": "^2.6.2", + "yauzl": "^2.10.0" + }, + "bin": { + "native-run": "bin/native-run" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -6724,6 +7253,13 @@ "node": ">=8" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/package-json-type": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/package-json-type/-/package-json-type-1.0.3.tgz", @@ -6820,6 +7356,33 @@ "dev": true, "license": "MIT" }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/path-to-regexp": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", @@ -6844,6 +7407,13 @@ "dev": true, "license": "MIT" }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -6943,6 +7513,21 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, "node_modules/pngjs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", @@ -7008,6 +7593,30 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/protobufjs": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", @@ -7126,6 +7735,21 @@ "node": ">= 0.8" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -7284,6 +7908,83 @@ "dev": true, "license": "MIT" }, + "node_modules/rimraf": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", + "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.3", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/roarr": { "version": "2.15.4", "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", @@ -7537,6 +8238,13 @@ "dev": true, "license": "MIT" }, + "node_modules/sax": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", + "integrity": "sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==", + "dev": true, + "license": "ISC" + }, "node_modules/semver": { "version": "7.7.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", @@ -7761,6 +8469,13 @@ "node": ">=18" } }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -7842,6 +8557,16 @@ "node": ">=0.10.0" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/sprintf-js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", @@ -7879,6 +8604,16 @@ "dev": true, "license": "MIT" }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", @@ -7998,6 +8733,23 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/tar": { + "version": "7.5.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.11.tgz", + "integrity": "sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/terser": { "version": "5.44.1", "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", @@ -8024,6 +8776,16 @@ "dev": true, "license": "MIT" }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "3" + } + }, "node_modules/tiny-invariant": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", @@ -8173,6 +8935,16 @@ "node": ">=16" } }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, "node_modules/ts-api-utils": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.3.0.tgz", @@ -8350,6 +9122,16 @@ "url": "https://github.com/sponsors/kettanaito" } }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -8366,6 +9148,13 @@ "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==", "license": "MIT" }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -8845,6 +9634,40 @@ } } }, + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml2js/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -8855,6 +9678,16 @@ "node": ">=10" } }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/yaml": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", @@ -8948,6 +9781,17 @@ "node": ">=8" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/ylru": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.4.0.tgz", diff --git a/package.json b/package.json index cdb6a4d..a8be87e 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,9 @@ "author": "", "license": "ISC", "dependencies": { + "@capacitor/app": "^8.0.1", + "@capacitor/browser": "^8.0.2", + "@capacitor/core": "^8.2.0", "@huggingface/transformers": "^4.0.0-next.2", "@lit-labs/compiler": "^1.1.2", "@lit-labs/virtualizer": "^2.1.1", @@ -58,6 +61,8 @@ "web-router": "^0.5.0" }, "devDependencies": { + "@capacitor/android": "^8.2.0", + "@capacitor/cli": "^8.2.0", "@eslint/eslintrc": "^3.3.3", "@eslint/js": "^9.39.1", "@lit-labs/ssr": "^4.0.0", diff --git a/public/.well-known/assetlinks.json b/public/.well-known/assetlinks.json index bb53753..be332a6 100644 --- a/public/.well-known/assetlinks.json +++ b/public/.well-known/assetlinks.json @@ -7,4 +7,14 @@ "11:B4:5F:D0:8B:F6:6D:6E:CC:FC:5A:5D:FA:EB:46:14:64:21:D5:8A:64:9A:02:0A:C4:DA:AF:05:71:A5:32:CB" ] } +}, +{ + "relation": ["delegate_permission/common.handle_all_urls"], + "target": { + "namespace": "android_app", + "package_name": "place.coho.app", + "sha256_cert_fingerprints": [ + "82:20:E9:33:F1:68:59:CF:76:A9:AB:E6:74:3C:6E:00:A6:BF:B0:DF:13:F9:10:DE:67:79:E9:BF:95:AD:FF:DA" + ] + } }] diff --git a/src/app-index.ts b/src/app-index.ts index f0b9a8f..6a4a374 100644 --- a/src/app-index.ts +++ b/src/app-index.ts @@ -69,6 +69,10 @@ export class AppIndex extends LitElement { console.error('[App] Failed to bootstrap auth session', error); } + // If the app was cold-launched via an OAuth deep link (App Link / Universal Link), + // consume the launch URL and complete the token exchange before routing starts. + await this.handleNativeLaunchCallback(); + // Register route-changed listener BEFORE router.init() to avoid missing the // initial route-changed event in browsers with native Navigation API + URLPattern // support (where init() completes synchronously before firstUpdated() runs). @@ -88,10 +92,13 @@ export class AppIndex extends LitElement { // Ensure the initial route renders after init completes this.requestUpdate(); - // Defer PWA update component - not needed immediately, loads on browser idle - requestIdleCallback(() => import('./components/pwa-update'), { - timeout: 5000, - }); + // Defer PWA update component - not needed in Capacitor native shell + const { isNativePlatform } = await import('./utils/platform.js'); + if (!isNativePlatform()) { + requestIdleCallback(() => import('./components/pwa-update'), { + timeout: 5000, + }); + } } disconnectedCallback() { @@ -99,6 +106,28 @@ export class AppIndex extends LitElement { router.removeEventListener('route-changed', this._onRouteChanged); } + /** + * Check if the app was cold-launched via a native deep link carrying OAuth + * callback params. If so, complete the token exchange so the user lands + * authenticated when routing initializes. + */ + private async handleNativeLaunchCallback() { + try { + const { isNativePlatform } = await import('./utils/platform.js'); + if (!isNativePlatform()) return; + + const { consumeLaunchCallback } = + await import('./services/auth-platform.js'); + const params = await consumeLaunchCallback(); + if (params) { + const { authToClient } = await import('./services/account.js'); + await authToClient(params.code, params.state); + } + } catch (error) { + console.error('[App] Native launch callback failed', error); + } + } + async handleInitTheme() { const { getSettings } = await import('./services/settings'); const settings = await getSettings(); diff --git a/src/components/header.ts b/src/components/header.ts index 84319be..e64d5cd 100644 --- a/src/components/header.ts +++ b/src/components/header.ts @@ -41,7 +41,7 @@ export class AppHeader extends LitElement { padding-right: 5px; position: fixed; left: env(titlebar-area-x, 0); - top: env(titlebar-area-y, 0); + top: env(titlebar-area-y, env(safe-area-inset-top, 0)); right: 0; app-region: drag; diff --git a/src/config/firebase.ts b/src/config/firebase.ts index 9337292..194ddfd 100644 --- a/src/config/firebase.ts +++ b/src/config/firebase.ts @@ -16,7 +16,9 @@ const LOCAL_BASE_URL = `http://127.0.0.1:5001/${FIREBASE_PROJECT_ID}/${FIREBASE_ const isLocal = (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') && - import.meta.env.MODE !== 'test'; + import.meta.env.MODE !== 'test' && + // Capacitor's WebView runs on https://localhost but should use production APIs + window.location.protocol !== 'https:'; // Export the appropriate base URL export const FIREBASE_FUNCTIONS_BASE_URL = isLocal diff --git a/src/generated/locales/de.ts b/src/generated/locales/de.ts index 3d9376e..ed593a4 100644 --- a/src/generated/locales/de.ts +++ b/src/generated/locales/de.ts @@ -280,6 +280,8 @@ export const templates = { sfdfc05708c242107: `Wie du für andere erscheinst`, sfe2f8c98d9edbf7a: `Beitrag nicht gefunden`, sff9d51b6c5a73163: `Alt-Text`, + s93c8f5aaa2f14fb6: `Back to login`, + s59169c4e8fbcdccf: `Signing in…`, sddd265e80aabafea: `Audio player`, s061cc20e3432dead: `Pause`, scd105819b5a10243: `Play`, @@ -337,6 +339,7 @@ export const templates = { s2bcebb0b6a6517b6: `Search for your server to connect another Mastodon account.`, s626c98f49c83a793: `Search for a Mastodon server`, s6d83773bf37278f8: `Starting OAuth...`, + sf18a42912f62bf8a: `Current account avatar`, s86723627c116f82a: `Failed to load notification preferences.`, sbfdfd594b652f867: `Failed to save notification preferences.`, s5261000c68eafb43: `Push notifications are not enabled.`, diff --git a/src/generated/locales/es.ts b/src/generated/locales/es.ts index 3c7829e..3462ebf 100644 --- a/src/generated/locales/es.ts +++ b/src/generated/locales/es.ts @@ -280,6 +280,8 @@ export const templates = { sfdfc05708c242107: `Cómo apareces ante los otros`, sfe2f8c98d9edbf7a: `Publicación no encontrada`, sff9d51b6c5a73163: `Texto Alternativo`, + s93c8f5aaa2f14fb6: `Back to login`, + s59169c4e8fbcdccf: `Signing in…`, sddd265e80aabafea: `Audio player`, s061cc20e3432dead: `Pause`, scd105819b5a10243: `Play`, @@ -337,6 +339,7 @@ export const templates = { s2bcebb0b6a6517b6: `Search for your server to connect another Mastodon account.`, s626c98f49c83a793: `Search for a Mastodon server`, s6d83773bf37278f8: `Starting OAuth...`, + sf18a42912f62bf8a: `Current account avatar`, s86723627c116f82a: `Failed to load notification preferences.`, sbfdfd594b652f867: `Failed to save notification preferences.`, s5261000c68eafb43: `Push notifications are not enabled.`, diff --git a/src/pages/app-home.ts b/src/pages/app-home.ts index 6033d6f..018eaa2 100644 --- a/src/pages/app-home.ts +++ b/src/pages/app-home.ts @@ -770,6 +770,10 @@ export class AppHome extends LitElement { // PWA Install methods async checkInstallPrompt() { + // Skip install prompt entirely when running inside Capacitor native shell + const { isNativePlatform } = await import('../utils/platform'); + if (isNativePlatform()) return; + // Wait a moment for the pwa-install component to initialize await this.updateComplete; diff --git a/src/pages/app-login.ts b/src/pages/app-login.ts index c9c8b48..2221ba8 100644 --- a/src/pages/app-login.ts +++ b/src/pages/app-login.ts @@ -209,8 +209,20 @@ export class AppLogin extends LitElement { } this.loggingIn = true; try { - const { initAuth } = await import('../services/account'); + const { initAuth, authToClient } = await import('../services/account'); await initAuth(serverURL); + + // On native, the OAuth redirect comes back as an appUrlOpen event + // instead of a page navigation, so we listen for it here. + const { isNativePlatform } = await import('../utils/platform'); + if (isNativePlatform()) { + const { waitForNativeCallback } = + await import('../services/auth-platform'); + const { code, state } = await waitForNativeCallback(); + await authToClient(code, state); + const router = await getRouter(); + await router.navigate(await this.getPostAuthRedirect()); + } } catch (err) { console.error(err); } finally { diff --git a/src/pages/auth-callback.ts b/src/pages/auth-callback.ts new file mode 100644 index 0000000..55ee9dc --- /dev/null +++ b/src/pages/auth-callback.ts @@ -0,0 +1,96 @@ +import { LitElement, html, css } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { msg, localized } from '@lit/localize'; + +const getRouter = () => import('../router/routes').then((m) => m.router); + +/** + * Lightweight callback page that handles the OAuth redirect. + * Parses `code` and `state` from query params, exchanges for a token, + * then navigates to the post-auth destination. + */ +@localized() +@customElement('auth-callback') +export class AuthCallback extends LitElement { + @state() private error: string | null = null; + + static styles = css` + :host { + display: flex; + align-items: center; + justify-content: center; + height: 100dvh; + width: 100%; + } + + .container { + text-align: center; + padding: 2rem; + } + + .error { + color: var(--md-sys-color-error, #b3261e); + } + + a { + color: var(--md-sys-color-primary, #6750a4); + } + `; + + connectedCallback() { + super.connectedCallback(); + this.handleCallback(); + } + + private async handleCallback() { + const urlParams = new URLSearchParams(window.location.search); + const code = urlParams.get('code'); + const state = urlParams.get('state'); + + if (!code || !state) { + this.error = 'Missing authorization parameters.'; + return; + } + + try { + const { bootstrapSession } = await import('../services/auth-session.js'); + await bootstrapSession(); + + const { authToClient } = await import('../services/account.js'); + await authToClient(code, state); + + const router = await getRouter(); + await router.navigate(await this.getPostAuthRedirect()); + } catch (err) { + console.error('Auth callback error', err); + this.error = + err instanceof Error ? err.message : 'Authentication failed.'; + } + } + + private async getPostAuthRedirect(): Promise { + const { consumeAuthRedirect } = await import('../utils/auth-redirect.js'); + const storedRedirect = consumeAuthRedirect(); + if (storedRedirect) { + return storedRedirect; + } + return '/home'; + } + + render() { + if (this.error) { + return html` +

+

${this.error}

+ ${msg('Back to login')} +
+ `; + } + + return html` +
+

${msg('Signing in…')}

+
+ `; + } +} diff --git a/src/router/routes.ts b/src/router/routes.ts index 0f0dc1e..a2a4ab4 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -24,6 +24,12 @@ const routes: Route[] = [ title: 'login', render: () => html``, }, + { + path: '/auth/callback', + title: 'signing in', + plugins: [lazy(() => import('../pages/auth-callback.js'))], + render: () => html``, + }, { path: '/share', title: 'share', diff --git a/src/services/account.ts b/src/services/account.ts index b04fa4c..2006c94 100644 --- a/src/services/account.ts +++ b/src/services/account.ts @@ -536,7 +536,13 @@ export const getInstanceInfo = async () => { export const initAuth = async (serverURL: string) => { const normalizedServer = normalizeServer(serverURL); - const redirect_uri = location.origin; + + // On native, location.origin is "https://localhost" (Capacitor WebView). + // The redirect must use the real domain so the OS intercepts it as an App Link. + const { isNativePlatform } = await import('../utils/platform.js'); + const redirect_uri = isNativePlatform() + ? 'https://coho.place/auth/callback' + : `${location.origin}/auth/callback`; const response = await fetch(`${FIREBASE_FUNCTIONS_BASE_URL}/authenticate`, { method: 'POST', @@ -549,7 +555,8 @@ export const initAuth = async (serverURL: string) => { const data = await response.json(); - window.location.href = data.url; + const { openOAuthUrl } = await import('./auth-platform.js'); + await openOAuthUrl(data.url); }; export const authToClient = async (code: string, state: string) => { diff --git a/src/services/auth-platform.ts b/src/services/auth-platform.ts new file mode 100644 index 0000000..f244474 --- /dev/null +++ b/src/services/auth-platform.ts @@ -0,0 +1,128 @@ +import { isNativePlatform } from '../utils/platform.js'; + +/** + * Parsed OAuth callback parameters. + */ +export interface OAuthCallbackParams { + code: string; + state: string; +} + +/** + * Open the OAuth authorization URL in the appropriate context. + * + * - Web: navigates the current tab (`window.location.href`). + * - Capacitor: opens a Chrome Custom Tab / SFSafariViewController + * via `@capacitor/browser` so the user stays in a system browser + * context (cookie jar, password manager, etc.). + */ +export async function openOAuthUrl(url: string): Promise { + if (isNativePlatform()) { + const { Browser } = await import('@capacitor/browser'); + await Browser.open({ url, presentationStyle: 'popover' }); + } else { + window.location.href = url; + } +} + +/** + * Listen for an OAuth callback URL delivered via an App Link / Universal Link. + * + * Returns a promise that resolves with the parsed `code` and `state` when the + * OS hands a matching URL back to the app. The listener is automatically + * cleaned up after the first matching callback (or on `signal.abort()`). + * + * Only meaningful on Capacitor — on web the callback arrives via normal + * navigation to `/auth/callback` and is handled by the route component. + */ +export function waitForNativeCallback( + signal?: AbortSignal +): Promise { + return new Promise((resolve, reject) => { + if (signal?.aborted) { + reject(new DOMException('Aborted', 'AbortError')); + return; + } + + let settled = false; + + Promise.all([import('@capacitor/app'), import('@capacitor/browser')]).then( + async ([{ App }, { Browser }]) => { + const appHandle = await App.addListener('appUrlOpen', ({ url }) => { + const params = parseCallbackUrl(url); + if (params && !settled) { + settled = true; + appHandle.remove(); + browserHandle.remove(); + Browser.close().catch(() => {}); + resolve(params); + } + }); + + // If the user closes the browser without completing OAuth, reject. + // A short delay avoids racing with appUrlOpen when an App Link + // redirect also triggers browserFinished. + const browserHandle = await Browser.addListener( + 'browserFinished', + () => { + setTimeout(() => { + if (!settled) { + settled = true; + appHandle.remove(); + browserHandle.remove(); + reject(new DOMException('Browser closed', 'AbortError')); + } + }, 500); + } + ); + + signal?.addEventListener( + 'abort', + () => { + if (!settled) { + settled = true; + appHandle.remove(); + browserHandle.remove(); + reject(new DOMException('Aborted', 'AbortError')); + } + }, + { once: true } + ); + } + ); + }); +} + +/** + * Check if the app was cold-launched via a deep link that carries OAuth + * callback parameters. Returns the params if present, otherwise `null`. + * + * Should be called once during app startup before the `appUrlOpen` listener + * is registered, because cold-launch URLs are only available via + * `App.getLaunchUrl()` and are NOT re-delivered as `appUrlOpen` events. + */ +export async function consumeLaunchCallback(): Promise { + if (!isNativePlatform()) return null; + + const { App } = await import('@capacitor/app'); + const result = await App.getLaunchUrl(); + if (!result?.url) return null; + return parseCallbackUrl(result.url); +} + +/** + * Parse an OAuth callback URL and extract `code` and `state` params. + * Returns `null` if the URL doesn't match the expected callback path. + */ +function parseCallbackUrl(url: string): OAuthCallbackParams | null { + try { + const parsed = new URL(url); + if (!parsed.pathname.startsWith('/auth/callback')) return null; + const code = parsed.searchParams.get('code'); + const state = parsed.searchParams.get('state'); + if (code && state) return { code, state }; + return null; + } catch { + return null; + } +} diff --git a/src/utils/platform.ts b/src/utils/platform.ts new file mode 100644 index 0000000..45b4acd --- /dev/null +++ b/src/utils/platform.ts @@ -0,0 +1,16 @@ +import { Capacitor } from '@capacitor/core'; + +/** + * Returns true when the app is running inside a Capacitor native shell + * (Android or iOS), false when running as a regular web page or PWA. + */ +export function isNativePlatform(): boolean { + return Capacitor.isNativePlatform(); +} + +/** + * Returns the current platform: 'android', 'ios', or 'web'. + */ +export function getPlatform(): 'android' | 'ios' | 'web' { + return Capacitor.getPlatform() as 'android' | 'ios' | 'web'; +} From d51e671e58e38951578f3f5ba136a340233406e7 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Sun, 15 Mar 2026 22:08:05 -0700 Subject: [PATCH 04/26] feat: add push notifications for Capacitor Android --- android/app/capacitor.build.gradle | 1 + android/app/google-services.json | 29 ++ android/app/src/main/AndroidManifest.xml | 2 + android/capacitor.settings.gradle | 3 + capacitor.config.ts | 4 + functions/package-lock.json | 10 + functions/package.json | 1 + functions/src/index.ts | 3 + functions/src/push-relay.ts | 422 +++++++++++++++++++++++ package-lock.json | 10 + package.json | 1 + scripts/test-push.mjs | 54 +++ src/app-index.ts | 10 + src/components/notifications.ts | 17 +- src/services/notifications.ts | 14 + src/services/push-native.ts | 351 +++++++++++++++++++ vite.config.ts | 3 +- 17 files changed, 929 insertions(+), 6 deletions(-) create mode 100644 android/app/google-services.json create mode 100644 functions/src/push-relay.ts create mode 100644 scripts/test-push.mjs create mode 100644 src/services/push-native.ts diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle index 70f93fc..b012cdb 100644 --- a/android/app/capacitor.build.gradle +++ b/android/app/capacitor.build.gradle @@ -11,6 +11,7 @@ apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" dependencies { implementation project(':capacitor-app') implementation project(':capacitor-browser') + implementation project(':capacitor-push-notifications') } diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..6293f4c --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "117311718455", + "project_id": "coho-mastodon", + "storage_bucket": "coho-mastodon.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:117311718455:android:ca27519307eab20e21ebb2", + "android_client_info": { + "package_name": "place.coho.app" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyBu3u8WpBs5hkiLa6r3O8MKR-Mrd3xPWyg" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index ac283f4..3d018d9 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -46,4 +46,6 @@ + + diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle index fde830c..6226bf0 100644 --- a/android/capacitor.settings.gradle +++ b/android/capacitor.settings.gradle @@ -7,3 +7,6 @@ project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/ include ':capacitor-browser' project(':capacitor-browser').projectDir = new File('../node_modules/@capacitor/browser/android') + +include ':capacitor-push-notifications' +project(':capacitor-push-notifications').projectDir = new File('../node_modules/@capacitor/push-notifications/android') diff --git a/capacitor.config.ts b/capacitor.config.ts index 50578b4..e26af02 100644 --- a/capacitor.config.ts +++ b/capacitor.config.ts @@ -13,6 +13,10 @@ const config: CapacitorConfig = { App: { // Keep default back-button handling so hardware back navigates the router }, + PushNotifications: { + // Show notifications even when the app is in the foreground + presentationOptions: ['badge', 'sound', 'alert'], + }, }, }; diff --git a/functions/package-lock.json b/functions/package-lock.json index 3f20fd1..f08333c 100644 --- a/functions/package-lock.json +++ b/functions/package-lock.json @@ -8,6 +8,7 @@ "dependencies": { "firebase-admin": "^12.6.0", "firebase-functions": "^6.0.1", + "http_ece": "^1.2.1", "openai": "^6.8.1" }, "devDependencies": { @@ -3690,6 +3691,15 @@ "dev": true, "license": "MIT" }, + "node_modules/http_ece": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/http_ece/-/http_ece-1.2.1.tgz", + "integrity": "sha512-+tzLoMYgXvicu60sVFoswTiu6BiQ6EX3DORRJQ3W2dNpNWCyZ3tcmRFZZ3jgVyw8ziWUCeUARKCkYDY6JgFx+w==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", diff --git a/functions/package.json b/functions/package.json index 59aa27c..c0bf624 100644 --- a/functions/package.json +++ b/functions/package.json @@ -16,6 +16,7 @@ "dependencies": { "firebase-admin": "^12.6.0", "firebase-functions": "^6.0.1", + "http_ece": "^1.2.1", "openai": "^6.8.1" }, "devDependencies": { diff --git a/functions/src/index.ts b/functions/src/index.ts index ef2003c..9bc51b7 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -10,6 +10,9 @@ import { defineSecret } from 'firebase-functions/params'; import OpenAI from 'openai'; import * as crypto from 'crypto'; +// Re-export push relay functions +export { pushRelay, pushRelayPush } from './push-relay'; + // Define the secret const openaiApiKey = defineSecret('OPENAI_API_KEY'); diff --git a/functions/src/push-relay.ts b/functions/src/push-relay.ts new file mode 100644 index 0000000..63902da --- /dev/null +++ b/functions/src/push-relay.ts @@ -0,0 +1,422 @@ +/** + * Push Relay — bridges Mastodon Web Push to FCM for Capacitor Android. + * + * Mastodon sends encrypted Web Push messages to an endpoint URL. + * This relay: + * 1. Registers an FCM token + generates ECDH keys → returns a Web Push–compatible + * subscription (endpoint + keys) that can be sent to Mastodon. + * 2. Receives incoming Web Push POSTs from Mastodon, decrypts them, and + * forwards the JSON payload to the device via FCM. + * 3. Supports unregistration to clean up Firestore entries. + */ + +import { onRequest, type Request } from 'firebase-functions/v2/https'; +import type { Response } from 'express'; +import * as logger from 'firebase-functions/logger'; +import * as admin from 'firebase-admin'; +import * as crypto from 'crypto'; +import * as http from 'http'; +// eslint-disable-next-line @typescript-eslint/no-require-imports +const ece = require('http_ece'); + +// --------------------------------------------------------------------------- +// Patch: strip non-standard Content-Encoding from Web Push requests +// --------------------------------------------------------------------------- +// Mastodon sends Content-Encoding: aesgcm (an *application-level* encryption +// scheme, not an HTTP transfer encoding). The Cloud Functions runtime's +// body-parser rejects anything it can't decompress (gzip/deflate/br/identity) +// with a 415 — and there's no way to disable or configure it. +// +// This patch intercepts the Node.js HTTP 'request' event (which fires before +// Express routing) and moves the non-standard value to x-content-encoding so +// body-parser sees no encoding and parses the raw bytes normally. +// --------------------------------------------------------------------------- + +const WEB_PUSH_ENCODINGS = new Set(['aesgcm', 'aes128gcm']); + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const _origEmit: (...args: any[]) => boolean = http.Server.prototype.emit; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +http.Server.prototype.emit = function ( + this: any, + event: string, + ...args: any[] +): boolean { + if (event === 'request') { + const req = args[0]; + if (req?.headers) { + const ce: string | undefined = req.headers['content-encoding']; + if (ce && WEB_PUSH_ENCODINGS.has(ce)) { + req.headers['x-content-encoding'] = ce; + delete req.headers['content-encoding']; + } + } + } + return _origEmit.apply(this, [event, ...args]); +}; + +// --------------------------------------------------------------------------- +// Firebase Admin Initialisation (idempotent) +// --------------------------------------------------------------------------- + +if (!admin.apps.length) { + admin.initializeApp(); +} + +const db = admin.firestore(); +const messaging = admin.messaging(); + +const COLLECTION = 'push-relay-registrations'; + +// --------------------------------------------------------------------------- +// CORS (same list used by the rest of the functions) +// --------------------------------------------------------------------------- + +const allowedOrigins = [ + 'https://coho.place', + 'https://coho-mastodon.web.app', + 'http://localhost:3000', + 'https://localhost', // Capacitor Android WebView +]; + +function applyCors( + request: { headers: { origin?: string } }, + response: { set: (key: string, value: string) => void } +) { + const origin = request.headers.origin; + if (origin && allowedOrigins.includes(origin)) { + response.set('Access-Control-Allow-Origin', origin); + } + response.set('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS'); + response.set('Access-Control-Allow-Headers', 'Content-Type, Authorization'); +} + +// --------------------------------------------------------------------------- +// Crypto helpers +// --------------------------------------------------------------------------- + +/** Generate an ECDH P-256 key pair and a 16-byte auth secret. */ +function generateSubscriptionKeys() { + const ecdh = crypto.createECDH('prime256v1'); + ecdh.generateKeys(); + + // Public key in uncompressed format (65 bytes) + const publicKey = ecdh.getPublicKey(); + const privateKey = ecdh.getPrivateKey(); + + // Random 16-byte auth secret + const auth = crypto.randomBytes(16); + + return { + p256dh: publicKey.toString('base64url'), + auth: auth.toString('base64url'), + // Stored server-side only — never sent to the client + privateKeyHex: privateKey.toString('hex'), + authHex: auth.toString('hex'), + }; +} + +// --------------------------------------------------------------------------- +// Web Push Decryption (RFC 8291 — aes128gcm, via http_ece) +// --------------------------------------------------------------------------- + +/** + * Parse a named parameter (e.g. salt=… or dh=…) from an HTTP header value. + * Parameters are separated by ; or ,. + */ +function parseHeaderParam(header: string, param: string): string | null { + const match = header.match( + new RegExp(`(?:^|[;,])\\s*${param}=([^;,\\s]+)`, 'i') + ); + return match ? match[1] : null; +} + +/** + * Decrypt a Web Push payload. + * + * Supports both encryption schemes: + * - **aesgcm** (draft-ietf-webpush-encryption) – used by most Mastodon + * instances. Salt and sender DH key are in the Encryption / Crypto-Key + * request headers. + * - **aes128gcm** (RFC 8291) – salt and key-id are embedded in the payload. + */ +function decryptPayload( + body: Buffer, + privateKeyHex: string, + authHex: string, + contentEncoding: string, + encryptionHeader?: string, + cryptoKeyHeader?: string +): string { + const receiverEcdh = crypto.createECDH('prime256v1'); + receiverEcdh.setPrivateKey(Buffer.from(privateKeyHex, 'hex')); + const authSecret = Buffer.from(authHex, 'hex'); + + if (contentEncoding === 'aesgcm') { + const salt = parseHeaderParam(encryptionHeader || '', 'salt'); + const dh = parseHeaderParam(cryptoKeyHeader || '', 'dh'); + if (!salt || !dh) { + throw new Error( + 'Missing Encryption/Crypto-Key header parameters for aesgcm' + ); + } + const decrypted: Buffer = ece.decrypt(body, { + version: 'aesgcm', + privateKey: receiverEcdh, + dh: Buffer.from(dh, 'base64url'), + salt: Buffer.from(salt, 'base64url'), + authSecret, + }); + return decrypted.toString('utf-8'); + } + + // aes128gcm (RFC 8291) – self-contained payload + const decrypted: Buffer = ece.decrypt(body, { + version: 'aes128gcm', + privateKey: receiverEcdh, + authSecret, + }); + return decrypted.toString('utf-8'); +} + +// --------------------------------------------------------------------------- +// Validate FCM token format (basic sanity check) +// --------------------------------------------------------------------------- +function isValidFcmToken(token: string): boolean { + return ( + typeof token === 'string' && token.length >= 32 && token.length <= 4096 + ); +} + +// --------------------------------------------------------------------------- +// Firebase Functions +// --------------------------------------------------------------------------- + +/** + * POST /pushRelay body: { action: 'register', fcmToken } + * → { registrationId, endpoint, keys: { p256dh, auth } } + * + * DELETE /pushRelay body: { action: 'unregister', registrationId } + * → { success: true } + * + * The push reception endpoint is a *separate* function (pushRelayPush) so Mastodon + * can POST raw encrypted bytes to it. + */ +export const pushRelay = onRequest( + async (request: Request, response: Response) => { + if (request.method === 'OPTIONS') { + applyCors(request, response); + response.status(204).send(''); + return; + } + + applyCors(request, response); + + const action: string = request.body?.action || request.query.action || ''; + + // ── Register ────────────────────────────────────────────── + if (request.method === 'POST' && action === 'register') { + const fcmToken: string = request.body?.fcmToken; + + if (!fcmToken || !isValidFcmToken(fcmToken)) { + response.status(400).json({ error: 'Valid fcmToken is required' }); + return; + } + + try { + const keys = generateSubscriptionKeys(); + const registrationId = crypto.randomUUID(); + + await db.collection(COLLECTION).doc(registrationId).set({ + fcmToken, + p256dh: keys.p256dh, + auth: keys.auth, + privateKeyHex: keys.privateKeyHex, + authHex: keys.authHex, + createdAt: admin.firestore.FieldValue.serverTimestamp(), + }); + + // Build the Web Push–compatible endpoint that Mastodon will POST to. + // The URL is the pushRelayPush function URL. + const projectId = + process.env.GCLOUD_PROJECT || + process.env.GCP_PROJECT || + JSON.parse(process.env.FIREBASE_CONFIG || '{}').projectId || + 'coho-mastodon'; + const region = process.env.FUNCTION_REGION || 'us-central1'; + const endpoint = `https://${region}-${projectId}.cloudfunctions.net/pushRelayPush/${registrationId}`; + + logger.info('Push relay registered', { registrationId }); + + response.json({ + registrationId, + endpoint, + keys: { + p256dh: keys.p256dh, + auth: keys.auth, + }, + }); + } catch (error) { + logger.error('Push relay registration failed', { error }); + response.status(500).json({ error: 'Registration failed' }); + } + return; + } + + // ── Unregister ──────────────────────────────────────────── + if ( + (request.method === 'POST' && action === 'unregister') || + request.method === 'DELETE' + ) { + const registrationId: string = + request.body?.registrationId || request.query.registrationId || ''; + + if (!registrationId) { + response.status(400).json({ error: 'registrationId is required' }); + return; + } + + try { + await db.collection(COLLECTION).doc(registrationId).delete(); + logger.info('Push relay unregistered', { registrationId }); + response.json({ success: true }); + } catch (error) { + logger.error('Push relay unregistration failed', { error }); + response.status(500).json({ error: 'Unregistration failed' }); + } + return; + } + + response.status(400).json({ error: 'Invalid action' }); + } +); + +/** + * Receives incoming Web Push payloads from Mastodon. + * + * Mastodon POSTs encrypted bytes to: + * https://-.cloudfunctions.net/pushRelayPush/ + * + * The non-standard Content-Encoding header (aesgcm) is stripped by the + * http.Server.prototype.emit patch above and saved as x-content-encoding. + */ +export const pushRelayPush = onRequest( + async (request: Request, response: Response) => { + if (request.method !== 'POST') { + response.status(405).send('Method Not Allowed'); + return; + } + + // Extract registrationId from the URL path + const pathParts = request.path.split('/').filter(Boolean); + const registrationId = pathParts[pathParts.length - 1]; + + if (!registrationId) { + response.status(400).send('Missing registrationId'); + return; + } + + try { + const doc = await db.collection(COLLECTION).doc(registrationId).get(); + if (!doc.exists) { + response.status(404).send('Registration not found'); + return; + } + + const data = doc.data()!; + const { fcmToken, privateKeyHex, authHex } = data; + + // Original Content-Encoding saved by the http.Server patch above + const contentEncoding = + (request.headers['x-content-encoding'] as string) || 'aes128gcm'; + + logger.info('Incoming push', { + registrationId, + contentEncoding, + hasEncryptionHeader: !!request.headers['encryption'], + hasCryptoKeyHeader: !!request.headers['crypto-key'], + bodyLength: request.rawBody?.length ?? 0, + }); + + // rawBody is always available on Firebase Functions requests + const rawBody = Buffer.isBuffer(request.rawBody) + ? request.rawBody + : Buffer.from(request.rawBody || ''); + + let decryptedJson: string; + try { + decryptedJson = decryptPayload( + rawBody, + privateKeyHex, + authHex, + contentEncoding, + request.headers['encryption'] as string | undefined, + request.headers['crypto-key'] as string | undefined + ); + } catch (decryptError) { + logger.error('Failed to decrypt push payload', { decryptError }); + response.status(201).send('Accepted (decrypt failed)'); + return; + } + + let payload: Record; + try { + payload = JSON.parse(decryptedJson); + } catch { + logger.error('Decrypted payload is not valid JSON', { + decryptedJson: decryptedJson.substring(0, 200), + }); + response.status(201).send('Accepted (invalid JSON)'); + return; + } + + const title = String(payload.title || 'Coho'); + const body = String(payload.body || 'You have a new notification'); + + // FCM data values must all be strings — stringify everything + const fcmData: Record = {}; + for (const [key, value] of Object.entries(payload)) { + fcmData[key] = + typeof value === 'string' ? value : JSON.stringify(value); + } + // Ensure required keys exist + fcmData.title = title; + fcmData.body = body; + + await messaging.send({ + token: fcmToken, + notification: { + title, + body, + }, + data: fcmData, + android: { + priority: 'high', + notification: { + channelId: 'PushDefaultForeground', + }, + }, + }); + + logger.info('Push relayed to FCM', { + registrationId, + type: payload.notification_type, + }); + response.status(201).send('Created'); + } catch (error) { + logger.error('Push relay delivery failed', { error }); + + if ( + error instanceof Error && + (error.message.includes('not-registered') || + error.message.includes('invalid-registration-token')) + ) { + await db.collection(COLLECTION).doc(registrationId).delete(); + logger.info('Cleaned up stale registration', { registrationId }); + } + + response.status(500).send('Relay failed'); + } + } +); diff --git a/package-lock.json b/package-lock.json index 9318067..5763e05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@capacitor/app": "^8.0.1", "@capacitor/browser": "^8.0.2", "@capacitor/core": "^8.2.0", + "@capacitor/push-notifications": "^8.0.2", "@huggingface/transformers": "^4.0.0-next.2", "@lit-labs/compiler": "^1.1.2", "@lit-labs/virtualizer": "^2.1.1", @@ -236,6 +237,15 @@ "tslib": "^2.1.0" } }, + "node_modules/@capacitor/push-notifications": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@capacitor/push-notifications/-/push-notifications-8.0.2.tgz", + "integrity": "sha512-mej8Eh4EU4JXbaeyMX2l+4NNK6IdY5iRsEXpBOTHLD29fuCACBP7kOJTiJv6piw134zdlbFH0rR+sDKHIiFOFg==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=8.0.0" + } + }, "node_modules/@emnapi/runtime": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", diff --git a/package.json b/package.json index a8be87e..3e0bfa7 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@capacitor/app": "^8.0.1", "@capacitor/browser": "^8.0.2", "@capacitor/core": "^8.2.0", + "@capacitor/push-notifications": "^8.0.2", "@huggingface/transformers": "^4.0.0-next.2", "@lit-labs/compiler": "^1.1.2", "@lit-labs/virtualizer": "^2.1.1", diff --git a/scripts/test-push.mjs b/scripts/test-push.mjs new file mode 100644 index 0000000..e3d425d --- /dev/null +++ b/scripts/test-push.mjs @@ -0,0 +1,54 @@ +/** + * Quick script to send a test FCM push notification. + * Run with: node scripts/test-push.mjs + * + * Requires: GOOGLE_APPLICATION_CREDENTIALS env var pointing to a + * Firebase service account key JSON file, OR run from a machine + * authenticated with `gcloud auth application-default login`. + */ + +import { initializeApp, cert, getApps } from 'firebase-admin/app'; +import { getMessaging } from 'firebase-admin/messaging'; + +// ── Config ────────────────────────────────────────────────────── +// Paste the FCM token from your device/emulator logs here: +const FCM_TOKEN = + 'cwLimXX-QJ2ku6R8dtYZQr:APA91bEZ-NHZIEph_KKpEamRXC0GvsdHnIUdLm2GKzAreL5m3VDx616oz5sE9ET6aTbIheKo0AGrSGIPHYnOXA2R0oDtzI6dOU4PvIweA2SclEg5rSkDcgk'; + +// ── Init Firebase Admin ───────────────────────────────────────── +if (!getApps().length) { + initializeApp({ projectId: 'coho-mastodon' }); +} + +// ── Send test message ─────────────────────────────────────────── +// This mimics the exact data payload the push relay sends after +// decrypting a Mastodon Web Push notification. +const message = { + token: FCM_TOKEN, + data: { + title: 'Test User mentioned you', + body: 'Hey! This is a test notification from the push relay.', + notification_id: '12345', + notification_type: 'mention', + icon: '', + access_token: '', + preferred_locale: 'en', + }, + android: { + priority: 'high', + }, +}; + +try { + const messageId = await getMessaging().send(message); + console.log('✅ Message sent successfully:', messageId); +} catch (error) { + console.error('❌ Failed to send:', error.message); + if (error.message.includes('credential')) { + console.log( + '\nMake sure you are authenticated. Run:\n' + + ' gcloud auth application-default login\n' + + 'Or set GOOGLE_APPLICATION_CREDENTIALS to a service account key.' + ); + } +} diff --git a/src/app-index.ts b/src/app-index.ts index 6a4a374..add0fcd 100644 --- a/src/app-index.ts +++ b/src/app-index.ts @@ -98,6 +98,16 @@ export class AppIndex extends LitElement { requestIdleCallback(() => import('./components/pwa-update'), { timeout: 5000, }); + } else { + // Initialize native push notification listeners (FCM via Capacitor) + requestIdleCallback( + async () => { + const { setupNativePushListeners } = + await import('./services/push-native.js'); + setupNativePushListeners(); + }, + { timeout: 5000 } + ); } } diff --git a/src/components/notifications.ts b/src/components/notifications.ts index 3752763..eef5078 100644 --- a/src/components/notifications.ts +++ b/src/components/notifications.ts @@ -654,11 +654,18 @@ export class Notifications extends LitElement { await scheduler.yield(); } // check push reg - const reg = await navigator.serviceWorker.getRegistration(); - if (reg && reg.pushManager) { - const sub = await reg.pushManager.getSubscription(); - if (sub) { - this.subbed = true; + const { isNativePlatform } = await import('../utils/platform.js'); + if (isNativePlatform()) { + const { isNativePushSubscribed } = + await import('../services/push-native.js'); + this.subbed = isNativePushSubscribed(); + } else { + const reg = await navigator.serviceWorker.getRegistration(); + if (reg && reg.pushManager) { + const sub = await reg.pushManager.getSubscription(); + if (sub) { + this.subbed = true; + } } } diff --git a/src/services/notifications.ts b/src/services/notifications.ts index 7c9b090..d5dcaa3 100644 --- a/src/services/notifications.ts +++ b/src/services/notifications.ts @@ -42,6 +42,13 @@ function urlBase64ToUint8Array(key: string) { } export const subToPush = async () => { + // On native Capacitor platforms, delegate to the FCM-based flow + const { isNativePlatform } = await import('../utils/platform.js'); + if (isNativePlatform()) { + const { subToPushNative } = await import('./push-native.js'); + return subToPushNative(); + } + const registration = await navigator.serviceWorker.getRegistration(); let vapidKey: string | undefined; @@ -264,6 +271,13 @@ export const modifyPush = async (options: { }; export const unsubToPush = async () => { + // On native Capacitor platforms, delegate to the FCM-based flow + const { isNativePlatform } = await import('../utils/platform.js'); + if (isNativePlatform()) { + const { unsubToPushNative } = await import('./push-native.js'); + return unsubToPushNative(); + } + // get push subscription const registration = await navigator.serviceWorker.getRegistration(); const subscription = await registration?.pushManager.getSubscription(); diff --git a/src/services/push-native.ts b/src/services/push-native.ts new file mode 100644 index 0000000..3cb73f5 --- /dev/null +++ b/src/services/push-native.ts @@ -0,0 +1,351 @@ +/** + * Native Push Notifications (Capacitor Android) + * + * Uses @capacitor/push-notifications for FCM token management and a + * Firebase Function relay to bridge Mastodon's Web Push to FCM. + * + * The relay presents a standard Web Push endpoint to Mastodon, so the + * Mastodon API call is identical to the PWA flow — only the subscription + * source differs. + */ + +import { PushNotifications } from '@capacitor/push-notifications'; +import { getClientConfig } from '../mastodon/config/client'; + +// --------------------------------------------------------------------------- +// Relay Configuration +// --------------------------------------------------------------------------- + +/** + * Base URL for the push relay Firebase Functions. + * In production this points to the deployed Cloud Function; during local + * development you can override via localStorage for testing with the emulator. + */ +function getRelayBaseUrl(): string { + return ( + localStorage.getItem('pushRelayBaseUrl') || + 'https://us-central1-coho-mastodon.cloudfunctions.net' + ); +} + +// --------------------------------------------------------------------------- +// Storage keys +// --------------------------------------------------------------------------- + +const RELAY_REGISTRATION_ID_KEY = 'pushRelayRegistrationId'; +const FCM_TOKEN_KEY = 'pushRelayFcmToken'; + +// --------------------------------------------------------------------------- +// Subscribe +// --------------------------------------------------------------------------- + +/** + * Subscribe to push notifications on a native Capacitor platform. + * + * 1. Requests notification permission + * 2. Gets an FCM token from the OS + * 3. Registers with the push relay → gets a Web Push–compatible endpoint + * 4. Sends that endpoint to Mastodon via POST /api/v1/push/subscription + */ +export async function subToPushNative(): Promise { + console.log('[NativePush] Starting subscription...'); + + // 1. Request permission + let permResult = await PushNotifications.checkPermissions(); + console.log('[NativePush] Permission status:', permResult.receive); + + if (permResult.receive === 'prompt') { + permResult = await PushNotifications.requestPermissions(); + console.log('[NativePush] Permission after request:', permResult.receive); + } + if (permResult.receive !== 'granted') { + throw new Error('Push notification permission denied'); + } + + // 2. Register with the OS and get the FCM token. + // Await the addListener calls so Capacitor has fully wired them + // before we call register(). + const fcmToken = await new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + console.error('[NativePush] FCM registration timed out after 15s'); + reject(new Error('FCM registration timed out')); + }, 15_000); + + let settled = false; + + const setup = async () => { + await PushNotifications.addListener('registration', (token) => { + if (settled) return; + settled = true; + clearTimeout(timeout); + console.log('[NativePush] FCM token received'); + resolve(token.value); + }); + + await PushNotifications.addListener('registrationError', (err) => { + if (settled) return; + settled = true; + clearTimeout(timeout); + console.error('[NativePush] FCM registration error:', err); + reject(new Error(err.error || 'FCM registration failed')); + }); + + console.log('[NativePush] Listeners ready, calling register()...'); + await PushNotifications.register(); + console.log('[NativePush] register() returned'); + }; + + setup().catch((err) => { + if (!settled) { + settled = true; + clearTimeout(timeout); + reject(err); + } + }); + }); + + localStorage.setItem(FCM_TOKEN_KEY, fcmToken); + console.log('[NativePush] FCM token stored, registering with relay...'); + + // 3. Register with the relay + const relayUrl = `${getRelayBaseUrl()}/pushRelay`; + console.log('[NativePush] Registering with relay...'); + + let relayResponse: Response; + try { + relayResponse = await fetch(relayUrl, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ action: 'register', fcmToken }), + }); + } catch (fetchErr) { + console.error('[NativePush] Relay fetch failed:', fetchErr); + throw fetchErr; + } + + console.log('[NativePush] Relay response status:', relayResponse.status); + + if (!relayResponse.ok) { + const errBody = await relayResponse.text().catch(() => ''); + console.error('[NativePush] Relay error body:', errBody); + throw new Error(`Push relay registration failed: ${relayResponse.status}`); + } + + const relay: { + registrationId: string; + endpoint: string; + keys: { p256dh: string; auth: string }; + } = await relayResponse.json(); + + localStorage.setItem(RELAY_REGISTRATION_ID_KEY, relay.registrationId); + + // 4. Register the Web Push–compatible subscription with Mastodon + const { url, accessToken } = getClientConfig(); + + const mastodonResponse = await fetch( + `https://${url}/api/v1/push/subscription`, + { + method: 'POST', + headers: { + 'Authorization': `Bearer ${accessToken}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + subscription: { + endpoint: relay.endpoint, + keys: { + p256dh: relay.keys.p256dh, + auth: relay.keys.auth, + }, + }, + data: { + alerts: { + follow: true, + reblog: true, + favourite: true, + mention: true, + poll: true, + follow_request: true, + status: true, + update: true, + }, + policy: 'all', + }, + }), + } + ); + + if (!mastodonResponse.ok) { + throw new Error( + `Mastodon push subscription failed: ${mastodonResponse.status}` + ); + } + + console.log('[NativePush] Subscribed via relay', relay.registrationId); +} + +// --------------------------------------------------------------------------- +// Unsubscribe +// --------------------------------------------------------------------------- + +export async function unsubToPushNative(): Promise { + const registrationId = localStorage.getItem(RELAY_REGISTRATION_ID_KEY); + const { url, accessToken } = getClientConfig(); + + // Delete from Mastodon + try { + await fetch(`https://${url}/api/v1/push/subscription`, { + method: 'DELETE', + headers: { + 'Authorization': `Bearer ${accessToken}`, + 'Content-Type': 'application/json', + }, + }); + } catch { + console.log('[NativePush] Mastodon unsub failed (may already be gone)'); + } + + // Delete from relay + if (registrationId) { + try { + await fetch(`${getRelayBaseUrl()}/pushRelay`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + action: 'unregister', + registrationId, + }), + }); + } catch { + console.log('[NativePush] Relay unsub failed'); + } + localStorage.removeItem(RELAY_REGISTRATION_ID_KEY); + } + + localStorage.removeItem(FCM_TOKEN_KEY); + + await PushNotifications.removeAllListeners(); + console.log('[NativePush] Unsubscribed'); +} + +// --------------------------------------------------------------------------- +// Check subscription status +// --------------------------------------------------------------------------- + +export function isNativePushSubscribed(): boolean { + return !!localStorage.getItem(RELAY_REGISTRATION_ID_KEY); +} + +// --------------------------------------------------------------------------- +// Notification target URL routing (mirrors src/sw/notifications.ts) +// --------------------------------------------------------------------------- + +function getTargetUrl(data: Record): string { + if (!data?.notification_type || !data?.notification_id) { + return '/home?tab=notifications'; + } + + switch (data.notification_type) { + case 'mention': + case 'reblog': + case 'favourite': + case 'poll': + case 'status': + case 'update': + return `/post/notification?notification_id=${data.notification_id}`; + case 'follow': + case 'follow_request': + case 'admin.sign_up': + case 'admin.report': + return '/home?tab=notifications'; + default: + return '/home?tab=notifications'; + } +} + +// --------------------------------------------------------------------------- +// Setup Listeners (call once at app startup on native) +// --------------------------------------------------------------------------- + +/** + * Attach listeners for incoming FCM push notifications and user taps. + * Also handles FCM token refresh by re-registering with the relay. + */ +export function setupNativePushListeners(): void { + // Foreground notification received + PushNotifications.addListener('pushNotificationReceived', (notification) => { + console.log('[NativePush] Foreground notification received'); + + const data = notification.data as Record | undefined; + if (!data) return; + + // Broadcast to the app — same message shape the service worker uses + // so components like conversation-thread can react + window.postMessage( + { + type: 'push-notification', + notificationType: data.notification_type, + notificationId: data.notification_id, + }, + '*' + ); + }); + + // User tapped a notification + PushNotifications.addListener( + 'pushNotificationActionPerformed', + async (action) => { + console.log('[NativePush] Notification tap'); + + const data = action.notification.data as + | Record + | undefined; + const targetUrl = getTargetUrl(data || {}); + + // Lazy-import router to avoid circular dependencies + const { router } = await import('../router/routes'); + router.navigate(targetUrl); + } + ); + + // FCM token refresh — re-register with relay + update Mastodon subscription. + // Only acts when the user already has an active relay registration AND the + // token actually changed (guards against the initial registration event + // firing into this listener during subToPushNative). + PushNotifications.addListener('registration', async (token) => { + const previousToken = localStorage.getItem(FCM_TOKEN_KEY); + const registrationId = localStorage.getItem(RELAY_REGISTRATION_ID_KEY); + + // Skip if this is the initial registration (no relay yet) or token unchanged + if (!registrationId || token.value === previousToken) return; + + console.log('[NativePush] FCM token refreshed, re-registering'); + + // Clean up old relay registration + if (registrationId) { + try { + await fetch(`${getRelayBaseUrl()}/pushRelay`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + action: 'unregister', + registrationId, + }), + }); + } catch { + // Best effort + } + localStorage.removeItem(RELAY_REGISTRATION_ID_KEY); + } + + // Re-subscribe with the new token + try { + await subToPushNative(); + } catch (err) { + console.error( + '[NativePush] Re-registration after token refresh failed', + err + ); + } + }); +} diff --git a/vite.config.ts b/vite.config.ts index f24898c..8566aff 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -250,8 +250,9 @@ export default defineConfig({ terserOptions: { module: true, compress: { - drop_console: true, + drop_console: false, drop_debugger: true, + pure_funcs: ['console.log'], // Strip console.log but keep warn/error passes: 2, arrows: true, booleans_as_integers: true, From 08de033e45918ed41da1cf65fe1c001a80b4b686 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Sun, 15 Mar 2026 22:43:54 -0700 Subject: [PATCH 05/26] android icons --- android/app/src/main/AndroidManifest.xml | 8 ++++++++ android/app/src/main/ic_launcher-playstore.png | Bin 0 -> 79314 bytes .../main/res/drawable-hdpi/ic_action_name.png | Bin 0 -> 662 bytes .../src/main/res/drawable-hdpi/ic_stat_name.png | Bin 0 -> 540 bytes .../main/res/drawable-mdpi/ic_action_name.png | Bin 0 -> 463 bytes .../src/main/res/drawable-mdpi/ic_stat_name.png | Bin 0 -> 377 bytes .../main/res/drawable-xhdpi/ic_action_name.png | Bin 0 -> 879 bytes .../main/res/drawable-xhdpi/ic_stat_name.png | Bin 0 -> 742 bytes .../main/res/drawable-xxhdpi/ic_action_name.png | Bin 0 -> 1423 bytes .../main/res/drawable-xxhdpi/ic_stat_name.png | Bin 0 -> 1191 bytes .../res/drawable-xxxhdpi/ic_action_name.png | Bin 0 -> 1970 bytes .../main/res/drawable-xxxhdpi/ic_stat_name.png | Bin 0 -> 1726 bytes .../main/res/mipmap-anydpi-v26/ic_launcher.xml | 1 + .../res/mipmap-anydpi-v26/ic_launcher_round.xml | 1 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 2786 -> 0 bytes .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 2178 bytes .../res/mipmap-hdpi/ic_launcher_foreground.png | Bin 3450 -> 0 bytes .../res/mipmap-hdpi/ic_launcher_foreground.webp | Bin 0 -> 3542 bytes .../res/mipmap-hdpi/ic_launcher_monochrome.webp | Bin 0 -> 3872 bytes .../main/res/mipmap-hdpi/ic_launcher_round.png | Bin 4341 -> 0 bytes .../main/res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 3926 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 1869 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 1418 bytes .../res/mipmap-mdpi/ic_launcher_foreground.png | Bin 2110 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_foreground.webp | Bin 0 -> 2024 bytes .../res/mipmap-mdpi/ic_launcher_monochrome.webp | Bin 0 -> 2304 bytes .../main/res/mipmap-mdpi/ic_launcher_round.png | Bin 2725 -> 0 bytes .../main/res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 2438 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 3981 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 3112 bytes .../res/mipmap-xhdpi/ic_launcher_foreground.png | Bin 5036 -> 0 bytes .../mipmap-xhdpi/ic_launcher_foreground.webp | Bin 0 -> 5468 bytes .../mipmap-xhdpi/ic_launcher_monochrome.webp | Bin 0 -> 5726 bytes .../main/res/mipmap-xhdpi/ic_launcher_round.png | Bin 6593 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 5792 bytes .../src/main/res/mipmap-xxhdpi/ic_launcher.png | Bin 6644 -> 0 bytes .../src/main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 4918 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 9793 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_foreground.webp | Bin 0 -> 9942 bytes .../mipmap-xxhdpi/ic_launcher_monochrome.webp | Bin 0 -> 10934 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 10455 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 9796 bytes .../src/main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 9441 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 7400 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 15529 -> 0 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.webp | Bin 0 -> 16546 bytes .../mipmap-xxxhdpi/ic_launcher_monochrome.webp | Bin 0 -> 18554 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 15916 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 14286 bytes android/app/src/main/res/values/colors.xml | 5 +++++ .../main/res/values/ic_launcher_background.xml | 2 +- functions/src/push-relay.ts | 3 ++- 52 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 android/app/src/main/ic_launcher-playstore.png create mode 100644 android/app/src/main/res/drawable-hdpi/ic_action_name.png create mode 100644 android/app/src/main/res/drawable-hdpi/ic_stat_name.png create mode 100644 android/app/src/main/res/drawable-mdpi/ic_action_name.png create mode 100644 android/app/src/main/res/drawable-mdpi/ic_stat_name.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_action_name.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_stat_name.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/ic_action_name.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/ic_stat_name.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/ic_action_name.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/ic_stat_name.png delete mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher.webp delete mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp create mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.webp delete mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp delete mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher.webp delete mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp create mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.webp delete mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp delete mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp delete mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp create mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.webp delete mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp delete mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp delete mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp create mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.webp delete mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp delete mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp delete mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp create mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.webp delete mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 android/app/src/main/res/values/colors.xml diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 3d018d9..0e6d13d 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -41,6 +41,14 @@ android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"> + + + + diff --git a/android/app/src/main/ic_launcher-playstore.png b/android/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..56c78c212326112d9e6320badbe53477fd952f7a GIT binary patch literal 79314 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
    b^|>qqM83lf%^`{){0* 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 beL3PIj@mTT{3v$^z~40k6a6AxOxXVc@H!x= literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-hdpi/ic_action_name.png b/android/app/src/main/res/drawable-hdpi/ic_action_name.png new file mode 100644 index 0000000000000000000000000000000000000000..427eaa60815f2e816fb8d95c80013b2631c0047b GIT binary patch literal 662 zcmV;H0%`q;P)3 z(7vfwt9kGlu9xxbhs0hXVs_QT3iW#Zj*3PlM(qMjtA`b8wb~;Uj!Go6s`}R8bf|Dd z9$~s}slGKJG8-apO{}*UkaKZ81I@eYV+;)QqKexR8f_#r&jrnOgf^u<#(?0G8pPz9 zdKiO43m%7vMk4DHYT0%5F$M(IRWu5rbB?Kc$D*np#wZjDw<)CJHbnn3B=QNB`=RPv z1446ZU`q5oWCdqYRo%$&w}HRR1`)};$JC6gUTkov)y#x=kteD(6tK*zSs!-5FaC8a z>?FW71ig*8U)ZY<^DAVL!{UFA*a?m(+WV@5WESxIDdP8?IL8j|%9?-@MxV7`4;(3I zd<-Q2L1S#;Lgbq!AqoBBn&BxB_bWV@u_Keg{aP>6kKm^@-OCE>45oX_46G;lMS%uRj( w`VckhDMu_Y#TkwHC*Xqa6;OSaAi;l)-$lXfFY?vCDgXcg07*qoM6N<$f_%U*3jhEB literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-hdpi/ic_stat_name.png b/android/app/src/main/res/drawable-hdpi/ic_stat_name.png new file mode 100644 index 0000000000000000000000000000000000000000..f862f62e2a213b2a2228852c4c7c8cc748bd78ad GIT binary patch literal 540 zcmV+%0^|LOP)HiJKl;gvxV z1|9V}&b^;=y?gF)v$8@$LjE}-QU;sh5FCa5Fo%yb29YAz z1Uq4?Gf5SU(s2>zxLJ4rUnHFx_c>M|GRakkM|cPq;5@wW4ySPpbGdH}B8yzM;0-o& z+X{p>xNgBJcdbEekL!lq!Aj9<%(L#SKqTqOo1t!%dcxF$un!a5HwKY=&lKidIX`b; zjQd6)&>{M-^ve@$;YqsQo67JAom3G5*9kTy{Rse9?%*P1w$3#vrntn)Mr=VI$0kgD^tp zw}@WYYTKxGk6D38;$!Ns*>N3PAg;B8&wZjVSdmQq-WLd!z)L6k9ZPUZ^e!BC&g+4% zu4C3HZ4Y8ylG#qJ9)NMt|F<4!Y?`~i5WPN9U%w4g-1H5i4RBX7`?i?iZW)7k9UOrx zqHoiQ=!;bEOfk{#J#*rHpH}-*DYpU#la#{>(J%hPG*%C{+?X!wOp63O%T5St~ei(+UtyXKCeU(aO zlx^^75Cqr0@4w^wf&WkFE(U z<=9ll;2VYH8I^Xya!rzCL?KqO5)_nY-Vu!*NKq6`D=anhjKjQxA9>l*7#=M8y)4Hn zZWo}Q!p#JGSos1{vzCs>O__{ia;ySq z7D3&-NlcnL=8gJ#G8m(rLN%Msm7m;&IF4tO(O2zudkp#BHRagj>dj8h@cS^x?DE%D zm5Nov0|s~pl{U{dRvh0fO!xv{YRsPrlTN_P+CJ1k`UF}N<(Vc&CN}^8002ovPDHLk FV1g^|(>MSC literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-mdpi/ic_stat_name.png b/android/app/src/main/res/drawable-mdpi/ic_stat_name.png new file mode 100644 index 0000000000000000000000000000000000000000..81240a56b177094d62c4ea7f52279dbdec374afb GIT binary patch literal 377 zcmV-<0fzpGP)4hVT;U{6Xs8rA3avz<(Of}ENiCwgs5Gi8bQ;%F_yY=|xnH2C5FsR@6ACe& z$$lGiZ+2%$RB})9WV1Wp`(}4GQ>pa%7dYppaTynNEee4J+%vbaiIZ5zH9Wyb_ss{6 zXiq5&9|z%_Pkh&hMn^lM5IEO{2+ugK9Z?8eX-kAH+{9V!DTU!DDT(3##XXK{PazC$ zNI{A_oY$U07_8#86qNCTZER>yDGbj@NfCZK{JsxsJ_(^EDJx=MGPUqN3d3{SX842T z|IH;%*{t8r9qejPDGU#}-V>U0X6qAn9l(yQwR>9a zC@4tL)Q%rPa0M^$Ehu}yQ@iH0H2W(ksNt%)YtQ^P9pEe8;GpLI1d7L8_N7%_>yzXQ X<}KawSJ=~700000NkvXXu0mjf2cn`! literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_action_name.png b/android/app/src/main/res/drawable-xhdpi/ic_action_name.png new file mode 100644 index 0000000000000000000000000000000000000000..f534d4b52c19d71bf9df52af2e7c5e6b2c86d730 GIT binary patch literal 879 zcmV-#1CacQP)X7N>4yr6Xa$u*v4vt0m4?=es1U5L`foi) zHZq)S9%g1skv(wOP4><`cV_R*+?_-sMvNFSV*C%tWHS3orPBFAp-{zjlC0HgN7QcH zAeYM>0Y#{?ZJ<1XZUaf1o1LNtc$SwieO*i{vLzI?@hHCz@}l*{F# zs_P7JeojThIKqVeLv-Lab<*kd0WPsvYA&H>jh-t%;L&dGZ$vbR7lE<4vwrgY5n;4{Bs_g^_;&F(mH4*R{a{W3tNY!)+rq2fz zx8x#xUTw8nJ5h%VK|u{OXSuQ%?gKg`CW&GEb?0 z6G2M3E#!jjy(^$WC%F>YJc{w3+QJx3C>o8*9MvYYlP$r`1Oo>h=0z-}pwx{ilTM6e8ff84_eDIg&_+ zlj=i(H*#E;XS98)c22<853vmmwhz}?jB$j6dC)df2<5^t4L;xvQ`adF$juPJE*iPa zvz~83IkD35<9XixVvmCX*kw#jr{EF?fdv&Ek~|1lWJzM?ywZ6Itq4BqmsHplBdJ6c z{7S+|&Ty$T#XG5ELoB@)RWCBI#6TzJv?IOPnG^l&{otd1OTmL$h);mC+^~W`8PMMY zFua{R+^}fR6{y!-Lfh3XsZjfY^$wR#E}OVM;D|Hj#4L#kTf(#VA)Ro05@8DjG}h~M zf&XLEo8-tFZ)-vAwmq0OJj6oqQ|QDMeI6r5j2JN@!Ed6>R&eY$Due(4002ovPDHLk FV1l5)p)vpf literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_stat_name.png b/android/app/src/main/res/drawable-xhdpi/ic_stat_name.png new file mode 100644 index 0000000000000000000000000000000000000000..c354befd988268db714c3145b1708b55a314d389 GIT binary patch literal 742 zcmV_vyXwy>svLUKZz9zh>@z&-?t(xij~CylriXL?V$$BpOFV zX5wnxizo34Ud0idVcWYxz$~1P%di*cYKLsQ7_PTtA0EP6_*ts6(cbR{#dqKrn<$|} zFYqRw!dN8w(4jDG)yeKy+#3U7#l%3{CGb%Da2_|&F3qU*)5&2@v~2W(;urt-yph1+bV z8x)@|VUekYb~^5OtwFrSqu6aTT_Iqt32v4LxJSxfbtfQb$aJ6)^sk}2(9Jl_W|Rtn z=PLWs5NB-NmO=PM+nWX$vUOVq;bXQpb?`_g4=tZ?fvu}ZSltJutkqYc_>rt5_3{$u z;XVl~_ikHL;r-coExYHgz3v9Zw`3vppdDTp-8(0)H39E0k;;Yfux;apgai18D6EM4 zQe&3k`bvCf?(4VhTp{4N2`oYnJ^C+n5MSfYsLl#}A2*h84(^Qe+##S_!lAv0c;(f- zjlS01<)1@3KYJv<#$%gT3KCZ2qQ@cC&{;@lCH-sUF>bR;gRo5!_As8bZU72_i}1SC z-mKM&?nXOoPU#TZkLR-vR70J;g+;qrdy~yVfB*%g9s(hyh(^#hP$DQ*Mb#n@Ahv>Dl#o)I zQvNOPWo>ElGWL$0#N$@;q$k_6-+X@G=kXl2cVr|WARr(hARr(hARr(h4-*p;56#TX zJlAfwdvP3p)ai6SOF1<)br5CuYn|H~&1UoQ$;rvrkbut-{JAKK{=xo#S%l3g_2C8c z^YeE?%vht*co0|f$!@p%1g{>;$bP?nht_cc>rPKkw~&Yh1biOH|7sHQh*TEfXgb*5P1{)9X3DWc#*dP7$r&EAfAcE?J))0CG7vL{)!Owe^LLH0s?k30V>Ru zsQ)Ln-@(TLFvk8DD7(5DpDB|IGozX-MXS|%N`)0=5{Oemir691XUg8%TLuVes<>fv z4RSMNU&X#q^;Qma6>qAzEZP!dD=YGQ7E$kzYV`sLc}K;G(6s=|25RFlUuZp-FdcY6 zwR!=>99Ds@fovmRSDoGfF^d*~-iTZN3}lU}PH%vyZ%u(ZB5idm%JavL83}sE)Q7p& z4o+gtvPuC_zo}3c<^@`mhObWzU1KOefU@gYntW(#t`rb*K?PS$CI~u~xo}OEJP~Km z#_yk~?n=<>_3nd!l`^fNOdVT&W4qKDEMTvgcD(JdmU~{cR{}KMN6H3Twq8-4NI61aot9cR|EYDynD@+r?<`m}9rS~& zn9Pvp*pgM7cO=vJODcN1$%MDt?UUHP?EMjH9yoJW@p*JTV?IfoYs-f1XIzfDSs2XYwh;C~TN}bQR+)nIkEM-@) z-n&;d~U3+8>~gMeciY#GAOQT6SL@$vC{SYLgT$oZt&R|;Nb6;+h%l*{%L?6^_?wE8ss z`hBC?Xf*ED4%J3&`WBwxQ%Tb|gX;{|SudL9DUz0R*5Yf8vF~qzQlJ^{RdFUYIeKjH zdjz#B9(*vx?+LFa_DgzBCWmiLEj~;xYCSJNAY%~Iw+I|cO%_KoaM>)!ao0Q_2M3qF z5B2t&^}GUC^96{yt|Et#iO?jOzahvQ^v$_VGSqXl`dDpk^xi=$q9LEY(7&TusOF0Rg$y$*>VE`M7GTC737<)!-=(<7ogcNrKH~28#WC z;Cnd!06ug)byC1?7wUYaNfGvS33E$=lfd+u54Y&MI!M6Dj>8wK z$pg02S+{KD`|k&J0TMBeM19lQIHRw}nyfD9^?EzGfJVYjAYng)d( literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_stat_name.png b/android/app/src/main/res/drawable-xxhdpi/ic_stat_name.png new file mode 100644 index 0000000000000000000000000000000000000000..16cc629bfcbf1f7d97c09485a4bf893cfb059f29 GIT binary patch literal 1191 zcmV;Y1X%ltP)2jUeUX`>nMhjTv27qpbR&p`B6!FH1?ok5LF!B8(~9<&R(-I}@>ze0W4s~2Eopjf4gqIp$+@`DmAVV~ZBnbGVng)+g+ z!ZD~D`}79P%wUHJaB%p#EPq22*rQiq=nZxmLyhgnGC*;B2Q{A`)O$UBhaf*7xw54u_aI) zh~*`302-k!W{=o1Y;~43B4BEwq*pfWc@cCn`YF^RRcbK|%&n^T-R}GZEr~oq24gz1tp=pNme|HLC{AaFB2^t0KKJ+aAcc(zwHb9N| zL8{ylCjsM^xi%#^%{L^+>LAj-0DTRu;%8ofk#FkjQi`vjX0dggh@+CBV@8_pV!OG~ zYQjEF;{_P`JgP}aG!PG_2l#ysx+J#S`ZWJ1BetZfgGHBjIGq<@WC0l~f^Joh>mJwh@^FV7M>R*?Fg9J1 zU$sWW1t~(y)2*b7(9QZs4e7()DudWjIej&Jp~0?hfD{; ziddhtyWV>%alweYSCnz=r;@;ESFwIcw}Z44`cG`F3Nk7dv^6_wTiCi^bum4m0N1Th+{w0mGeCkhz0HCEEN$}s08LapuoQ1a#S<$a)@HM_*(7qfrJ@2sQz;{$6dx#45U(=eS)imi5(CJkfc{(G zBQsRz(K9>Ou02b?s#mi!eZJQ{J>7Hcz<`H`hlhuUhlhuUhlhuUhlhuUhlhuUN3St7 zH1x>m=;($%C*Jyf=jDV5P!^kn1dH~zg*j|R||6u!X z92ricp+3|6JUXCOt33?kMq&IR7=8h~p$4ZV(*DtIx9`(3oCQzW@$vCj>h=2D5U>?K zypQdt=uP{u-3_)G26HCZE4OXi_Bgg{H*VbcfaaAJGcz;yB9Hap9_0U%nplLW_i|;1 zA(;9ydyI-mVsxs5myq^2ILAiAw$W;}o{Z~#3kwVPa2!XxDe(7BLrPvk)3;i-vw#WH zDxe5yYOpe9e}ms2;`d81N0XiAfDLil7BtpXtOrtleIOl;L^B^jJK?T`Z zmRV_-bavSoUU&yppYsTp`!`jP$*g8%VHx@I!ppUXYO4gW{C`me6=4~Mre)MIxBygL zl>u)*s4!EY9_tm;md%A-P?cK_HUuko8}ATiGax!3{r)%6W&K}k498l5uvKpWlG|m7%f{dL$a~J~G zsb1%R%AP38{Ic?im^Z&LU0by}2R@NPMHf_n2q|jB9mmtKNLuv#uc%G+ItNs?T|}sj zW#yN*@e%)2k;kMxLpW==q5?!rCh`9_q2~3X4d@BLH?LVo|jSMB{gE) z@lN5;akN&eJ)`=Z2P!|WVmgUUVj6>!!sBR*&xIFy{15ed{SDPs32=tc$nbiI&4euB zWfAqh#<@LTAX8110t|as#U-(b!9~&CKN4R;P@%!0BI2K~aX9)pz+@HFgN-q}xhH+Kx?FGu;|_gRhS9Ez?3vXJIXOiVn% za{0bK3_Bi$;r9)Mk8AzXfDMW~4yz9AAJn+c0fsze_L^=H24BH&_nKKYKN&*U0>Um} zxM-STX~BgW(x1`tNa(6*d?#V{#BPv1vkPx34 zd{^d-gn4oHhJ3GUxdy-1bk1UIZ0uPTqvL5_GT$=q=Y$vAnH2TgscD@?Gsj;7q%a{` zGwjv!@&e|6Zk8KY2ff}nk8lcS6=P$LxVr{qe$O$wvGOqJ9DXnHt9dhA(F|W0*8G)> zqiL%EeifPOtq3(C+SjcT`OopqsfNBlc+Y6nH@9j| zTv(5}pmpyn@TnDyK8VJ+s^W_@K(KN{kQe@2wB?_cmH8^B2*NeP82BZ)7?~e;CfJUJ z$4~K3m5|4J^PjEwU>)I~G%X9UxV((;yXVacg13pozqr{-(_p~&;3d;2F7UuVwV@bq zAm%m%!M7xu8SmC2&*jQ|p42UH28Bi4t)YrW^BTfu15L{}$eli};6#9*9R(Tw#S7f7 z`P`L&@sGlk7ERL|W z{O_LwL5Ha^|JPd6dX$K8nA;1p&zsj9<1CogG#*_5hqdrK=fgNFPO~wvUE*J_X0~l*z-x!^6YF!^6YF!^6YF!^6YF!=vZ;5B?|S_E@}WF8}}l07*qoM6N<$ Ef^S30O#lD@ literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_stat_name.png b/android/app/src/main/res/drawable-xxxhdpi/ic_stat_name.png new file mode 100644 index 0000000000000000000000000000000000000000..371ea56a073f8bb267128821648e212d9b956502 GIT binary patch literal 1726 zcmV;v20{6WP)=r`z38qQzP zgV3hBF2fT9Zzi+^x*d80`rQezFURS6qXG_W22FydLAyW;q1~Yw(3D;pYn(1y71S{S z+7r4GdKvnensd3{PZYrL-Jn&_cgmqG{)S$Ko`>#-E`^SV=0Q_*-7ZMq1UeA9jpULN znq%}nqX33KpgpO^@H`$B<))i!0;!vHx1z+v-sxt zImubmPq_XQv|rHx)`xPQGol>s6f)?P?-C)a(!Vu_v=-*k~to?`< zICGQs&LJxp$u>8w-wo#0{VBAS@?m>u4fHxR%S~%NF!;`%V@(-}24J1x*gg?D2l~>< zyV&)w^}yh}dxkd+UeoeLBz3<)(rxC^+6zdAtzCGoU?=TktAW8Uk&LA@4PevqMI=Z6 zy(HsS{O>o5wc5Yd1EU8iOz=X~kx-|upP>2Lzg9ys4)lp~q%LmI>IAS3$$t2Anf9;s z!04qUL&iRgR8X0!`??1jtNm*=Bwe?!(tb3iYT!cf95h+`*Lq;|6WWsqd6;6H1tVEY z!U4`IBl8OE3 z$NzaLNgh>$RTku;G+%hV&|T1u+L!2n6Pr`L6=zvA4Qv@3plhJ%+K*@d zdm{80rDxwb|6bY_hU6U)dFwqjkLdEzK{7P0R~F}y7igyF62;ryMZfEy2^qHV`yzZ^ zk&v)b*AXRfWN#Y&Pqhw3jld-7_d)wYvq;wU^CfBr%I|9Cak};;T1a{vMXwPk3Tz#? zKAwL32Kt(0sYz9qYCoa|4qc@^tch=9`R2=`TMfX#sjDe{CM1`QtYGDB%i3O-yt;UM z_ZonKV@FZ>&9E%cMQOg2)p3fpy)(eMIncA(V?|Mbiqd>3tD_sepgc$x@16v`N7=zB zI}7^FI&E_&A$flsHv~Tbp_en(X#g(s1N08`7W6jBGrv{gHz&^4_I4JM{yJZpE`(N- zbRCnkKsSW`&G0tvcFu>kCTG3?-zP)Yk^jHogg9T$7YdSK^57cJ&+-wS1fIv3__dRK zl)7*aYkyr&0!e)X=^}-EMln8?)DJiiBm-&u;Kar^n2 zI9u28zlJ1$|Gl{u-?xCSC0PzRK%UFYN$x#7SXj1zV30D#mW)7<+%K-6{N*i7yc09A zKyoIX3B5?^n>F887V7*)A3?xplgu^T3N6v;hG7_nVHk#C7=~dOhG7_nVHm#r3yR=q U6( + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 036d09b..4df90c3 100644 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -2,4 +2,5 @@ + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index c023e50595074292c7361183a64de08cf9686c9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2786 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 diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..90ce47cc947f3ffd565cf2765633e68be88514d1 GIT binary patch literal 2178 zcmV-|2z~cbNk&F`2mkiWw(_dWoCM*Cqs=6vNse;Zvj^{j6pcXN@* zUw}wWbol~EKzzXiV;}+=O49Z(l9b;sv$CqIvb}3&aCdjNOR#5UJC5LT1Kq(L*t*-e z`%Jsh<*EN4T1EU5TYgC48Mr6X5o3wF6F~`*ZPT_@a~YRuJ*edYfy|NNs(-M)WT;*4Oo9+-q+wUDFkX!W8uBtmf}uX}uMYa+8C0qx0PT)VZFW-mr+N)WT~bXzCPh?gOXLbD;a&5KN$ zeYcrgrmEohg&*d={)bIXBnX+AHg)~RkMsDV8C>+1P=2QnQBlnFGE+NskqI>YW2o9l zM5N7zp!LV*2+2nvqGW*|6<;<7mWT?#6ln3?=&;UchE#EC8*4_U6RC)Nf6G)il-!^!GM zUylK;DPB^y0FV$zwf+CrTsRiqHP&1*vbF5IDn znZ!u2AYy#rdkY?ZVs+cMTw5U0wDpKlj(P)~=>Ual% z<`gceUCOcc($|*X^-R5d82cpd{(zO<-H-t`{)F$w5*uTCh7v2?@QRt~G{{n38DzQG zQ^_;5l7PUSR$lkQ;EXrKVdS&t+vNKMEUbVwgaE`+mKlRc`z4j8v+@6|%9x`R$q}N9 zXcg2R)?M<_ij(h@Whz~8*ugp5J#os0JZ=ClR1vV>zAbf%s`HjXF%tYPHXj$q_IcF9s-It zr)Mev8IuEX8b=fe0kX!fHuetJ+w3E$0K~EYIxASGgTp7@G5q5}SQBSA0KlTS^a}@m z{)ib4BTcSZ`iG3&rmvnJSY-e<6mhu-xq#LsG42tVo}JPH;Ou7Nm!aa2up zUAB^*U3YtTzS(Isy*=n?30a5*eB{Cy>n-R#p@T0l?`DeE1f9d!<9W;s{cFCk=TBeg z+H>^*+J*Kx{*}?uoS)keXuudu2_K;MM^nH6GE$`JPP4vp$h$u<8wP+(DMvh#xkE{} zY$?Gg>+6r8y9*vn{P?d;RfELjPmF&X@>rFz>)fxs0FcYT01mz*b_XCaQz65J)L4jM zKok@&`p<3;!7e=$(mRpVYP672)@ zJCh3l*tTrt7L;>Q3arz{H|9K zIspLK*27%6XV=Pa*lqH~ogJ8O9A-DY2XKFVFWhsmpZ^*#Bj$S=1V9f!?+(~o7(fDe zbx5Ojgu#CgT+I6W?luq2pTz~IIdcyEnb=Q#16AdrkXjrOLcpY8Xoj809tP6%|CQWS z>k>wTl9Sgs%bxpOy(eIgDGI4^pLoDix1lsd0ZjN^Hv{&w{Ko?AA;yO6jgeX^T$mnw zvEs!$GSYTBEnGWU>62k=Rv2K2bwh?6XgSEpDc^qdK!-c0<**JfW(D~yton@GI%EKN z6=dVvHbU@;b^t15P-_wzVqorTdw>0v%sEs#OJDj)Wxz+|M;5YfeCBF262b%{6*INs zpErsqV2cA4QHsdVz3KV&F03&4*l*NP>|IxVqlY~q2Ki%6oKcTBzKwsrPXrK!$CDBs zPOutlEZ!{qg~`q&cO`%#M<9v)gyG|J zhgEw;GiMK4(8;H8dkO?0^qqk{AhMBykcWL5zfnu$V2GNnU*ZYz{6jS8ux<5?0ghdzHf*7}o>LQ=q@C#$g_O)Z>yz-0r}9VW{|=r< E1z4{a;Q#;t literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png deleted file mode 100644 index 2127973b2d318df7085734d236d0ec649a2b0292..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3450 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 72905b854cb4d39e8717090424302e370239a08e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1869 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 YE&ky*L2jKzPRXyKt@S_o+`s2J0JyHBnE(I) literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png deleted file mode 100644 index 8ed0605c27c764f865674ab0b14c859a1ba29ce6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2110 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 GSuO;sSKvbc literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.webp b/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.webp new file mode 100644 index 0000000000000000000000000000000000000000..f8234fa21697b83626d3370e341fb70da01c2e71 GIT binary patch literal 2304 zcmV+b3IFy|Nk&Ha2mk)H$Q9q*lnxy%j2xwlVV}h04g#ww8i^qRz1; z%4HSGV?*A2M4|FYQ9{uoT2bZvpd=}RCgP5qOEIOn;?uqo$zYM{plx*NCM#(sQ7x-@ z{-xh}*^ijvGM0mu3!g;UF-m!yeDA0 zpv6bQ-7PLv6w+e=^8xxNRKwyu_!f{?l2^h+eiHSMRS>;>tO@hQ^W&Wd*LnZh*{P0> zzG(p3M2CP)?>C8A14dPugVZUPo%1>-ot=qi)Efl2*sRig=lcOexXe6&f~S3J@=&Z?d#D;J`T9j)rz zk955wT=8!@@O0-6(5kToSpl2B8bu-tU3RvA#FRCei(J4P+8Hamx=z7~xI= z1B}?c{MGnI2@1sdtmO_%5aC`>WwAx&@n7XZWif~z^46TY=jj@_sV;AatI~5P$FtCR z+%Br@NCepwlK=n=!!-*5%k~?&3uxa zkyfTq0=D1I7L>0qk2GHt)MuzkGQ=jiU3+veh*lWj(LFm2n8uwaIr>s*90 zAET)sd3EH-((|W>Mp_1vyTQW(b|{Z$VN@HdQLMbD}x(t+Q?0v`y1g`3e!{ zXCpjn4Kh*$qiK0}&%yyXBR!I4Th>U&8Q1>JCYf?mt~>pdrw~i!@k?cE!$3BRGRpFZ zt{jpNX{2RYj^mKY(EVJKa-(IRI{7g~SkN@hj<9$e=4-6#Jf>pQ<$;Mvc1kqoe{!0p*(zUeROjqB$Y^mHg$ZIWk5stdNuj}t}IS31&(mprZ$fQ;;s*6i7pX1cI*iD7Hkr3eR| z>!weal>8C5=Cn7WyxY?83rAXt@RGX(0hpV;S%nu{H+q`wLF(3J(qd>4wmuwt16?Gg zza?Ew7fBYdxZb5HrXXw_0sJJwPEv#bXX!d-@(|IG!|QMSrtLxqps^5czKGHg_eQ<{^A70+?+cOtsFE>(`=Q;$w5YnWH+{~ zYqS%D{n2$KfN!5tgb}p8s1pQT*Lj2kY6e?ni>5u?WE8KLTIq=yV|~4nOw>7J3jP|9eK&4jHZ5MX#xm3>bj2Gw{qIKpWNPuH<$mJPAn0==Or!+II@Pe{Y)W}&XSaV zmq;H)`N2AI!2d)5BBCH{CRG@Z+=i&@1OZzQbmq}FhV(W;)wd|Z_ej8g28xZ(y$`jJ zmOZ+RG3Eo-@qqvJ3Cf8g!rIftyL2Vzkx!8zO-Nul7hIJg9C&({l9Unyszy5tx%fSC zL-mdps`lyIh_Fr^T0;)m){FdFM!2l(?-7v~UXd=0$exb?KIsz@h`TqM_CK*prP6(O zRpll@0x^Nn98ei>KBNpp5~-$HdO%DdVggYR z#tY;F%0c{^NGnPk#x3fpd5OJ&rKUx+4VwChOp4G}M^t0o$7H8;!00Dp?o)=$}qEjfEUpSKp z6Ifc*GFl@2Ec*0)ARh+z-Bo{&NQXA&JdClLGg4$3>D@fw?-ys_*MI*lU~fSw#+ayc z646`AGtr|3B$6W%$pdBMzw|6xKuP9D&fyV15p|sauDwC6o9bP9O2?zkCWucT>VKD= aKZ*<^7%K}cE)Uk20G0{@3m+L~3`Z@Z7+iAz literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index 9502e47a2c575c50c925b987f397bc5244c57b90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2725 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 diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..65f0f453c8bf9c2a4de0b49917a04cc2c1d38900 GIT binary patch literal 2438 zcmV;133>KXNk&F~2><|BMM6+kP&iC+2><{uFTe{B6^DVeZBqZTzk7&?3Gf!G2CPd* z+Ws|?^E<-Q0Vv#PFTijEj+nvBw9L%R+&IwE|F3n`USRKp(y!Gw_?hi!@+F0a0U0x< zE3h3gGc!d)xwDZmb!P@mWXNneQ>5HwnPmReB#>;|Htp;m)NR|mKOYZQ=bX6Y7T77- z?u(t&(vWnXnn;&5N#kS4-Dt@+c z&Sc=Wk)mW4j(PUpAW8fGLvoI3Th;EdZQE8=wR>#aw(U7Vnny|YJcF%m9^3oALwJQe zeTb}km!*0iC!_7$pjQ8^U`w`b+Ocihwr$(a$$he8JA0q|Be8AUwrx8lOSav(je73h z{~`r(!~-5kg6@3uUy<9k4Kv!?eg$Q9C!lPdgSJD#s3e1xL8VPOI{FOib_<>My4{}n zViZj|qT#)jwY1mpy_|celV;nv(lkkr6t{&a5#o);^>jnIf9U7B`rJAJQLQGGB*hht z>rIM~EHJP7>yR9QM-=SE%t6T3#9WOOIn0tJRgplvnwej|+osSqK_!tK87CQ6(k#|=c4X393UREqx`sgi#-;lYR>5t7n9k-bQ^%VF zhlBMAwk$b1o5O32^@cPHt?of;9;Ett^Uc`9hQ(hOY$^DHnXkT3VX-;3kV0KsGzC{> zMT|UeX$okoynFX<6K;5tCncD*`b+oBiGnl;TKiNkji#5V-v^^f-rV}IVaeMWi~e88 zqzby{?<9T1qf-d?HX#-IN^-D0h~xs=B)m$V5)YkDAx&bYri{wwW_EX}`8*0Q|LA{T zrIXEH`gXyz-v<))3#?O$ghFC%WCn#~6J^L1ba{^U+S^PWd_7eYjBNh zZnE1;^GjHK{VM*wg~K(Wq4;!Y%pHa9(c_qQefMI!lHyuZN$ZUx1g?DSB`m)-p;MQ% zl!E`8GC@k$*xh$?Q-ah;!BA~DLg~za>&3rq222}6_Y^zdYU>nSK@(Bv>TPB!)>Ii# z%2kGgzJ45GMxRwGRxuM`#^r`l37RzZ^6=tXWOMiIGWa)|jn0f@Ovjy>?>ZvwNf%Y`d>Nn!v(%r6^Io< zHkuxx?OB;WZ@SRkq{0kxd0mIJj7tr}l_7|&@kg{yN~ikVzpwMf zg9mH;?AF=^ZdV9z(H;Vz6D{aE^NV;SC{f6QQ0UU)qd@`nGl^jsnTn*zS3+x$;_=pd zG1qu}osS#5lrIUhLwAe#?ovd|wrptKQ;}#80GmUTWfEDVrY?AHK})>%2U5YDqYTl~$Ea=DS}}lGHbc_hUdbH^5kte#A(PKIC${ zZo;(d7*uJ_HX~*Dg{$S$r>e!V#?1#0mW85EeIMY>L`nO8IzeGUG&PMWN+f0(P(vm5 zV~|gksLyqq$eGdeev&X-O6&ey;iP<)mmRvN$mIgSSvaB}YogH#J;m1zMi4HbVmHj9 zajEN&_w}G;8~Q@`1^TWq^=a$ezR1STQ_a8Ae76h4O8VT6Y{i(UcO8mFqy!@fMV5Lp%V?<(t1XQLGf3>lj zP>wM<^302~*yzwVI(@I_IwlX-Cl@TgaoqI-ix$5?;PtwX0dRM}xqojq8OBJC+thN% z2mm+;i$a^0qFlZt9QEc0jMB_2Ba^UN8LYg*2aY&5Cn^**-QXngaH7`lB|U+ zS@LQFEdR96HJMCiS%hgRF0yi+hm|(*KhNXl818KKbr-Pw(=E-9TBn>o@t83`J(D3Z zNu{DbsHEdNW210hu=hL~StMXGB8sEk8mwI%l?%f^MlDM$%Gy%48slB_+%C&6ozwV> z2-O^?`KSvWw7mvb zNoIq%n|7&GN<@_eCJ`tE@zR>H{el6(lA1^slQ?zoU-5TH^d7Y;LN{dL&mgE9u$J_JT_jjTqAzOHtW)5~^upBL7xtpE|9-;x)2A^}rArhHB7Fc* z7(X;EukLf%tbsBrnAzP|G&~3@_aWy1E4i0HIoVnO(a~-LHC|lr>o3dex8ku zBLElx3>Ty_`>KDNd2aJxoip6?0F3fq;Nw&&0OJ{{Ocha}iSW)f$GM*W(9~pR0GO1H zHqZ&Tq!fU`DFf4ybopjYB+Ycr_4aYx_V(^+RM*uvI;d3mq;#I4MFUg7NX+^aFJ zcD;R0#qyxfd(?|8)79f?N!2g|KfccbW2tQ9$)b5_W&#!J}w&#sJZ>QHt_a%g3%w!FaVT8t*IV&@FWhx8{-m9P=xbZ0&~mUH)SLJOG0Ct&j8H?NBgEvLA#1 E0CCU7EC2ui literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 4d1e077104cd61e6a4c3707e87363b523077245a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3981 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 nm0GElTB(&OnKI&V600000NkvXXu0mjff+~0a diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..9ae37ce9b24e14289026b78e4d3e7c5afa127edd GIT binary patch literal 3112 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 CuK*+f literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png deleted file mode 100644 index df0f15880bee46332dfc6622583215194f948b0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5036 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 S*Z&1I`cI?(T%`+*X6iWKE0wGO literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.webp b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.webp new file mode 100644 index 0000000000000000000000000000000000000000..da5474261e7ad01ebcdc7289b8c5045d129d8758 GIT binary patch literal 5726 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 QxQ1oZf13W&^q&bMaVhUH)Bpeg literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 853db043d8a21a3f2429bb521e373e8b1d39cacd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6593 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 diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..1be4151c3fcedf6128dd5cbbe558efe4083a012d GIT binary patch literal 5792 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 6cdf97c1196d48e9833487ff6de7c4cfc4e1232d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6644 zcmZ{pXFL_||NoDW?HrtJha-DLIVbC69wc;}LWs%=Q3!R8%&a5HUWX12AsLxPvg`0M z4%vI3LpIs#@B6?1yK#+s*Lz*p^YOagQKokd*qHg50RRA-;ceu-i#6_lgYojkOx2(J z4gm1|FhpvbVaC=zTE$&4#|MuVHK$myjH# zaR><-@RxJ^M@VC6^+G<*Okqst5fUDIQ9WVJ5cXClVR6gh zFmq4#{2DHp(xxs?nQ3QtH_YQje$8KoOpb$NxwsXr7j(5D24KC~kbOKX$ob|zL&y1< zvY)r2?2A%s8p86w&=5Jg)zhrGPn0~G~ z#k1it{z_(l*yq0NgX*Uf!dU^I^6@0F-pV%RX+%(uH4~wcVOg@l&Wf8)=nF?{6(fT6 zT1ez={Z8gSw!~xWMl&~ln&9tcO2&!r-%Izrj;n1X^5xl>A8r7r1sWS&|C?-No)*dq z@%SeY;bmZ?h13jo#qTT^gaV&8=^8ZKwKk4kb$~w{W)nE?xw;8@j=|MPc*-*yXR-lN zOV;2?#Y{50B9kp}W^D1Dea72;(#9?8QdP3{g5Syd70l%+8PEI23PSm@`|YV zRg5K62lJnK%|@)k&&wgR&7lm+EjB%vst9|Toj`t=d@Qs*-%_P-1FMjHZ-U(ae=%sPO`E95q@ za+?(wg5XR#Af8 z84W_KwbOh=6e!vuR<0GcPv#=bh!I;6_^TIZr|N&{dCe2dFdM4)SkfStjlZnn=HpZWm8bo8B*7vIZvQ3A zM!m(+hdm(}{Fdg4w{EfMJ8%ywCCS`40?{u?rkfU5ib)^`Z29hq8li?1IybXpttJ$>fDi6PPTtg!z zx7%}>e9%%Tomft}4Wxsk`1zjNDu3j`4JUOLuO$b>%jEOkf$n?A24h$%CtQr!{OydG zMF|M>nA<~iVpdU)Nq}qMe@Z;w5Mi+J7fx=O1g;smIscE_|05i-m+Kt~mjRevRML>-?0U z=+0@B9d*Zv2_tqBSjhiE^-ufE%x8*v-};%jp34f8zIr`0&>FN0Oken=;InO_dhQ3A zaIak!n`ktU)E)Gn&AAI}fSuABJiN+0Z!&$XYi@hfLH_H;s%3|0>}i%BCCDYddffPB zO@c6@@Od5Tp=0wgckS^v?!#S+Xq&>tAJiDNK1mcizpO>^vlzuk4qdxphlp!Pb7`EV zu78*_U(?PG&^A~QSA*BVYawecA$F!K+ie?#QhQ!RzyEx=hIJc7#JyeqPraOo6eQz>1X`9 z7C%08Tf|z>z9+$7)PQTZEkh~u-*aah%=#M-K@kfa{hafR(`IgRW&`RQ%*5%lGMR)x12Yg-{KK5I05|>VCy^Cx2;Tl>g4c{#%$KTJRzx^ zLLXNUVFj0~2y6t3G^#py6@R;lS7Lx1d^?`rZ)3O!RST$5{YeccG+_W47<^H*+t$2I z4$aIn11#DbK;UC5_C={MxQC zbFR_5$b1P#E(o84aYP)z#yE@0Q#PYmTfcUi#|Ua-E3gv9`7U*-;?+(ApQVteJaQGU zA`PchToSIEtZJ)$fNL#~x#+t`-v&!;>;40^hYEkc7g;FFC+btBH_Mbl+NMMqzfOHu zvi#IL`mZcJ=0~B1Jn0D3RQa?(4>IW~(n}05ikg=df{vfB*uCMcZj1E#zR*$$ZnCNyO(xy^0m`xB40j0#li-YyYRk+i ztAdMTFi_%VHhCoFxaCjq(g;q^V#BAJ{fZ`1;0P+Jv>;+FnkHF93(kq^wVT>AkWD;V z5%Z=r-G4RfIvx}556tb$Wcy&X@IYOzqIf)6O-lo3dXx1#I^{j8N~KHEzTI*djs|2$ zN+VQZXYNbD1tFVUzfEJm;Fg=Ss+++Stp68TFwqGL%6a@xlM|G~*9Mx-a`#WWLIjzF zb?DhlwO76=78dpAJKeMa0}gcuuZp)`e~8i=IcXbm!4<0N218B-{Y4d>;o4bJa-;3_ z?>738Mlil6J2<8eZ};hh{7LeuGy@~(#Us;cqvvQ z2|=opVCqXC(+REsM`Z=D-`IXNb6rLoxny%RpK0|ahpme9>6&p}*BJnP+>NG2Esc$G zHao>q-~1V;S!ud|H=+RAKh1m^GSj+3NcHG!QA#j1-{Vyeb!i>|woRAfH%hb7+t5dz4LMy&d(5?9FD9En1Slug&XxUh& z+c!&-|3yuRugxWel+aO=XRnsNRT4D_B6ce~bvWAT=Da6{Qc~z7*D9X^pYBKAx4cs^l z>8(+Fq+ujGS&?uAeO?aoHCTx92N_BV>~|!SB(#x2PakC!tR2z*(oVX92=w0D)_7%7 z1rtMwF>@GU-Q|$iDRRn#^+S6PGh4~Ks+mnyj z+dXAv6A~pVxt~N$I$#sR5-T)8frn+0zwc>k$5oe1P|D=C%f?3&V**X8%x?V8!$tNj zZ7w?&`&Ea4zCDJPJ1W+(3BO<2JQ`JUk9U4m*8tj$#6v~laVRs6VyrpH>m$LqmEsGwxw6jW&u~@5U zzyBDZ^%$pH96mV_x!bqQwhe8eGI+S#*E?yp)o_Nv3U%KGI4{ugMjUgK@3Ou;V>4O{d zIJ}9O{AiO;ZQt7QSE*O9J#;%=iFNCnzfk3ByeYHjeMmG*uCsyJ%Y)((7DxO`sKzU5 zlfxhi-p}wBSoQ{QP$U{piNc8JL>?LmBg{mhW7pAKc1aQJ-=x2;auiGYg({&Ot>@ug z5n zPIMP!lS8%VDPKsEUGo^q#(%ei9>#i8cxaJ~K(#Je=-iQbG5{$nD&qGl^$XVVj&{pX z4~WRdx>%kDX8l5)4G7_XMZDo6s<(AdE)o0K^3OOq#Gu>z#dpDFE?Y35um7Wg8DnCs6&LhQFVgLPa6wKEE$Pt-Tzx`g zh?h@QXjh!Gq#o2qzg8z*&#Rt9AA4DtHfSy;mld>I$F6i_?E32R7iFI(iq7PaX}D+e zHx@9XeLRu?hf z!2vFWCH*@ojt&D)yA^Q~@>=N410y5{Q89~A_vB~m=#?UIxDV!4kP`1|A0g;8%Qthy%+JBI_-S!LD>?bAe!a3B2;Q=g-Tj z*ZN9bX$3DOuRq2uF~zj-xwU?k?ZMiGcE2Vz`;0KsKr~47v7!vIuPv-3;6sL+NnY3% zx49BSK{2^Y@zd0t=f0T6k&vYWL`eTlu;%#SK7LE+Q3J`>e(`aYF;Rq@4WEQ77YVPD(?&CB1$b z$=)iPW&`aDSuTYHI1*-7_G!Z6gE?2YuX22ZRGzf15iR&KIShd|u84m|kmJ@*6d@Y6 z;PEC8YxCawX0~SDM9Q;(Ch0-che%fuZ8Y? z)e{zZOA?qXcqQ?3!)3Mp*z$hmCnidiBUkbZRR(AP!{uieQu)9wv)=%M&AaLyy#8~4 zY8g|hzESUeZDi~IBdc)nA2rF!$TRj$V#n_)cJ876VBEPi3)9$-*BcMMO$Q!#s}#JR z@FKmJR(6GXQ( z@cBNSP5gONEnVjgb%o&kDgT{rrCF-e@S`_tubZPam$e<+TUzn%NuR}xnFlN1;&yNE z6vN{gVsl*i4^MW;WSfB9!D&)${cME5)7c5iCD3is^KX-TLI>DM*|Pd=a%gDizmglo zsZtqQgj|Qd9i~XeJ3;X|?zj5>PT0YnzZcL}JntVLH?k;u^iz=9o6-3JL8IgBwg(@! z@s>Y1ffP0e3G?y>dp1xC^}#-WdixEUZ3UjFxgWjeZiWP6*dBFy+qQ08Hx`)k7x)I* zvWcV?&G(Jq^Nl7SqhW}+k^gor6D5~|rDsRynHdA>ug`%Q_$sey1Qy=*) z(`Wvu^`<_G^j_|Ey#_GZau+YESAAgP^~+>)hk>klezLv3zOF=y6_!lC6RvVylvNMj zB)E+9$?j;LhThoZ${sa?-(T{Zs6Z;OMX|~~m3;u8yT!b2r-J9ImN-}N45jz=hcww~ zc+Jrr{_96IT30_C>{oG~n&{r5yc|msB$=TWp|uaX)0LCf=62Sm-MJubeXfmVOIA#`GRZEf6RRo&C{?^L!`%;cLrzSGlFn_(f9 zUXRtomzp*T`;)+yfH(Vdrwnu&$53x-=}+b!y$275A-!rVPd+G8y}u|sKfrpA#24&s zxj}vM&jlCw$$URP<>tgDpM)HBf8 znJzG22QR0>qavxItYV<@U@EhFo8tL5NrFui8N~cjl~HX-xrO00dbH9x=)9uy+K*3h z6s8`Uu3!6}ck63wCo;a|w{nFs^2{}?1*rIRm2SGP4idWL#UA94Ph~u=dEPzi%ELe@*qf@gvSATw~wkjraBbjEv=m!)LYHnjt2qLNp9xFikdM1hG07L*9Dt$TU1X`wlehm5ev+D^ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..2118bb4824c5a97d3deda63fde01c27bc3a760c4 GIT binary patch literal 4918 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 Uf8&4Sf8&1x&j@mbjQ@?|0TF%O7ytkO literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.webp b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.webp new file mode 100644 index 0000000000000000000000000000000000000000..1a4adf80fef147447db9215093fb60ad83bc7eaa GIT binary patch literal 10934 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 YkpB<)|B(L=`Tvmr5BdL){|^Bd0Cd#icmMzZ literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index 8e3093a86fffb4d02383785a46189822142d5607..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10455 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 aG<+Ajbh|WzX-diqWS1`Q2<$d}-xF-jhG(t- literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png deleted file mode 100644 index d2ea9abed395c5fb38369a54896c51c8e8bdff72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15529 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 y3vD~Wi9;mL_v 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 diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..3de3ee8738de9f94bfdcee5b0d78419489e6ae51 GIT binary patch literal 16546 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.webp b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.webp new file mode 100644 index 0000000000000000000000000000000000000000..63908e3f2db941e734c545205078562de7c40e65 GIT binary patch literal 18554 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 F<`E}UJb(ZI literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index a40d73e9c68ea638c28c7b13e4bcd1e179a3a102..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15916 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 + + + #d6325c + diff --git a/android/app/src/main/res/values/ic_launcher_background.xml b/android/app/src/main/res/values/ic_launcher_background.xml index c5d5899..c249097 100644 --- a/android/app/src/main/res/values/ic_launcher_background.xml +++ b/android/app/src/main/res/values/ic_launcher_background.xml @@ -1,4 +1,4 @@ - #FFFFFF + #EFC4C4 \ No newline at end of file diff --git a/functions/src/push-relay.ts b/functions/src/push-relay.ts index 63902da..1d9bbdd 100644 --- a/functions/src/push-relay.ts +++ b/functions/src/push-relay.ts @@ -37,7 +37,6 @@ const WEB_PUSH_ENCODINGS = new Set(['aesgcm', 'aes128gcm']); // eslint-disable-next-line @typescript-eslint/no-explicit-any const _origEmit: (...args: any[]) => boolean = http.Server.prototype.emit; -// eslint-disable-next-line @typescript-eslint/no-explicit-any http.Server.prototype.emit = function ( this: any, event: string, @@ -395,6 +394,8 @@ export const pushRelayPush = onRequest( priority: 'high', notification: { channelId: 'PushDefaultForeground', + icon: 'ic_stat_name', + color: '#d6325c', }, }, }); From 53e2aa2745dacb8c9880177645f9fa2ae969b477 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Sun, 15 Mar 2026 23:14:35 -0700 Subject: [PATCH 06/26] fix safe area issues --- src/pages/app-explore.ts | 2 +- src/pages/app-hashtags.ts | 2 +- src/pages/app-media.ts | 2 +- src/pages/app-messages.ts | 2 +- src/pages/conversation-thread.ts | 2 +- src/pages/create-account.ts | 2 +- src/pages/edit-page.ts | 2 +- src/pages/post-detail.ts | 2 +- src/styles/home-styles.ts | 5 +++-- src/styles/shared-styles.ts | 2 +- 10 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/pages/app-explore.ts b/src/pages/app-explore.ts index 31a9cc6..15586e0 100644 --- a/src/pages/app-explore.ts +++ b/src/pages/app-explore.ts @@ -27,7 +27,7 @@ export class AppExplore extends LitElement { } main { - padding-top: 60px; + padding-top: calc(60px + env(safe-area-inset-top, 0px)); display: grid; grid-template-columns: 2fr 1fr; gap: 10px; diff --git a/src/pages/app-hashtags.ts b/src/pages/app-hashtags.ts index 358b06a..f29790f 100644 --- a/src/pages/app-hashtags.ts +++ b/src/pages/app-hashtags.ts @@ -20,8 +20,8 @@ export class AppHashtags extends LitElement { } main { - padding-top: 60px; padding: 10px; + padding-top: calc(60px + env(safe-area-inset-top, 0px)); height: 100%; box-sizing: border-box; display: flex; diff --git a/src/pages/app-media.ts b/src/pages/app-media.ts index f9258ce..ef0269e 100644 --- a/src/pages/app-media.ts +++ b/src/pages/app-media.ts @@ -15,7 +15,7 @@ export class AppMedia extends LitElement { } main { - padding-top: 60px; + padding-top: calc(60px + env(safe-area-inset-top, 0px)); } ul { diff --git a/src/pages/app-messages.ts b/src/pages/app-messages.ts index 4b2d850..df6dd1b 100644 --- a/src/pages/app-messages.ts +++ b/src/pages/app-messages.ts @@ -44,7 +44,7 @@ export class AppMessages extends LitElement { display: flex; flex-direction: column; height: 100%; - padding-top: 46px; + padding-top: calc(46px + env(safe-area-inset-top, 0px)); box-sizing: border-box; } diff --git a/src/pages/conversation-thread.ts b/src/pages/conversation-thread.ts index 9916e18..1c2e5f7 100644 --- a/src/pages/conversation-thread.ts +++ b/src/pages/conversation-thread.ts @@ -46,7 +46,7 @@ export class ConversationThread extends LitElement { display: flex; flex-direction: column; box-sizing: border-box; - padding-top: 46px; + padding-top: calc(46px + env(safe-area-inset-top, 0px)); } .scroller { diff --git a/src/pages/create-account.ts b/src/pages/create-account.ts index 7869b00..ceb504e 100644 --- a/src/pages/create-account.ts +++ b/src/pages/create-account.ts @@ -43,7 +43,7 @@ export class CreateAccount extends LitElement { main { padding: 10px; - padding-top: 60px; + padding-top: calc(60px + env(safe-area-inset-top, 0px)); overflow-y: auto; height: 88vh; diff --git a/src/pages/edit-page.ts b/src/pages/edit-page.ts index dd92bd7..d681639 100644 --- a/src/pages/edit-page.ts +++ b/src/pages/edit-page.ts @@ -19,7 +19,7 @@ export class EditPage extends LitElement { main { display: block; - padding-top: 56px; + padding-top: calc(56px + env(safe-area-inset-top, 0px)); padding-bottom: 80px; min-height: calc(100vh - 56px); max-width: var(--layout-max-width, 1200px); diff --git a/src/pages/post-detail.ts b/src/pages/post-detail.ts index f556e1e..ae3a65a 100644 --- a/src/pages/post-detail.ts +++ b/src/pages/post-detail.ts @@ -74,7 +74,7 @@ export class PostDetail extends LitElement { /* Account for fixed header on full-page view */ :host(:not([embedded])) main { - padding-top: 60px; + padding-top: calc(60px + env(safe-area-inset-top, 0px)); } .scroller { diff --git a/src/styles/home-styles.ts b/src/styles/home-styles.ts index 907a54b..3bc616b 100644 --- a/src/styles/home-styles.ts +++ b/src/styles/home-styles.ts @@ -270,7 +270,8 @@ export const homeStyles = css` } main { - padding-top: 54px; + padding-top: calc(54px + env(safe-area-inset-top, 0px)); + display: grid; grid-template-columns: var(--layout-nav-width, 80px) 1fr var( --layout-sidebar-width, @@ -611,7 +612,7 @@ export const homeStyles = css` height: 100%; overflow-y: auto; -webkit-overflow-scrolling: touch; - padding-top: 50px; + padding-top: calc(50px + env(safe-area-inset-top, 0px)); scrollbar-color: var(--md-sys-scrollbar-thumb-color) var(--md-sys-color-background); } diff --git a/src/styles/shared-styles.ts b/src/styles/shared-styles.ts index 227ece0..1d273f5 100644 --- a/src/styles/shared-styles.ts +++ b/src/styles/shared-styles.ts @@ -10,7 +10,7 @@ export const styles = css` } main { - padding-top: 60px; + padding-top: calc(60px + env(safe-area-inset-top, 0px)); } md-button::part(control) { From 8012e3812cab6444e66da0e936ba508a230b0ff7 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Sun, 15 Mar 2026 23:15:28 -0700 Subject: [PATCH 07/26] lint --- src/pages/post-detail.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/post-detail.ts b/src/pages/post-detail.ts index ae3a65a..8ab9947 100644 --- a/src/pages/post-detail.ts +++ b/src/pages/post-detail.ts @@ -528,7 +528,7 @@ export class PostDetail extends LitElement {

    Date: Sun, 15 Mar 2026 23:24:41 -0700 Subject: [PATCH 08/26] more safe area fixes --- src/components/post-dialog.ts | 1 + src/pages/app-profile.ts | 2 +- src/styles/home-styles.ts | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/post-dialog.ts b/src/components/post-dialog.ts index 7778910..2dd468b 100644 --- a/src/components/post-dialog.ts +++ b/src/components/post-dialog.ts @@ -138,6 +138,7 @@ export class PostDialog extends LitElement { md-dialog::part(dialog) { min-width: 100vw; min-height: 100vh; + margin-top: calc(env(safe-area-inset-top, 0px)); } } diff --git a/src/pages/app-profile.ts b/src/pages/app-profile.ts index bfe856f..f749917 100644 --- a/src/pages/app-profile.ts +++ b/src/pages/app-profile.ts @@ -132,7 +132,7 @@ export class AppProfile extends LitElement { background-size: cover; background-position: center; position: relative; - margin-top: 40px; + margin-top: calc(40px + env(safe-area-inset-top, 0px)); overflow: hidden; view-timeline-name: --banner-timeline; view-timeline-axis: block; diff --git a/src/styles/home-styles.ts b/src/styles/home-styles.ts index 3bc616b..16fb97d 100644 --- a/src/styles/home-styles.ts +++ b/src/styles/home-styles.ts @@ -550,6 +550,10 @@ export const homeStyles = css` display: none; } + otter-drawer::part(base) { + margin-top: calc(env(safe-area-inset-top, 0px)); + } + md-tab-panel { max-width: unset; } From b3e3d08fe4fde3609688ac83caf8ccaf03a6858a Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Mon, 16 Mar 2026 22:09:28 -0700 Subject: [PATCH 09/26] safe area fixes --- android/app/build.gradle | 2 +- android/build.gradle | 2 +- android/gradle.properties | 10 ++++++++++ android/gradle/wrapper/gradle-wrapper.properties | 2 +- android/settings.gradle | 3 +++ src/components/header.ts | 1 + src/components/post-detail-dialog.ts | 2 ++ src/pages/app-login.ts | 1 + src/pages/post-detail.ts | 1 + src/styles/home-styles.ts | 1 + 10 files changed, 22 insertions(+), 3 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 73b57a7..f4c199f 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -19,7 +19,7 @@ android { buildTypes { release { minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } diff --git a/android/build.gradle b/android/build.gradle index f8f0e43..34a92c9 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -7,7 +7,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.13.0' + classpath 'com.android.tools.build:gradle:9.1.0' classpath 'com.google.gms:google-services:4.4.4' // NOTE: Do not place your application dependencies here; they belong diff --git a/android/gradle.properties b/android/gradle.properties index 2e87c52..65681bf 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -20,3 +20,13 @@ org.gradle.jvmargs=-Xmx1536m # Android operating system, and which are packaged with your app's APK # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true +android.defaults.buildfeatures.resvalues=true +android.sdk.defaultTargetSdkToCompileSdkIfUnset=false +android.enableAppCompileTimeRClass=false +android.usesSdkInManifest.disallowed=false +android.uniquePackageNames=false +android.dependency.useConstraints=true +android.r8.strictFullModeForKeepRules=false +android.r8.optimizedResourceShrinking=false +android.builtInKotlin=false +android.newDsl=false diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 7705927..5f38436 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/android/settings.gradle b/android/settings.gradle index 3b4431d..c3c9ec6 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,3 +1,6 @@ +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' +} include ':app' include ':capacitor-cordova-android-plugins' project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') diff --git a/src/components/header.ts b/src/components/header.ts index e64d5cd..7df62e4 100644 --- a/src/components/header.ts +++ b/src/components/header.ts @@ -57,6 +57,7 @@ export class AppHeader extends LitElement { backdrop-filter: unset; background: var(--md-sys-color-background); height: calc(env(titlebar-area-height, 33px) - 4px); + background: transparent; } #actions { diff --git a/src/components/post-detail-dialog.ts b/src/components/post-detail-dialog.ts index a70a53e..7d27f07 100644 --- a/src/components/post-detail-dialog.ts +++ b/src/components/post-detail-dialog.ts @@ -35,6 +35,8 @@ export class PostDetailDialog extends LitElement { background-color: var(--md-sys-color-surface, #1e1e24); color: var(--md-sys-color-on-surface, #e6e1e5); overflow: hidden; + padding-top: calc(60px + env(safe-area-inset-top, 0px)); + /* padding-bottom: 120px; */ } dialog[open] { diff --git a/src/pages/app-login.ts b/src/pages/app-login.ts index 2221ba8..86900d1 100644 --- a/src/pages/app-login.ts +++ b/src/pages/app-login.ts @@ -41,6 +41,7 @@ export class AppLogin extends LitElement { width: 100%; background-color: var(--md-sys-color-surface-container); padding: 20px; + padding-top: calc(90px + env(safe-area-inset-top, 0px)) !important; box-sizing: border-box; position: relative; overflow: hidden; diff --git a/src/pages/post-detail.ts b/src/pages/post-detail.ts index 8ab9947..853b578 100644 --- a/src/pages/post-detail.ts +++ b/src/pages/post-detail.ts @@ -159,6 +159,7 @@ export class PostDetail extends LitElement { padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)); box-shadow: 0 -12px 24px rgba(0, 0, 0, 0.18); border-radius: var(--md-sys-shape-corner-medium); + margin-bottom: 68px; } .composer-shell { diff --git a/src/styles/home-styles.ts b/src/styles/home-styles.ts index 16fb97d..2903d46 100644 --- a/src/styles/home-styles.ts +++ b/src/styles/home-styles.ts @@ -585,6 +585,7 @@ export const homeStyles = css` #mobile-actions { display: flex; + bottom: calc(env(safe-area-inset-bottom, 0px) + 86px); } #mobile-actions md-button md-icon { From e120d0d260ba5290d58b4bdece19dcc04ccd7528 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Mon, 16 Mar 2026 23:25:06 -0700 Subject: [PATCH 10/26] google play --- README.md | 1 + SAFETY_STANDARDS.md | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 SAFETY_STANDARDS.md diff --git a/README.md b/README.md index 41b9621..6eb0852 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for details. - [Technical Architecture](docs/TECHNICAL_ARCHITECTURE.md) - [Why Coho?](docs/WHY_COHO.md) +- [Safety Standards (CSAE)](SAFETY_STANDARDS.md)
    AI Use Disclaimer diff --git a/SAFETY_STANDARDS.md b/SAFETY_STANDARDS.md new file mode 100644 index 0000000..1191489 --- /dev/null +++ b/SAFETY_STANDARDS.md @@ -0,0 +1,31 @@ +# Safety Standards + +## Child Sexual Abuse and Exploitation (CSAE) Policy + +Coho is a fast, offline-first Mastodon client designed to connect users to the Fediverse. As a client application, Coho does not host any user-generated content directly. However, we are deeply committed to maintaining a safe environment and strictly prohibit any use of our application to facilitate, distribute, or access Child Sexual Abuse Material (CSAM) or any form of Child Sexual Abuse and Exploitation (CSAE). + +### Zero Tolerance Policy + +We have a zero-tolerance policy against CSAE. Any use of the Coho app to promote, facilitate, or share content related to the sexual abuse or exploitation of children is strictly prohibited. + +### Content Moderation and Reporting + +Because Coho connects to third-party Mastodon servers, content moderation is primarily handled by the administrators of those individual servers. However, Coho enforces safety at the client level by: + +- **Blocking Known Offending Instances**: Coho reserves the right to block connections to any Mastodon instances that are known to host or tolerate CSAM or other forms of CSAE. +- **Reporting Mechanisms**: Users are encouraged to report any instances of CSAE encountered on the Fediverse. These reports should be directed to: + 1. The administrator of the instance hosting the content. + 2. The appropriate law enforcement agencies, such as the [National Center for Missing & Exploited Children (NCMEC)](https://www.missingkids.org/) in the United States, or local equivalent authorities. + 3. Coho developers at jgw9617@gmail.com, so we may evaluate whether the offending instance should be disconnected or blocked from the client. + +### Enforcement + +Violations of this policy will result in immediate action, which may include: +- Blocking access to the offending instances from within the Coho app. +- Cooperating fully with law enforcement and reporting authorities in any investigations related to CSAE. + +### User Responsibility + +Users of Coho are expected to adhere to the rules and policies of the Mastodon instances they connect to, as well as local and international laws. Engaging in any activity involving CSAE is a severe criminal offense and will not be tolerated. + +For more information on our community standards and how we ensure a safe environment, please refer to our [Code of Conduct](./CODE_OF_CONDUCT.md). From 3cf3e15464c916b904bcbb87c9233d1466999010 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Tue, 17 Mar 2026 19:59:46 -0700 Subject: [PATCH 11/26] fixed auth issue --- index.html | 27 +++++++++++++++++++++++ public/.well-known/assetlinks.json | 32 +++++++++++----------------- src/components/post-detail-dialog.ts | 8 +++++-- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/index.html b/index.html index be10f2e..e332951 100644 --- a/index.html +++ b/index.html @@ -190,6 +190,33 @@ + + + diff --git a/public/.well-known/assetlinks.json b/public/.well-known/assetlinks.json index be332a6..3e816b7 100644 --- a/public/.well-known/assetlinks.json +++ b/public/.well-known/assetlinks.json @@ -1,20 +1,14 @@ -[{ - "relation": ["delegate_permission/common.handle_all_urls"], - "target": { - "namespace": "android_app", - "package_name": "coho.mastodon.twa", - "sha256_cert_fingerprints": [ - "11:B4:5F:D0:8B:F6:6D:6E:CC:FC:5A:5D:FA:EB:46:14:64:21:D5:8A:64:9A:02:0A:C4:DA:AF:05:71:A5:32:CB" - ] + +[ + { + "relation": ["delegate_permission/common.handle_all_urls"], + "target": { + "namespace": "android_app", + "package_name": "place.coho.app", + "sha256_cert_fingerprints": [ + "B0:9F:08:87:66:03:4A:D1:BF:6D:E8:08:6B:C0:05:4F:63:8E:1A:39:E9:05:3C:40:83:1C:B8:F6:40:C6:A6:E6", + "82:20:E9:33:F1:68:59:CF:76:A9:AB:E6:74:3C:6E:00:A6:BF:B0:DF:13:F9:10:DE:67:79:E9:BF:95:AD:FF:DA" + ] + } } -}, -{ - "relation": ["delegate_permission/common.handle_all_urls"], - "target": { - "namespace": "android_app", - "package_name": "place.coho.app", - "sha256_cert_fingerprints": [ - "82:20:E9:33:F1:68:59:CF:76:A9:AB:E6:74:3C:6E:00:A6:BF:B0:DF:13:F9:10:DE:67:79:E9:BF:95:AD:FF:DA" - ] - } -}] +] \ No newline at end of file diff --git a/src/components/post-detail-dialog.ts b/src/components/post-detail-dialog.ts index 7d27f07..2e573b5 100644 --- a/src/components/post-detail-dialog.ts +++ b/src/components/post-detail-dialog.ts @@ -35,7 +35,7 @@ export class PostDetailDialog extends LitElement { background-color: var(--md-sys-color-surface, #1e1e24); color: var(--md-sys-color-on-surface, #e6e1e5); overflow: hidden; - padding-top: calc(60px + env(safe-area-inset-top, 0px)); + padding-top: env(safe-area-inset-top, 0px); /* padding-bottom: 120px; */ } @@ -160,6 +160,7 @@ export class PostDetailDialog extends LitElement { height: min(90vh, 900px); max-width: min(720px, calc(100vw - 64px)); max-height: min(90vh, 900px); + padding-top: 0; } .back-button { @@ -336,7 +337,10 @@ export class PostDetailDialog extends LitElement {
    ${this.post - ? html`` + ? html`` : null}
    From 1008fa5924b3187e3e0234b49791537f707c52ad Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Tue, 17 Mar 2026 20:47:08 -0700 Subject: [PATCH 12/26] fix share --- android/app/build.gradle | 4 ++-- android/app/capacitor.build.gradle | 1 + android/capacitor.settings.gradle | 3 +++ package-lock.json | 10 ++++++++++ package.json | 1 + src/components/home-sidebar.ts | 10 ++++++++++ src/components/settings-drawer-content.ts | 9 +++++++++ src/pages/post-detail.ts | 9 +++++++++ src/utils/timeline-actions.ts | 9 +++++++++ 9 files changed, 54 insertions(+), 2 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index f4c199f..166e28c 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "place.coho.app" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 1 - versionName "1.0" + versionCode 2 + versionName "1.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle index b012cdb..4d496a7 100644 --- a/android/app/capacitor.build.gradle +++ b/android/app/capacitor.build.gradle @@ -12,6 +12,7 @@ dependencies { implementation project(':capacitor-app') implementation project(':capacitor-browser') implementation project(':capacitor-push-notifications') + implementation project(':capacitor-share') } diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle index 6226bf0..3f70383 100644 --- a/android/capacitor.settings.gradle +++ b/android/capacitor.settings.gradle @@ -10,3 +10,6 @@ project(':capacitor-browser').projectDir = new File('../node_modules/@capacitor/ include ':capacitor-push-notifications' project(':capacitor-push-notifications').projectDir = new File('../node_modules/@capacitor/push-notifications/android') + +include ':capacitor-share' +project(':capacitor-share').projectDir = new File('../node_modules/@capacitor/share/android') diff --git a/package-lock.json b/package-lock.json index 5763e05..40d3c86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@capacitor/browser": "^8.0.2", "@capacitor/core": "^8.2.0", "@capacitor/push-notifications": "^8.0.2", + "@capacitor/share": "^8.0.1", "@huggingface/transformers": "^4.0.0-next.2", "@lit-labs/compiler": "^1.1.2", "@lit-labs/virtualizer": "^2.1.1", @@ -246,6 +247,15 @@ "@capacitor/core": ">=8.0.0" } }, + "node_modules/@capacitor/share": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@capacitor/share/-/share-8.0.1.tgz", + "integrity": "sha512-3cSBKBCJVon54rKDROP2rqGyeGks4pBh9TbaEk9S375Kbek/ZHe72N50zIa0Vn9Eac/SuhwgehO/mmA4CsUOiw==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=8.0.0" + } + }, "node_modules/@emnapi/runtime": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", diff --git a/package.json b/package.json index 3e0bfa7..c31d881 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@capacitor/browser": "^8.0.2", "@capacitor/core": "^8.2.0", "@capacitor/push-notifications": "^8.0.2", + "@capacitor/share": "^8.0.1", "@huggingface/transformers": "^4.0.0-next.2", "@lit-labs/compiler": "^1.1.2", "@lit-labs/virtualizer": "^2.1.1", diff --git a/src/components/home-sidebar.ts b/src/components/home-sidebar.ts index 6695410..c6b2323 100644 --- a/src/components/home-sidebar.ts +++ b/src/components/home-sidebar.ts @@ -208,6 +208,16 @@ export class HomeSidebar extends LitElement { text: 'Check out my Mastodon profile!', url: this.user.url, }); + } + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + else if (window.Capacitor) { + const { Share } = await import('@capacitor/share'); + await Share.share({ + title: 'My Mastodon Profile', + text: 'Check out my Mastodon profile!', + url: this.user.url, + }); } else { await navigator.clipboard.writeText(this.user.url); } diff --git a/src/components/settings-drawer-content.ts b/src/components/settings-drawer-content.ts index 5ebbfac..44080ca 100644 --- a/src/components/settings-drawer-content.ts +++ b/src/components/settings-drawer-content.ts @@ -191,6 +191,15 @@ export class SettingsDrawerContent extends LitElement { text: 'Check out my Mastodon profile!', url: this.user.url, }); + } // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + else if (window.Capacitor) { + const { Share } = await import('@capacitor/share'); + await Share.share({ + title: 'My Mastodon Profile', + text: 'Check out my Mastodon profile!', + url: this.user.url, + }); } else { await navigator.clipboard.writeText(this.user.url); } diff --git a/src/pages/post-detail.ts b/src/pages/post-detail.ts index 853b578..b170c3d 100644 --- a/src/pages/post-detail.ts +++ b/src/pages/post-detail.ts @@ -386,6 +386,15 @@ export class PostDetail extends LitElement { text: this.tweet?.content, url: this.tweet?.url, }); + } // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + else if (window.Capacitor) { + const { Share } = await import('@capacitor/share'); + await Share.share({ + title: 'Coho', + text: this.tweet?.content, + url: this.tweet?.url, + }); } else { // fallback to clipboard api await navigator.clipboard.writeText(this.tweet?.url || ''); diff --git a/src/utils/timeline-actions.ts b/src/utils/timeline-actions.ts index fd02559..84e61c2 100644 --- a/src/utils/timeline-actions.ts +++ b/src/utils/timeline-actions.ts @@ -23,6 +23,15 @@ export async function shareStatus(tweet: Post | undefined | null) { // User cancelled or share failed, ignore console.warn('Share failed:', err); } + } // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + else if (window.Capacitor) { + const { Share } = await import('@capacitor/share'); + await Share.share({ + title: 'Coho', + text: content, + url: url, + }); } else { try { await navigator.clipboard.writeText(url); From 89468499e5df63adb2736b93b4a2b888e6ff8bc6 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Tue, 17 Mar 2026 21:15:04 -0700 Subject: [PATCH 13/26] trending widget --- android/app/src/main/AndroidManifest.xml | 12 + .../java/place/coho/app/MainActivity.java | 10 +- .../place/coho/app/TrendingDataFetcher.java | 75 +++++++ .../java/place/coho/app/TrendingWidget.java | 99 +++++++++ .../java/place/coho/app/WidgetBridge.java | 51 +++++ .../res/drawable-night/widget_background.xml | 6 + .../main/res/drawable/widget_background.xml | 6 + .../res/drawable/widget_item_background.xml | 6 + .../src/main/res/layout/widget_trending.xml | 206 ++++++++++++++++++ .../app/src/main/res/values-night/colors.xml | 7 + android/app/src/main/res/values/colors.xml | 10 + android/app/src/main/res/values/strings.xml | 5 + .../src/main/res/xml/trending_widget_info.xml | 16 ++ src/app-index.ts | 22 ++ 14 files changed, 530 insertions(+), 1 deletion(-) create mode 100644 android/app/src/main/java/place/coho/app/TrendingDataFetcher.java create mode 100644 android/app/src/main/java/place/coho/app/TrendingWidget.java create mode 100644 android/app/src/main/java/place/coho/app/WidgetBridge.java create mode 100644 android/app/src/main/res/drawable-night/widget_background.xml create mode 100644 android/app/src/main/res/drawable/widget_background.xml create mode 100644 android/app/src/main/res/drawable/widget_item_background.xml create mode 100644 android/app/src/main/res/layout/widget_trending.xml create mode 100644 android/app/src/main/res/values-night/colors.xml create mode 100644 android/app/src/main/res/xml/trending_widget_info.xml diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0e6d13d..2e94d05 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -49,6 +49,18 @@ + + + + + + + + diff --git a/android/app/src/main/java/place/coho/app/MainActivity.java b/android/app/src/main/java/place/coho/app/MainActivity.java index 16a16ee..106aa6f 100644 --- a/android/app/src/main/java/place/coho/app/MainActivity.java +++ b/android/app/src/main/java/place/coho/app/MainActivity.java @@ -1,5 +1,13 @@ package place.coho.app; +import android.os.Bundle; + import com.getcapacitor.BridgeActivity; -public class MainActivity extends BridgeActivity {} +public class MainActivity extends BridgeActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + registerPlugin(WidgetBridge.class); + super.onCreate(savedInstanceState); + } +} diff --git a/android/app/src/main/java/place/coho/app/TrendingDataFetcher.java b/android/app/src/main/java/place/coho/app/TrendingDataFetcher.java new file mode 100644 index 0000000..f24df58 --- /dev/null +++ b/android/app/src/main/java/place/coho/app/TrendingDataFetcher.java @@ -0,0 +1,75 @@ +package place.coho.app; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +public class TrendingDataFetcher { + + public static class TrendingTag { + public final String name; + public final String uses; + + public TrendingTag(String name, String uses) { + this.name = name; + this.uses = uses; + } + } + + /** + * Fetches trending tags from the Mastodon API. + * This endpoint is public and does not require authentication. + */ + public static List fetchTrendingTags(String server) { + List tags = new ArrayList<>(); + HttpURLConnection conn = null; + try { + URL url = new URL("https://" + server + "/api/v1/trends/tags"); + conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(10_000); + conn.setReadTimeout(10_000); + conn.setRequestProperty("Accept", "application/json"); + + if (conn.getResponseCode() == 200) { + InputStream is = conn.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + reader.close(); + + JSONArray array = new JSONArray(sb.toString()); + int limit = Math.min(array.length(), 5); + for (int i = 0; i < limit; i++) { + JSONObject obj = array.getJSONObject(i); + String name = obj.optString("name", ""); + String uses = "0"; + JSONArray history = obj.optJSONArray("history"); + if (history != null && history.length() > 0) { + uses = history.getJSONObject(0).optString("uses", "0"); + } + if (!name.isEmpty()) { + tags.add(new TrendingTag(name, uses)); + } + } + } + } catch (Exception e) { + // Network or parse error — return empty list, widget will show fallback + } finally { + if (conn != null) { + conn.disconnect(); + } + } + return tags; + } +} diff --git a/android/app/src/main/java/place/coho/app/TrendingWidget.java b/android/app/src/main/java/place/coho/app/TrendingWidget.java new file mode 100644 index 0000000..ef6c8d5 --- /dev/null +++ b/android/app/src/main/java/place/coho/app/TrendingWidget.java @@ -0,0 +1,99 @@ +package place.coho.app; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.view.View; +import android.widget.RemoteViews; + +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class TrendingWidget extends AppWidgetProvider { + + private static final ExecutorService executor = Executors.newSingleThreadExecutor(); + static final String PREFS_NAME = "coho_widget"; + static final String PREF_SERVER = "server"; + static final String DEFAULT_SERVER = "mastodon.social"; + + private static final int[] ITEM_IDS = { + R.id.item_1, R.id.item_2, R.id.item_3, R.id.item_4, R.id.item_5 + }; + private static final int[] TAG_NAME_IDS = { + R.id.tag_name_1, R.id.tag_name_2, R.id.tag_name_3, R.id.tag_name_4, R.id.tag_name_5 + }; + private static final int[] TAG_COUNT_IDS = { + R.id.tag_count_1, R.id.tag_count_2, R.id.tag_count_3, R.id.tag_count_4, R.id.tag_count_5 + }; + + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + for (int appWidgetId : appWidgetIds) { + updateWidget(context, appWidgetManager, appWidgetId); + } + } + + static void updateWidget(Context context, AppWidgetManager manager, int widgetId) { + // Show loading placeholder immediately + RemoteViews loading = buildLoadingView(context); + manager.updateAppWidget(widgetId, loading); + + executor.execute(() -> { + String server = getServer(context); + List tags = TrendingDataFetcher.fetchTrendingTags(server); + + RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_trending); + + // Set up tap-to-open intent on the entire widget + Intent intent = new Intent(context, MainActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + PendingIntent pendingIntent = PendingIntent.getActivity( + context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + views.setOnClickPendingIntent(R.id.widget_root, pendingIntent); + + if (tags.isEmpty()) { + // Hide all items, show empty state + for (int itemId : ITEM_IDS) { + views.setViewVisibility(itemId, View.GONE); + } + views.setViewVisibility(R.id.widget_empty, View.VISIBLE); + } else { + views.setViewVisibility(R.id.widget_empty, View.GONE); + for (int i = 0; i < ITEM_IDS.length; i++) { + if (i < tags.size()) { + TrendingDataFetcher.TrendingTag tag = tags.get(i); + views.setViewVisibility(ITEM_IDS[i], View.VISIBLE); + views.setTextViewText(TAG_NAME_IDS[i], "#" + tag.name); + views.setTextViewText(TAG_COUNT_IDS[i], + String.format(context.getString(R.string.widget_posts_today), tag.uses)); + } else { + views.setViewVisibility(ITEM_IDS[i], View.GONE); + } + } + } + + manager.updateAppWidget(widgetId, views); + }); + } + + private static RemoteViews buildLoadingView(Context context) { + RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_trending); + views.setTextViewText(R.id.tag_name_1, "Loading…"); + views.setViewVisibility(R.id.item_1, View.VISIBLE); + views.setViewVisibility(R.id.tag_count_1, View.GONE); + for (int i = 1; i < ITEM_IDS.length; i++) { + views.setViewVisibility(ITEM_IDS[i], View.GONE); + } + views.setViewVisibility(R.id.widget_empty, View.GONE); + return views; + } + + static String getServer(Context context) { + SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + return prefs.getString(PREF_SERVER, DEFAULT_SERVER); + } +} diff --git a/android/app/src/main/java/place/coho/app/WidgetBridge.java b/android/app/src/main/java/place/coho/app/WidgetBridge.java new file mode 100644 index 0000000..2443430 --- /dev/null +++ b/android/app/src/main/java/place/coho/app/WidgetBridge.java @@ -0,0 +1,51 @@ +package place.coho.app; + +import android.appwidget.AppWidgetManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.SharedPreferences; + +import com.getcapacitor.JSObject; +import com.getcapacitor.Plugin; +import com.getcapacitor.PluginCall; +import com.getcapacitor.PluginMethod; +import com.getcapacitor.annotation.CapacitorPlugin; + +/** + * Simple Capacitor plugin that bridges the web app's server URL + * to SharedPreferences so the Android widget can read it. + */ +@CapacitorPlugin(name = "WidgetBridge") +public class WidgetBridge extends Plugin { + + @PluginMethod + public void setServer(PluginCall call) { + String server = call.getString("server", TrendingWidget.DEFAULT_SERVER); + SharedPreferences prefs = getContext() + .getSharedPreferences(TrendingWidget.PREFS_NAME, Context.MODE_PRIVATE); + prefs.edit().putString(TrendingWidget.PREF_SERVER, server).apply(); + + // Trigger widget refresh so it picks up the new server + refreshWidgets(); + + call.resolve(); + } + + @PluginMethod + public void refresh(PluginCall call) { + refreshWidgets(); + call.resolve(); + } + + private void refreshWidgets() { + Context context = getContext(); + AppWidgetManager manager = AppWidgetManager.getInstance(context); + int[] ids = manager.getAppWidgetIds( + new ComponentName(context, TrendingWidget.class)); + if (ids != null && ids.length > 0) { + for (int id : ids) { + TrendingWidget.updateWidget(context, manager, id); + } + } + } +} diff --git a/android/app/src/main/res/drawable-night/widget_background.xml b/android/app/src/main/res/drawable-night/widget_background.xml new file mode 100644 index 0000000..68da970 --- /dev/null +++ b/android/app/src/main/res/drawable-night/widget_background.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/android/app/src/main/res/drawable/widget_background.xml b/android/app/src/main/res/drawable/widget_background.xml new file mode 100644 index 0000000..68da970 --- /dev/null +++ b/android/app/src/main/res/drawable/widget_background.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/android/app/src/main/res/drawable/widget_item_background.xml b/android/app/src/main/res/drawable/widget_item_background.xml new file mode 100644 index 0000000..a38bc80 --- /dev/null +++ b/android/app/src/main/res/drawable/widget_item_background.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/android/app/src/main/res/layout/widget_trending.xml b/android/app/src/main/res/layout/widget_trending.xml new file mode 100644 index 0000000..994eb8a --- /dev/null +++ b/android/app/src/main/res/layout/widget_trending.xml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/values-night/colors.xml b/android/app/src/main/res/values-night/colors.xml new file mode 100644 index 0000000..edcd899 --- /dev/null +++ b/android/app/src/main/res/values-night/colors.xml @@ -0,0 +1,7 @@ + + + #1C1B1F + #E6E1E5 + #CAC4D0 + #2B2930 + diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index 1c7f8c2..e2f4af1 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -2,4 +2,14 @@ #d6325c + + + #F3EDF7 + #d6325c + #1C1B1F + #49454F + #FFFFFF + #d6325c + #a8284a + #d6325c diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 5e13a05..fca752b 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -4,4 +4,9 @@ Coho place.coho.app place.coho.app + Trending on Mastodon + Shows trending hashtags from Mastodon + Tap to open Coho + Coho Trending + %s posts today diff --git a/android/app/src/main/res/xml/trending_widget_info.xml b/android/app/src/main/res/xml/trending_widget_info.xml new file mode 100644 index 0000000..5a9f818 --- /dev/null +++ b/android/app/src/main/res/xml/trending_widget_info.xml @@ -0,0 +1,16 @@ + + diff --git a/src/app-index.ts b/src/app-index.ts index add0fcd..d7edda4 100644 --- a/src/app-index.ts +++ b/src/app-index.ts @@ -301,6 +301,28 @@ export class AppIndex extends LitElement { private async syncCredentialsToIndexedDB() { await syncActiveToIndexedDb(); console.log('[App] Synced credentials to IndexedDB'); + + // Sync server URL to native SharedPreferences for the Android widget + this.syncServerToNativeWidget(); + } + + /** + * Pushes the current server URL to the native Android widget + * via the WidgetBridge Capacitor plugin, so the widget can + * fetch trending data from the correct Mastodon instance. + */ + private async syncServerToNativeWidget() { + try { + const { isNativePlatform } = await import('./utils/platform.js'); + if (!isNativePlatform()) return; + + const { registerPlugin } = await import('@capacitor/core'); + const WidgetBridge = registerPlugin('WidgetBridge'); + const server = localStorage.getItem('server') || 'mastodon.social'; + await (WidgetBridge as any).setServer({ server }); + } catch { + // Widget bridge not available — ignore + } } /** From 8132de0dfae1b0063a15ba2f24faa628844ba518 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Tue, 17 Mar 2026 21:44:37 -0700 Subject: [PATCH 14/26] support android theme color --- .../place/coho/app/DynamicThemeBridge.java | 38 +++++++++++++++++++ .../java/place/coho/app/MainActivity.java | 1 + src/app-index.ts | 13 ++++++- src/components/app-theme.ts | 38 +++++++++++-------- src/utils/dynamic-theme.ts | 25 ++++++++++++ 5 files changed, 98 insertions(+), 17 deletions(-) create mode 100644 android/app/src/main/java/place/coho/app/DynamicThemeBridge.java create mode 100644 src/utils/dynamic-theme.ts diff --git a/android/app/src/main/java/place/coho/app/DynamicThemeBridge.java b/android/app/src/main/java/place/coho/app/DynamicThemeBridge.java new file mode 100644 index 0000000..a458ea6 --- /dev/null +++ b/android/app/src/main/java/place/coho/app/DynamicThemeBridge.java @@ -0,0 +1,38 @@ +package place.coho.app; + +import android.os.Build; + +import androidx.core.content.ContextCompat; + +import com.getcapacitor.JSObject; +import com.getcapacitor.Plugin; +import com.getcapacitor.PluginCall; +import com.getcapacitor.PluginMethod; +import com.getcapacitor.annotation.CapacitorPlugin; + +/** + * Capacitor plugin that exposes the Android Material You dynamic accent color + * to the web layer. On API 31+ (Android 12+), reads the system wallpaper-derived + * accent color. On older versions, returns null so the web app can fall back. + */ +@CapacitorPlugin(name = "DynamicThemeBridge") +public class DynamicThemeBridge extends Plugin { + + @PluginMethod + public void getAccentColor(PluginCall call) { + JSObject result = new JSObject(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + int colorInt = ContextCompat.getColor( + getContext(), android.R.color.system_accent1_500); + String hex = String.format("#%06X", (0xFFFFFF & colorInt)); + result.put("color", hex); + result.put("supported", true); + } else { + result.put("color", null); + result.put("supported", false); + } + + call.resolve(result); + } +} diff --git a/android/app/src/main/java/place/coho/app/MainActivity.java b/android/app/src/main/java/place/coho/app/MainActivity.java index 106aa6f..920623d 100644 --- a/android/app/src/main/java/place/coho/app/MainActivity.java +++ b/android/app/src/main/java/place/coho/app/MainActivity.java @@ -8,6 +8,7 @@ public class MainActivity extends BridgeActivity { @Override protected void onCreate(Bundle savedInstanceState) { registerPlugin(WidgetBridge.class); + registerPlugin(DynamicThemeBridge.class); super.onCreate(savedInstanceState); } } diff --git a/src/app-index.ts b/src/app-index.ts index d7edda4..b9592b8 100644 --- a/src/app-index.ts +++ b/src/app-index.ts @@ -143,10 +143,19 @@ export class AppIndex extends LitElement { const settings = await getSettings(); console.log('settings', settings); - const potentialColor = settings.primary_color; - const { applyThemeColor } = await import('./utils/theme-color'); + // On Android Capacitor, always use the device's Material You accent color + const { getAndroidDynamicColor } = await import('./utils/dynamic-theme'); + const deviceColor = await getAndroidDynamicColor(); + if (deviceColor) { + localStorage.setItem('coho-theme-color', deviceColor); + applyThemeColor(deviceColor, { useIdleCallback: true }); + return; + } + + const potentialColor = settings.primary_color; + if (potentialColor) { // Sync to localStorage for instant theme on next load (migration for existing users) if (!localStorage.getItem('coho-theme-color')) { diff --git a/src/components/app-theme.ts b/src/components/app-theme.ts index 39f2d80..c29155a 100644 --- a/src/components/app-theme.ts +++ b/src/components/app-theme.ts @@ -6,6 +6,7 @@ import './md/md-icon.js'; import { getSettings, setSettings, Settings } from '../services/settings'; import { applyThemeColor } from '../utils/theme-color'; +import { getAndroidDynamicColor } from '../utils/dynamic-theme'; @customElement('app-theme') export class AppTheme extends LitElement { @@ -144,24 +145,31 @@ export class AppTheme extends LitElement { this.settings = await getSettings(); console.log('this.settings', this.settings); - const potentialColor = this.settings.primary_color; - const potentialFontSize = this.settings.font_size; - - if (potentialColor) { - this.primary_color = potentialColor; - applyThemeColor(potentialColor); + // On Android Capacitor, device color always wins + const deviceColor = await getAndroidDynamicColor(); + if (deviceColor) { + this.primary_color = deviceColor; + applyThemeColor(deviceColor); } else { - // get css variable color - const color = getComputedStyle(document.body).getPropertyValue( - '--sl-color-primary-600' - ); - this.primary_color = color; - - document - .querySelector('html')! - .style.setProperty('--primary-color', color); + const potentialColor = this.settings.primary_color; + + if (potentialColor) { + this.primary_color = potentialColor; + applyThemeColor(potentialColor); + } else { + // get css variable color + const color = getComputedStyle(document.body).getPropertyValue( + '--sl-color-primary-600' + ); + this.primary_color = color; + + document + .querySelector('html')! + .style.setProperty('--primary-color', color); + } } + const potentialFontSize = this.settings.font_size; if (potentialFontSize) { this.font_size = potentialFontSize; document.body.style.setProperty( diff --git a/src/utils/dynamic-theme.ts b/src/utils/dynamic-theme.ts new file mode 100644 index 0000000..0322ba7 --- /dev/null +++ b/src/utils/dynamic-theme.ts @@ -0,0 +1,25 @@ +import { isNativePlatform, getPlatform } from './platform'; + +interface DynamicThemePlugin { + getAccentColor(): Promise<{ color: string | null; supported: boolean }>; +} + +/** + * Returns the Android Material You dynamic accent color as a hex string, + * or null when running as a PWA or on unsupported Android versions (< 12). + */ +export async function getAndroidDynamicColor(): Promise { + if (!isNativePlatform() || getPlatform() !== 'android') { + return null; + } + + try { + const { registerPlugin } = await import('@capacitor/core'); + const DynamicThemeBridge = + registerPlugin('DynamicThemeBridge'); + const result = await DynamicThemeBridge.getAccentColor(); + return result.supported ? result.color : null; + } catch { + return null; + } +} From 10ead51810415439b14b14a18b74e6c83e070ca0 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Tue, 17 Mar 2026 22:24:14 -0700 Subject: [PATCH 15/26] widget uses system theme color + native share target support --- android/app/src/main/AndroidManifest.xml | 22 +++ .../java/place/coho/app/MainActivity.java | 17 ++ .../place/coho/app/ShareTargetBridge.java | 185 ++++++++++++++++++ .../src/main/res/values-night-v31/colors.xml | 9 + .../app/src/main/res/values-night/colors.xml | 1 + .../app/src/main/res/values-v31/colors.xml | 9 + src/components/post-dialog.ts | 8 +- src/pages/app-home.ts | 60 +++++- src/services/native-share-target.ts | 116 +++++++++++ 9 files changed, 424 insertions(+), 3 deletions(-) create mode 100644 android/app/src/main/java/place/coho/app/ShareTargetBridge.java create mode 100644 android/app/src/main/res/values-night-v31/colors.xml create mode 100644 android/app/src/main/res/values-v31/colors.xml create mode 100644 src/services/native-share-target.ts diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 2e94d05..995c767 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -30,6 +30,28 @@ + + + + + + + + + + + + + + + + + + + + + + uris = new ArrayList<>(); + + if (isSend) { + Uri singleUri = intent.getParcelableExtra(Intent.EXTRA_STREAM); + if (singleUri != null) { + uris.add(singleUri); + } + } else if (isSendMultiple) { + List multiUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); + if (multiUris != null) { + uris.addAll(multiUris); + } + } + + ContentResolver resolver = getContext().getContentResolver(); + File cacheDir = new File(getContext().getCacheDir(), "share_target"); + if (!cacheDir.exists()) { + cacheDir.mkdirs(); + } + + for (Uri uri : uris) { + try { + String mimeType = resolver.getType(uri); + String fileName = getFileName(resolver, uri); + if (fileName == null) { + // Generate a name from MIME type + String ext = MimeTypeMap.getSingleton() + .getExtensionFromMimeType(mimeType); + fileName = UUID.randomUUID().toString() + (ext != null ? "." + ext : ""); + } + + // Copy to internal cache + File destFile = new File(cacheDir, fileName); + try (InputStream in = resolver.openInputStream(uri); + FileOutputStream out = new FileOutputStream(destFile)) { + if (in == null) continue; + byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = in.read(buffer)) != -1) { + out.write(buffer, 0, bytesRead); + } + } + + JSObject fileObj = new JSObject(); + fileObj.put("name", fileName); + fileObj.put("type", mimeType != null ? mimeType : "application/octet-stream"); + fileObj.put("path", destFile.getAbsolutePath()); + fileObj.put("size", destFile.length()); + filesArray.put(fileObj); + } catch (IOException e) { + // Skip files that fail to copy + System.err.println("[ShareTargetBridge] Failed to copy shared file: " + e.getMessage()); + } + } + + if (filesArray.length() > 0) { + result.put("files", filesArray); + } + + call.resolve(result); + } + + @PluginMethod + public void clearSharedContent(PluginCall call) { + // Clear the intent so re-opening the app doesn't re-trigger the share + Intent intent = getActivity().getIntent(); + if (intent != null) { + intent.setAction(null); + intent.removeExtra(Intent.EXTRA_TEXT); + intent.removeExtra(Intent.EXTRA_SUBJECT); + intent.removeExtra(Intent.EXTRA_STREAM); + } + + // Clean up cached files + File cacheDir = new File(getContext().getCacheDir(), "share_target"); + if (cacheDir.exists()) { + File[] files = cacheDir.listFiles(); + if (files != null) { + for (File file : files) { + file.delete(); + } + } + } + + call.resolve(); + } + + /** + * Notify the web layer that a new share intent arrived while the app + * was already running (via onNewIntent in MainActivity). + */ + public void notifyShareIntent() { + notifyListeners("shareIntent", new JSObject()); + } + + private static String getFileName(ContentResolver resolver, Uri uri) { + if ("content".equals(uri.getScheme())) { + try (Cursor cursor = resolver.query(uri, null, null, null, null)) { + if (cursor != null && cursor.moveToFirst()) { + int idx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + if (idx >= 0) { + return cursor.getString(idx); + } + } + } + } + // Fall back to last path segment + String path = uri.getLastPathSegment(); + return path; + } +} diff --git a/android/app/src/main/res/values-night-v31/colors.xml b/android/app/src/main/res/values-night-v31/colors.xml new file mode 100644 index 0000000..c170ce9 --- /dev/null +++ b/android/app/src/main/res/values-night-v31/colors.xml @@ -0,0 +1,9 @@ + + + + @android:color/system_neutral1_800 + @android:color/system_accent1_200 + @android:color/system_neutral1_100 + @android:color/system_neutral2_200 + @android:color/system_neutral1_700 + diff --git a/android/app/src/main/res/values-night/colors.xml b/android/app/src/main/res/values-night/colors.xml index edcd899..88b8422 100644 --- a/android/app/src/main/res/values-night/colors.xml +++ b/android/app/src/main/res/values-night/colors.xml @@ -1,6 +1,7 @@ #1C1B1F + #E6A3B5 #E6E1E5 #CAC4D0 #2B2930 diff --git a/android/app/src/main/res/values-v31/colors.xml b/android/app/src/main/res/values-v31/colors.xml new file mode 100644 index 0000000..3d8ddfb --- /dev/null +++ b/android/app/src/main/res/values-v31/colors.xml @@ -0,0 +1,9 @@ + + + + @android:color/system_neutral2_50 + @android:color/system_accent1_600 + @android:color/system_neutral1_900 + @android:color/system_neutral2_700 + @android:color/system_neutral1_10 + diff --git a/src/components/post-dialog.ts b/src/components/post-dialog.ts index 2dd468b..9ca062c 100644 --- a/src/components/post-dialog.ts +++ b/src/components/post-dialog.ts @@ -165,7 +165,8 @@ export class PostDialog extends LitElement { public async openNewDialog( shareName?: string, - origin?: { x: number; y: number } + origin?: { x: number; y: number }, + shareText?: string ) { await this.updateComplete; await customElements.whenDefined('md-dialog'); @@ -176,6 +177,11 @@ export class PostDialog extends LitElement { this.notifyDialog?.show(); + // Pre-fill composer with shared text (e.g. a URL from another app) + if (shareText && this.composer) { + this.composer.value = shareText; + } + const nameToUse = shareName ?? new URLSearchParams(window.location.search).get('name'); diff --git a/src/pages/app-home.ts b/src/pages/app-home.ts index 018eaa2..2528a47 100644 --- a/src/pages/app-home.ts +++ b/src/pages/app-home.ts @@ -226,8 +226,14 @@ export class AppHome extends LitElement { await this.shareTarget(name); } } + + // Check for native Android share intent (cold start) + this._checkNativeShareTarget(); }, 1000); + // Listen for share intents that arrive while the app is already open + this._initNativeShareListener(); + window.requestIdleCallback(async () => { // Import and init key shortcuts const { init } = await import('../utils/key-shortcuts'); @@ -401,6 +407,49 @@ export class AppHome extends LitElement { } } + private _nativeShareCleanup: { remove: () => void } | null = null; + + /** + * Check for shared content from an Android share intent (cold start). + */ + private async _checkNativeShareTarget() { + const { checkNativeShare } = + await import('../services/native-share-target'); + const result = await checkNativeShare(); + if (result.hasShare) { + this._handleNativeShare(result); + } + } + + /** + * Listen for Android share intents that arrive while the app is already + * running (warm start via onNewIntent). + */ + private async _initNativeShareListener() { + const { onNativeShareIntent } = + await import('../services/native-share-target'); + this._nativeShareCleanup = onNativeShareIntent((result) => { + this._handleNativeShare(result); + }); + } + + /** + * Process a native share intent result — open the compose dialog with + * the shared media file and/or pre-filled text. + */ + private async _handleNativeShare( + result: import('../services/native-share-target').NativeShareResult + ) { + if (result.cachedFileName) { + // Media share — the file is already in the shareTarget cache, + // so openNewDialog → post-dialog shareTarget will pick it up. + await this.openNewDialog(result.cachedFileName, undefined, result.text); + } else if (result.text) { + // Text-only share (e.g. a URL from Chrome) + await this.openNewDialog(undefined, undefined, result.text); + } + } + handlePrimaryColor(color: string) { document.documentElement.style.setProperty('--sl-color-primary-600', color); localStorage.setItem('primary_color', color); @@ -415,7 +464,11 @@ export class AppHome extends LitElement { return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 }; } - async openNewDialog(shareName?: string, origin?: { x: number; y: number }) { + async openNewDialog( + shareName?: string, + origin?: { x: number; y: number }, + shareText?: string + ) { // Lazy load post-dialog component if (!this.postDialogLoaded) { if (await lazyLoad('postDialog', componentLoaders.postDialog)) { @@ -435,7 +488,7 @@ export class AppHome extends LitElement { // Wait for the post-dialog's own shadow DOM to render if (this.postDialog) { await this.postDialog.updateComplete; - this.postDialog.openNewDialog(shareName, origin); + this.postDialog.openNewDialog(shareName, origin, shareText); } } @@ -662,6 +715,9 @@ export class AppHome extends LitElement { // Remove keyboard shortcut new post dialog listener window.removeEventListener('open-post-dialog', this._handleOpenPostDialog); + // Remove native share intent listener + this._nativeShareCleanup?.remove(); + const lastPageID = sessionStorage.getItem(getLatestReadStorageKey()); console.log('lastPageID', lastPageID); if (lastPageID) { diff --git a/src/services/native-share-target.ts b/src/services/native-share-target.ts new file mode 100644 index 0000000..63932e6 --- /dev/null +++ b/src/services/native-share-target.ts @@ -0,0 +1,116 @@ +import { Capacitor, registerPlugin } from '@capacitor/core'; + +interface SharedFile { + name: string; + type: string; + path: string; + size: number; +} + +interface SharedContent { + hasShare: boolean; + text?: string; + subject?: string; + files?: SharedFile[]; +} + +interface ShareTargetBridgePlugin { + getSharedContent(): Promise; + clearSharedContent(): Promise; + addListener( + event: 'shareIntent', + callback: () => void + ): Promise<{ remove: () => void }>; +} + +const ShareTargetBridge = + registerPlugin('ShareTargetBridge'); + +export interface NativeShareResult { + hasShare: boolean; + text?: string; + subject?: string; + /** Name of the file written to the shareTarget cache (for media shares). */ + cachedFileName?: string; +} + +/** + * Check for shared content from an Android ACTION_SEND intent. + * If media files were shared, they are written into the Cache API using + * the same key format as the PWA share target (`/_share/{name}`), + * so the existing post-dialog shareTarget flow can pick them up. + */ +export async function checkNativeShare(): Promise { + if (!Capacitor.isNativePlatform()) { + return { hasShare: false }; + } + + const shared = await ShareTargetBridge.getSharedContent(); + if (!shared.hasShare) { + return { hasShare: false }; + } + + const result: NativeShareResult = { + hasShare: true, + text: shared.text, + subject: shared.subject, + }; + + // If media files were shared, write the first one into the Cache API + // so the existing compose-dialog media flow can handle it. + if (shared.files && shared.files.length > 0) { + const file = shared.files[0]; + const webPath = Capacitor.convertFileSrc(file.path); + + const response = await fetch(webPath); + const blob = await response.blob(); + + const cache = await caches.open('shareTarget'); + const cacheKey = `/_share/${encodeURIComponent(file.name)}`; + await cache.put( + cacheKey, + new Response(blob, { + headers: { + 'content-length': file.size.toString(), + 'content-type': file.type, + }, + }) + ); + + result.cachedFileName = file.name; + } + + // Clear the intent so it doesn't re-trigger on next resume + await ShareTargetBridge.clearSharedContent(); + + return result; +} + +/** + * Listen for share intents that arrive while the app is already open + * (warm start via onNewIntent). Calls the handler with the shared content. + */ +export function onNativeShareIntent( + handler: (result: NativeShareResult) => void +): { remove: () => void } { + if (!Capacitor.isNativePlatform()) { + return { remove: () => {} }; + } + + let listenerHandle: { remove: () => void } | null = null; + + ShareTargetBridge.addListener('shareIntent', async () => { + const result = await checkNativeShare(); + if (result.hasShare) { + handler(result); + } + }).then((handle) => { + listenerHandle = handle; + }); + + return { + remove: () => { + listenerHandle?.remove(); + }, + }; +} From e202ab6bdffc255bdb3408f67ac99fb3b9d57e9b Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Tue, 17 Mar 2026 22:52:27 -0700 Subject: [PATCH 16/26] shortcuts + predictive back --- android/app/src/main/AndroidManifest.xml | 6 ++ .../java/place/coho/app/MainActivity.java | 57 +++++++++++++++ .../main/res/drawable/ic_shortcut_home.xml | 12 ++++ .../res/drawable/ic_shortcut_messages.xml | 12 ++++ .../res/drawable/ic_shortcut_new_post.xml | 12 ++++ .../drawable/ic_shortcut_notifications.xml | 12 ++++ .../main/res/drawable/ic_shortcut_search.xml | 12 ++++ android/app/src/main/res/values/strings.xml | 12 ++++ android/app/src/main/res/xml/shortcuts.xml | 69 +++++++++++++++++++ 9 files changed, 204 insertions(+) create mode 100644 android/app/src/main/res/drawable/ic_shortcut_home.xml create mode 100644 android/app/src/main/res/drawable/ic_shortcut_messages.xml create mode 100644 android/app/src/main/res/drawable/ic_shortcut_new_post.xml create mode 100644 android/app/src/main/res/drawable/ic_shortcut_notifications.xml create mode 100644 android/app/src/main/res/drawable/ic_shortcut_search.xml create mode 100644 android/app/src/main/res/xml/shortcuts.xml diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 995c767..5d956cf 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -15,6 +15,7 @@ android:label="@string/title_activity_main" android:theme="@style/AppTheme.NoActionBarLaunch" android:launchMode="singleTask" + android:enableOnBackInvokedCallback="true" android:exported="true"> @@ -22,6 +23,11 @@ + + + diff --git a/android/app/src/main/java/place/coho/app/MainActivity.java b/android/app/src/main/java/place/coho/app/MainActivity.java index 45c7a58..81e4b3b 100644 --- a/android/app/src/main/java/place/coho/app/MainActivity.java +++ b/android/app/src/main/java/place/coho/app/MainActivity.java @@ -1,17 +1,45 @@ package place.coho.app; import android.content.Intent; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import android.webkit.WebView; +import android.window.OnBackInvokedCallback; +import android.window.OnBackInvokedDispatcher; import com.getcapacitor.BridgeActivity; public class MainActivity extends BridgeActivity { + + private OnBackInvokedCallback backCallback; + @Override protected void onCreate(Bundle savedInstanceState) { registerPlugin(WidgetBridge.class); registerPlugin(DynamicThemeBridge.class); registerPlugin(ShareTargetBridge.class); super.onCreate(savedInstanceState); + + // If launched from a shortcut (ACTION_VIEW with localhost data), + // navigate the WebView to the shortcut's target path. + handleShortcutIntent(getIntent()); + + // Register predictive back callback for Android 13+ (API 33). + // This replaces the deprecated onBackPressed() and enables the + // native predictive back animation (peek at previous page / home). + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + backCallback = () -> { + WebView webView = getBridge().getWebView(); + if (webView.canGoBack()) { + webView.goBack(); + } else { + finish(); + } + }; + getOnBackInvokedDispatcher().registerOnBackInvokedCallback( + OnBackInvokedDispatcher.PRIORITY_DEFAULT, backCallback); + } } @Override @@ -26,6 +54,35 @@ protected void onNewIntent(Intent intent) { if (plugin != null) { plugin.notifyShareIntent(); } + } else if (Intent.ACTION_VIEW.equals(action)) { + // Handle shortcut taps when the app is already running + handleShortcutIntent(intent); + } + } + + /** + * If the intent carries a localhost URL (from a static shortcut), + * extract the path + query and navigate the WebView there. + */ + private void handleShortcutIntent(Intent intent) { + if (intent == null || !Intent.ACTION_VIEW.equals(intent.getAction())) { + return; } + Uri data = intent.getData(); + if (data == null) return; + + String host = data.getHost(); + if (!"localhost".equals(host)) return; + + String path = data.getPath(); + if (path == null || path.equals("/")) return; + + String query = data.getQuery(); + String url = path + (query != null ? "?" + query : ""); + + // Wait for the bridge to be ready, then navigate + getBridge().getWebView().post(() -> { + getBridge().getWebView().loadUrl("https://localhost" + url); + }); } } diff --git a/android/app/src/main/res/drawable/ic_shortcut_home.xml b/android/app/src/main/res/drawable/ic_shortcut_home.xml new file mode 100644 index 0000000..8f71e5d --- /dev/null +++ b/android/app/src/main/res/drawable/ic_shortcut_home.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/android/app/src/main/res/drawable/ic_shortcut_messages.xml b/android/app/src/main/res/drawable/ic_shortcut_messages.xml new file mode 100644 index 0000000..ef70ebb --- /dev/null +++ b/android/app/src/main/res/drawable/ic_shortcut_messages.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/android/app/src/main/res/drawable/ic_shortcut_new_post.xml b/android/app/src/main/res/drawable/ic_shortcut_new_post.xml new file mode 100644 index 0000000..d2a9a3c --- /dev/null +++ b/android/app/src/main/res/drawable/ic_shortcut_new_post.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/android/app/src/main/res/drawable/ic_shortcut_notifications.xml b/android/app/src/main/res/drawable/ic_shortcut_notifications.xml new file mode 100644 index 0000000..7e29295 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_shortcut_notifications.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/android/app/src/main/res/drawable/ic_shortcut_search.xml b/android/app/src/main/res/drawable/ic_shortcut_search.xml new file mode 100644 index 0000000..63e08ce --- /dev/null +++ b/android/app/src/main/res/drawable/ic_shortcut_search.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index fca752b..5543993 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -9,4 +9,16 @@ Tap to open Coho Coho Trending %s posts today + + + Home + Go to home timeline + Explore + Explore trending content + Notifications + View your notifications + Messages + View your messages + New Post + Compose a new post diff --git a/android/app/src/main/res/xml/shortcuts.xml b/android/app/src/main/res/xml/shortcuts.xml new file mode 100644 index 0000000..8a6d098 --- /dev/null +++ b/android/app/src/main/res/xml/shortcuts.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + From b5b587beaf2061f4c1e48d269085d7b39973d1ea Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Wed, 18 Mar 2026 20:23:05 -0700 Subject: [PATCH 17/26] fix predictive back --- android/app/build.gradle | 13 +- .../main/java/place/coho/app/AiBridge.java | 366 ++++++++++++++++++ .../java/place/coho/app/MainActivity.java | 53 ++- android/variables.gradle | 2 +- capacitor.config.ts | 6 +- src/services/ai.ts | 164 ++++++-- src/services/native-ai.ts | 136 +++++++ 7 files changed, 693 insertions(+), 47 deletions(-) create mode 100644 android/app/src/main/java/place/coho/app/AiBridge.java create mode 100644 src/services/native-ai.ts diff --git a/android/app/build.gradle b/android/app/build.gradle index 166e28c..c3c224e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "place.coho.app" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 2 - versionName "1.1" + versionCode 3 + versionName "1.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. @@ -36,6 +36,15 @@ dependencies { implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion" implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion" implementation project(':capacitor-android') + + // On-device AI: ML Kit Language Identification + Translation + implementation 'com.google.mlkit:language-id:17.0.6' + implementation 'com.google.mlkit:translate:17.0.3' + + // On-device AI: ML Kit GenAI (Gemini Nano) – image description + proofreading + implementation 'com.google.mlkit:genai-image-description:1.0.0-beta1' + implementation 'com.google.mlkit:genai-proofreading:1.0.0-beta1' + testImplementation "junit:junit:$junitVersion" androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" diff --git a/android/app/src/main/java/place/coho/app/AiBridge.java b/android/app/src/main/java/place/coho/app/AiBridge.java new file mode 100644 index 0000000..5435d84 --- /dev/null +++ b/android/app/src/main/java/place/coho/app/AiBridge.java @@ -0,0 +1,366 @@ +package place.coho.app; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.Base64; +import android.util.Log; + +import com.getcapacitor.JSArray; +import com.getcapacitor.JSObject; +import com.getcapacitor.Plugin; +import com.getcapacitor.PluginCall; +import com.getcapacitor.PluginMethod; +import com.getcapacitor.annotation.CapacitorPlugin; + +import com.google.mlkit.nl.languageid.LanguageIdentification; +import com.google.mlkit.nl.languageid.LanguageIdentifier; +import com.google.mlkit.nl.translate.TranslateLanguage; +import com.google.mlkit.nl.translate.Translation; +import com.google.mlkit.nl.translate.Translator; +import com.google.mlkit.nl.translate.TranslatorOptions; + +import com.google.mlkit.genai.common.FeatureStatus; +import com.google.mlkit.genai.imagedescription.ImageDescriber; +import com.google.mlkit.genai.imagedescription.ImageDescriberOptions; +import com.google.mlkit.genai.imagedescription.ImageDescription; +import com.google.mlkit.genai.imagedescription.ImageDescriptionRequest; +import com.google.mlkit.genai.proofreading.Proofreader; +import com.google.mlkit.genai.proofreading.ProofreaderOptions; +import com.google.mlkit.genai.proofreading.Proofreading; +import com.google.mlkit.genai.proofreading.ProofreadingRequest; +import com.google.mlkit.genai.proofreading.ProofreadingResult; +import com.google.mlkit.genai.proofreading.ProofreadingSuggestion; + +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Capacitor plugin that exposes Android on-device AI capabilities to the web layer: + * - Translation via ML Kit + * - Alt text generation via ML Kit GenAI Image Description (Gemini Nano) + * - Proofreading via ML Kit GenAI Proofreading (Gemini Nano) + */ +@CapacitorPlugin(name = "AiBridge") +public class AiBridge extends Plugin { + + private static final String TAG = "AiBridge"; + private static final ExecutorService executor = Executors.newCachedThreadPool(); + + // ── Language Detection (ML Kit) ───────────────────────────────────── + + @PluginMethod + public void detectLanguage(PluginCall call) { + String text = call.getString("text"); + if (text == null || text.isEmpty()) { + call.reject("text is required"); + return; + } + + LanguageIdentifier identifier = LanguageIdentification.getClient(); + identifier.identifyLanguage(text) + .addOnSuccessListener(languageCode -> { + JSObject result = new JSObject(); + // ML Kit returns "und" for undetermined + result.put("language", "und".equals(languageCode) ? "en" : languageCode); + call.resolve(result); + identifier.close(); + }) + .addOnFailureListener(e -> { + Log.e(TAG, "Language detection failed", e); + JSObject result = new JSObject(); + result.put("language", "en"); + call.resolve(result); + identifier.close(); + }); + } + + // ── Translation (ML Kit) ────────────────────────────────────────────── + + @PluginMethod + public void translate(PluginCall call) { + String text = call.getString("text"); + String sourceLang = call.getString("sourceLanguage", "en"); + String targetLang = call.getString("targetLanguage", "en"); + + if (text == null || text.isEmpty()) { + call.reject("text is required"); + return; + } + + String sourceTag = mapToMlKitLanguage(sourceLang); + String targetTag = mapToMlKitLanguage(targetLang); + + if (sourceTag == null || targetTag == null) { + call.reject("Unsupported language pair: " + sourceLang + " -> " + targetLang); + return; + } + + TranslatorOptions options = new TranslatorOptions.Builder() + .setSourceLanguage(sourceTag) + .setTargetLanguage(targetTag) + .build(); + + Translator translator = Translation.getClient(options); + + // Ensure models are downloaded, then translate + translator.downloadModelIfNeeded() + .addOnSuccessListener(unused -> + translator.translate(text) + .addOnSuccessListener(translatedText -> { + JSObject result = new JSObject(); + result.put("translatedText", translatedText); + call.resolve(result); + translator.close(); + }) + .addOnFailureListener(e -> { + Log.e(TAG, "Translation failed", e); + call.reject("Translation failed: " + e.getMessage()); + translator.close(); + }) + ) + .addOnFailureListener(e -> { + Log.e(TAG, "Model download failed", e); + call.reject("Translation model download failed: " + e.getMessage()); + translator.close(); + }); + } + + // ── Alt Text Generation (ML Kit GenAI Image Description) ───────────── + + @PluginMethod + public void generateAltText(PluginCall call) { + String imageBase64 = call.getString("imageBase64"); + + if (imageBase64 == null || imageBase64.isEmpty()) { + call.reject("imageBase64 is required"); + return; + } + + try { + // Strip data URI prefix if present + String base64Data = imageBase64; + if (base64Data.contains(",")) { + base64Data = base64Data.substring(base64Data.indexOf(",") + 1); + } + + byte[] imageBytes = Base64.decode(base64Data, Base64.DEFAULT); + Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length); + + if (bitmap == null) { + call.reject("Failed to decode image from base64"); + return; + } + + executor.execute(() -> { + ImageDescriber describer = null; + try { + ImageDescriberOptions options = ImageDescriberOptions.builder(getContext()).build(); + describer = ImageDescription.getClient(options); + + int status = describer.checkFeatureStatus().get(); + if (status == FeatureStatus.UNAVAILABLE) { + call.reject("Image description not available on this device"); + return; + } + + ImageDescriptionRequest request = ImageDescriptionRequest.builder(bitmap).build(); + String description = describer.runInference(request).get().getDescription(); + + JSObject result = new JSObject(); + result.put("altText", description != null ? description.trim() : ""); + call.resolve(result); + } catch (Exception e) { + Log.e(TAG, "Alt text generation failed", e); + call.reject("Alt text generation failed: " + e.getMessage()); + } finally { + if (describer != null) describer.close(); + } + }); + + } catch (Exception e) { + Log.e(TAG, "Alt text generation error", e); + call.reject("Alt text generation error: " + e.getMessage()); + } + } + + // ── Proofreading (ML Kit GenAI) ─────────────────────────────────────── + + @PluginMethod + public void proofread(PluginCall call) { + String text = call.getString("text"); + + if (text == null || text.isEmpty()) { + call.reject("text is required"); + return; + } + + executor.execute(() -> { + Proofreader proofreader = null; + try { + ProofreaderOptions options = ProofreaderOptions.builder(getContext()) + .setInputType(ProofreaderOptions.InputType.KEYBOARD) + .setLanguage(ProofreaderOptions.Language.ENGLISH) + .build(); + proofreader = Proofreading.getClient(options); + + int status = proofreader.checkFeatureStatus().get(); + if (status == FeatureStatus.UNAVAILABLE) { + call.reject("Proofreading not available on this device"); + return; + } + + ProofreadingRequest request = ProofreadingRequest.builder(text).build(); + ProofreadingResult proofResult = proofreader.runInference(request).get(); + List suggestions = proofResult.getResults(); + + JSObject result = new JSObject(); + if (suggestions != null && !suggestions.isEmpty()) { + // Top suggestion is sorted by highest confidence + result.put("correctedInput", suggestions.get(0).getText()); + } else { + result.put("correctedInput", text); + } + // ML Kit returns whole-text suggestions, not granular corrections + result.put("corrections", new JSArray()); + call.resolve(result); + } catch (Exception e) { + Log.e(TAG, "Proofreading failed", e); + call.reject("Proofreading failed: " + e.getMessage()); + } finally { + if (proofreader != null) proofreader.close(); + } + }); + } + + // ── Availability Check ──────────────────────────────────────────────── + + @PluginMethod + public void checkAvailability(PluginCall call) { + executor.execute(() -> { + boolean altTextAvailable = false; + boolean proofreadingAvailable = false; + + // Check image description availability + ImageDescriber describer = null; + try { + ImageDescriberOptions idOptions = ImageDescriberOptions.builder(getContext()).build(); + describer = ImageDescription.getClient(idOptions); + int status = describer.checkFeatureStatus().get(); + Log.i(TAG, "Image description feature status: " + status + + " (AVAILABLE=" + FeatureStatus.AVAILABLE + + ", DOWNLOADABLE=" + FeatureStatus.DOWNLOADABLE + + ", DOWNLOADING=" + FeatureStatus.DOWNLOADING + + ", UNAVAILABLE=" + FeatureStatus.UNAVAILABLE + ")"); + altTextAvailable = (status != FeatureStatus.UNAVAILABLE); + } catch (Exception e) { + Log.e(TAG, "Image description check failed", e); + } finally { + if (describer != null) describer.close(); + } + + // Check proofreading availability + Proofreader proofreader = null; + try { + ProofreaderOptions prOptions = ProofreaderOptions.builder(getContext()) + .setInputType(ProofreaderOptions.InputType.KEYBOARD) + .setLanguage(ProofreaderOptions.Language.ENGLISH) + .build(); + proofreader = Proofreading.getClient(prOptions); + int status = proofreader.checkFeatureStatus().get(); + Log.i(TAG, "Proofreading feature status: " + status + + " (AVAILABLE=" + FeatureStatus.AVAILABLE + + ", DOWNLOADABLE=" + FeatureStatus.DOWNLOADABLE + + ", DOWNLOADING=" + FeatureStatus.DOWNLOADING + + ", UNAVAILABLE=" + FeatureStatus.UNAVAILABLE + ")"); + proofreadingAvailable = (status != FeatureStatus.UNAVAILABLE); + } catch (Exception e) { + Log.e(TAG, "Proofreading check failed", e); + } finally { + if (proofreader != null) proofreader.close(); + } + + Log.i(TAG, "AI capabilities: translation=true, altText=" + altTextAvailable + + ", proofreading=" + proofreadingAvailable); + + JSObject result = new JSObject(); + result.put("translation", true); + result.put("altText", altTextAvailable); + result.put("proofreading", proofreadingAvailable); + call.resolve(result); + }); + } + + // ── Helpers ─────────────────────────────────────────────────────────── + + /** + * Map a BCP-47 language tag (or common shorthand) to an ML Kit + * TranslateLanguage constant. Returns null if unsupported. + */ + private String mapToMlKitLanguage(String langCode) { + if (langCode == null) return null; + // Normalize: take first segment, lowercase + String code = langCode.split("-")[0].toLowerCase(); + switch (code) { + case "af": return TranslateLanguage.AFRIKAANS; + case "ar": return TranslateLanguage.ARABIC; + case "be": return TranslateLanguage.BELARUSIAN; + case "bg": return TranslateLanguage.BULGARIAN; + case "bn": return TranslateLanguage.BENGALI; + case "ca": return TranslateLanguage.CATALAN; + case "cs": return TranslateLanguage.CZECH; + case "cy": return TranslateLanguage.WELSH; + case "da": return TranslateLanguage.DANISH; + case "de": return TranslateLanguage.GERMAN; + case "el": return TranslateLanguage.GREEK; + case "en": return TranslateLanguage.ENGLISH; + case "eo": return TranslateLanguage.ESPERANTO; + case "es": return TranslateLanguage.SPANISH; + case "et": return TranslateLanguage.ESTONIAN; + case "fa": return TranslateLanguage.PERSIAN; + case "fi": return TranslateLanguage.FINNISH; + case "fr": return TranslateLanguage.FRENCH; + case "ga": return TranslateLanguage.IRISH; + case "gl": return TranslateLanguage.GALICIAN; + case "gu": return TranslateLanguage.GUJARATI; + case "he": return TranslateLanguage.HEBREW; + case "hi": return TranslateLanguage.HINDI; + case "hr": return TranslateLanguage.CROATIAN; + case "hu": return TranslateLanguage.HUNGARIAN; + case "id": return TranslateLanguage.INDONESIAN; + case "is": return TranslateLanguage.ICELANDIC; + case "it": return TranslateLanguage.ITALIAN; + case "ja": return TranslateLanguage.JAPANESE; + case "ka": return TranslateLanguage.GEORGIAN; + case "kn": return TranslateLanguage.KANNADA; + case "ko": return TranslateLanguage.KOREAN; + case "lt": return TranslateLanguage.LITHUANIAN; + case "lv": return TranslateLanguage.LATVIAN; + case "mk": return TranslateLanguage.MACEDONIAN; + case "mr": return TranslateLanguage.MARATHI; + case "ms": return TranslateLanguage.MALAY; + case "mt": return TranslateLanguage.MALTESE; + case "nl": return TranslateLanguage.DUTCH; + case "no": return TranslateLanguage.NORWEGIAN; + case "pl": return TranslateLanguage.POLISH; + case "pt": return TranslateLanguage.PORTUGUESE; + case "ro": return TranslateLanguage.ROMANIAN; + case "ru": return TranslateLanguage.RUSSIAN; + case "sk": return TranslateLanguage.SLOVAK; + case "sl": return TranslateLanguage.SLOVENIAN; + case "sq": return TranslateLanguage.ALBANIAN; + case "sv": return TranslateLanguage.SWEDISH; + case "sw": return TranslateLanguage.SWAHILI; + case "ta": return TranslateLanguage.TAMIL; + case "te": return TranslateLanguage.TELUGU; + case "th": return TranslateLanguage.THAI; + case "tl": return TranslateLanguage.TAGALOG; + case "tr": return TranslateLanguage.TURKISH; + case "uk": return TranslateLanguage.UKRAINIAN; + case "ur": return TranslateLanguage.URDU; + case "vi": return TranslateLanguage.VIETNAMESE; + case "zh": return TranslateLanguage.CHINESE; + default: return null; + } + } +} diff --git a/android/app/src/main/java/place/coho/app/MainActivity.java b/android/app/src/main/java/place/coho/app/MainActivity.java index 81e4b3b..53727d8 100644 --- a/android/app/src/main/java/place/coho/app/MainActivity.java +++ b/android/app/src/main/java/place/coho/app/MainActivity.java @@ -2,44 +2,61 @@ import android.content.Intent; import android.net.Uri; -import android.os.Build; import android.os.Bundle; import android.webkit.WebView; -import android.window.OnBackInvokedCallback; -import android.window.OnBackInvokedDispatcher; +import androidx.activity.OnBackPressedCallback; + +import com.getcapacitor.Bridge; import com.getcapacitor.BridgeActivity; +import com.getcapacitor.BridgeWebViewClient; public class MainActivity extends BridgeActivity { - private OnBackInvokedCallback backCallback; + private OnBackPressedCallback webViewBackCallback; @Override protected void onCreate(Bundle savedInstanceState) { registerPlugin(WidgetBridge.class); registerPlugin(DynamicThemeBridge.class); registerPlugin(ShareTargetBridge.class); + registerPlugin(AiBridge.class); super.onCreate(savedInstanceState); // If launched from a shortcut (ACTION_VIEW with localhost data), // navigate the WebView to the shortcut's target path. handleShortcutIntent(getIntent()); - // Register predictive back callback for Android 13+ (API 33). - // This replaces the deprecated onBackPressed() and enables the - // native predictive back animation (peek at previous page / home). - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - backCallback = () -> { - WebView webView = getBridge().getWebView(); - if (webView.canGoBack()) { - webView.goBack(); - } else { - finish(); + // Predictive back gesture support (Android 14+). + // The callback is only enabled when the WebView has history, so the + // system can show the correct predictive animation: + // - enabled → in-app back: navigates WebView history + // - disabled → system "back to home" peek animation, then finish() + WebView webView = getBridge().getWebView(); + webViewBackCallback = new OnBackPressedCallback(webView.canGoBack()) { + @Override + public void handleOnBackPressed() { + WebView wv = getBridge().getWebView(); + if (wv.canGoBack()) { + wv.goBack(); } - }; - getOnBackInvokedDispatcher().registerOnBackInvokedCallback( - OnBackInvokedDispatcher.PRIORITY_DEFAULT, backCallback); - } + // Update enabled state after navigation + setEnabled(wv.canGoBack()); + } + }; + getOnBackPressedDispatcher().addCallback(this, webViewBackCallback); + + // Install a custom WebViewClient that tracks both real page loads and + // SPA pushState/replaceState navigations via doUpdateVisitedHistory, + // keeping the back callback's enabled state in sync with WebView history. + Bridge bridge = getBridge(); + bridge.setWebViewClient(new BridgeWebViewClient(bridge) { + @Override + public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) { + super.doUpdateVisitedHistory(view, url, isReload); + webViewBackCallback.setEnabled(view.canGoBack()); + } + }); } @Override diff --git a/android/variables.gradle b/android/variables.gradle index ee4ba41..0c479ae 100644 --- a/android/variables.gradle +++ b/android/variables.gradle @@ -1,5 +1,5 @@ ext { - minSdkVersion = 24 + minSdkVersion = 26 compileSdkVersion = 36 targetSdkVersion = 36 androidxActivityVersion = '1.11.0' diff --git a/capacitor.config.ts b/capacitor.config.ts index e26af02..62f305b 100644 --- a/capacitor.config.ts +++ b/capacitor.config.ts @@ -11,7 +11,11 @@ const config: CapacitorConfig = { }, plugins: { App: { - // Keep default back-button handling so hardware back navigates the router + // Disable Capacitor's default back-button handler so our custom + // OnBackPressedCallback in MainActivity can dynamically enable/disable + // itself based on WebView.canGoBack(). This is required for the + // predictive back gesture animation on Android 14+. + disableBackButtonHandler: true, }, PushNotifications: { // Show notifications even when the app is in the foreground diff --git a/src/services/ai.ts b/src/services/ai.ts index f654b5f..46355d6 100644 --- a/src/services/ai.ts +++ b/src/services/ai.ts @@ -65,6 +65,57 @@ export const translate = async ( language: string = 'en-us', statusId?: string ) => { + // Normalize target language code (e.g., 'en-us' -> 'en') + const targetLanguage = language.split('-')[0].toLowerCase(); + + // Detect source language up front (shared by native + Chrome paths) + let sourceLanguage = 'en'; + if ('LanguageDetector' in window) { + try { + const detector = await window.LanguageDetector.create(); + const results = await detector.detect(prompt); + if (results && results.length > 0 && results[0].confidence > 0.5) { + sourceLanguage = results[0].detectedLanguage; + } + detector.destroy(); + } catch (err) { + console.warn('Language detection failed, defaulting to English:', err); + } + } else { + // Fallback to native ML Kit language detection on Android + try { + const { nativeDetectLanguage } = await import('./native-ai'); + sourceLanguage = await nativeDetectLanguage(prompt); + } catch { + // Not on Android or native detection failed + } + } + + // Skip translation if source and target are the same + if (sourceLanguage === targetLanguage) { + return prompt; + } + + // Try native Android ML Kit translation first + try { + const { getNativeAICapabilities, nativeTranslate } = + await import('./native-ai'); + const caps = await getNativeAICapabilities(); + if (caps.translation) { + const result = await nativeTranslate( + prompt, + sourceLanguage, + targetLanguage + ); + return result; + } + } catch (nativeErr) { + console.warn( + 'Native translation unavailable, trying Chrome API:', + nativeErr + ); + } + // Use Chrome's built-in Translator API try { // Check if the API is available @@ -72,31 +123,6 @@ export const translate = async ( throw new Error('Translator API not available'); } - // Detect source language using Language Detector API - let sourceLanguage = 'en'; - - if ('Translator' in window && 'LanguageDetector' in window) { - try { - console.log('Attempting language detection for prompt:', prompt); - const detector = await window.LanguageDetector.create(); - const results = await detector.detect(prompt); - console.log('Language detection results:', results); - if (results && results.length > 0 && results[0].confidence > 0.5) { - sourceLanguage = results[0].detectedLanguage; - } - detector.destroy(); - } catch (err) { - console.warn('Language detection failed, defaulting to English:', err); - } - } - - // Normalize language code (e.g., 'en-us' -> 'en') - const targetLanguage = language.split('-')[0].toLowerCase(); - - // Skip translation if source and target are the same - if (sourceLanguage === targetLanguage) { - return prompt; - } console.log( 'Checking translator capabilities for', sourceLanguage, @@ -181,6 +207,15 @@ export const createImage = async (prompt: string) => { * Check if Chrome's Proofreader API is available on this device */ export const isProofreaderAvailable = async (): Promise => { + // Check native Android Gemini Nano proofreading first + try { + const { getNativeAICapabilities } = await import('./native-ai'); + const caps = await getNativeAICapabilities(); + if (caps.proofreading) return true; + } catch { + // Not on native, fall through + } + try { if (typeof Proofreader === 'undefined') { return false; @@ -202,6 +237,22 @@ export const isProofreaderAvailable = async (): Promise => { export const proofread = async ( text: string ): Promise => { + // Try native Android Gemini Nano proofreading first + try { + const { getNativeAICapabilities, nativeProofread } = + await import('./native-ai'); + const caps = await getNativeAICapabilities(); + if (caps.proofreading) { + const result = await nativeProofread(text); + return result as ProofreadResult; + } + } catch (nativeErr) { + console.warn( + 'Native proofreading unavailable, trying Chrome API:', + nativeErr + ); + } + try { if (typeof Proofreader === 'undefined') { throw new Error('Proofreader API not available'); @@ -253,6 +304,49 @@ export const isPromptAPIAvailable = (): boolean => { export const generateAltText = async ( imageSource: string | Blob ): Promise => { + // Try native Android Gemini Nano first + try { + const { getNativeAICapabilities, nativeGenerateAltText } = + await import('./native-ai'); + const caps = await getNativeAICapabilities(); + if (caps.altText) { + // Convert image to base64 for the native bridge + let base64: string; + if (typeof imageSource === 'string' && !imageSource.startsWith('blob:')) { + // Regular URL — fetch and convert + const resp = await fetch(imageSource); + const blob = await resp.blob(); + const reader = new FileReader(); + base64 = await new Promise((resolve) => { + reader.onloadend = () => resolve(reader.result as string); + reader.readAsDataURL(blob); + }); + } else if (typeof imageSource === 'string') { + // blob: URL + const resp = await fetch(imageSource); + const blob = await resp.blob(); + const reader = new FileReader(); + base64 = await new Promise((resolve) => { + reader.onloadend = () => resolve(reader.result as string); + reader.readAsDataURL(blob); + }); + } else { + const reader = new FileReader(); + base64 = await new Promise((resolve) => { + reader.onloadend = () => resolve(reader.result as string); + reader.readAsDataURL(imageSource); + }); + } + const result = await nativeGenerateAltText(base64); + if (result) return result; + } + } catch (nativeErr) { + console.warn( + 'Native alt text generation unavailable, trying Chrome API:', + nativeErr + ); + } + try { if (!isPromptAPIAvailable()) { throw new Error('Prompt API (LanguageModel) not available'); @@ -479,6 +573,26 @@ What text is written in this image?`; * Check if on-device translation is available via Chrome's Translator API */ export const isOnDeviceTranslationAvailable = (): boolean => { + // Native Android ML Kit translation is always available on Capacitor Android + try { + // Sync check using Capacitor global (available when running in native shell) + const cap = + 'Capacitor' in window + ? ( + window as unknown as { + Capacitor?: { + isNativePlatform?: () => boolean; + getPlatform?: () => string; + }; + } + ).Capacitor + : undefined; + if (cap?.isNativePlatform?.() && cap?.getPlatform?.() === 'android') { + return true; + } + } catch { + // Not in Capacitor context + } return 'Translator' in window; }; diff --git a/src/services/native-ai.ts b/src/services/native-ai.ts new file mode 100644 index 0000000..46d82de --- /dev/null +++ b/src/services/native-ai.ts @@ -0,0 +1,136 @@ +import { registerPlugin } from '@capacitor/core'; +import { isNativePlatform, getPlatform } from '../utils/platform.js'; + +/** + * TypeScript bridge to the native AiBridge Capacitor plugin. + * Provides on-device AI via ML Kit Translation and Gemini Nano + * (alt text generation + proofreading) on Android. + */ + +interface AiBridgePlugin { + translate(opts: { + text: string; + sourceLanguage: string; + targetLanguage: string; + }): Promise<{ translatedText: string }>; + + generateAltText(opts: { imageBase64: string }): Promise<{ altText: string }>; + + proofread(opts: { text: string }): Promise<{ + correctedInput: string; + corrections: Array<{ + startIndex: number; + endIndex: number; + correction: string; + correctionType?: string; + explanation?: string; + }>; + }>; + + checkAvailability(): Promise<{ + translation: boolean; + altText: boolean; + proofreading: boolean; + }>; + + detectLanguage(opts: { text: string }): Promise<{ language: string }>; +} + +// Cached capabilities – populated once per session +let cachedCapabilities: { + translation: boolean; + altText: boolean; + proofreading: boolean; +} | null = null; + +const bridge = registerPlugin('AiBridge'); + +function getBridge(): AiBridgePlugin { + return bridge; +} + +function isNativeAndroid(): boolean { + return isNativePlatform() && getPlatform() === 'android'; +} + +/** + * Probe which native AI capabilities are available on this device. + * Result is cached for the session lifetime. + */ +export async function getNativeAICapabilities(): Promise<{ + translation: boolean; + altText: boolean; + proofreading: boolean; +}> { + if (!isNativeAndroid()) { + return { translation: false, altText: false, proofreading: false }; + } + + if (cachedCapabilities) return cachedCapabilities; + + try { + cachedCapabilities = await getBridge().checkAvailability(); + } catch { + cachedCapabilities = { + translation: false, + altText: false, + proofreading: false, + }; + } + + return cachedCapabilities; +} + +/** + * Translate text using ML Kit on-device translation. + * Throws if not on native Android or if translation fails. + */ +export async function nativeTranslate( + text: string, + sourceLanguage: string, + targetLanguage: string +): Promise { + const result = await getBridge().translate({ + text, + sourceLanguage, + targetLanguage, + }); + return result.translatedText; +} + +/** + * Generate alt text for an image using Gemini Nano. + * @param imageBase64 - Base64-encoded image data (with or without data URI prefix) + */ +export async function nativeGenerateAltText( + imageBase64: string +): Promise { + const result = await getBridge().generateAltText({ imageBase64 }); + return result.altText; +} + +/** + * Proofread text using Gemini Nano. + * Returns a result matching the ProofreadResult interface shape. + */ +export async function nativeProofread(text: string): Promise<{ + correctedInput: string; + corrections: Array<{ + startIndex: number; + endIndex: number; + correction: string; + correctionType?: string; + explanation?: string; + }>; +}> { + return await getBridge().proofread({ text }); +} + +/** + * Detect the language of text using ML Kit Language Identification. + * Returns a BCP-47 language code (e.g. 'en', 'ja', 'es'). + */ +export async function nativeDetectLanguage(text: string): Promise { + const result = await getBridge().detectLanguage({ text }); + return result.language; +} From 0bae1c5c67241a57c6e4ba73779f203e6ec17e75 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Wed, 18 Mar 2026 21:05:03 -0700 Subject: [PATCH 18/26] notification channels --- functions/src/push-relay.ts | 16 ++++++++- src/services/push-native.ts | 68 +++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/functions/src/push-relay.ts b/functions/src/push-relay.ts index 1d9bbdd..6808f25 100644 --- a/functions/src/push-relay.ts +++ b/functions/src/push-relay.ts @@ -372,6 +372,19 @@ export const pushRelayPush = onRequest( const title = String(payload.title || 'Coho'); const body = String(payload.body || 'You have a new notification'); + const notificationType = String(payload.notification_type || ''); + // Map Mastodon notification types to Android notification channels + const channelMap: Record = { + mention: 'coho_mentions', + reblog: 'coho_boosts', + favourite: 'coho_favourites', + follow: 'coho_follows', + follow_request: 'coho_follows', + poll: 'coho_polls', + status: 'coho_status', + update: 'coho_status', + }; + const channelId = channelMap[notificationType] || 'coho_general'; // FCM data values must all be strings — stringify everything const fcmData: Record = {}; @@ -393,9 +406,10 @@ export const pushRelayPush = onRequest( android: { priority: 'high', notification: { - channelId: 'PushDefaultForeground', + channelId, icon: 'ic_stat_name', color: '#d6325c', + tag: `coho_${notificationType || 'general'}`, }, }, }); diff --git a/src/services/push-native.ts b/src/services/push-native.ts index 3cb73f5..6a77fc0 100644 --- a/src/services/push-native.ts +++ b/src/services/push-native.ts @@ -263,6 +263,70 @@ function getTargetUrl(data: Record): string { } } +// --------------------------------------------------------------------------- +// Notification Channels (Android 8+) +// --------------------------------------------------------------------------- + +const NOTIFICATION_CHANNELS: Array<{ + id: string; + name: string; + description: string; + importance: 1 | 2 | 3 | 4 | 5; +}> = [ + { + id: 'coho_mentions', + name: 'Mentions', + description: 'When someone mentions you', + importance: 4, + }, + { + id: 'coho_boosts', + name: 'Boosts', + description: 'When someone boosts your post', + importance: 3, + }, + { + id: 'coho_favourites', + name: 'Favourites', + description: 'When someone favourites your post', + importance: 2, + }, + { + id: 'coho_follows', + name: 'Follows', + description: 'New followers and follow requests', + importance: 3, + }, + { + id: 'coho_polls', + name: 'Polls', + description: 'Poll results', + importance: 2, + }, + { + id: 'coho_status', + name: 'New Posts', + description: 'Posts from people you follow', + importance: 2, + }, + { + id: 'coho_general', + name: 'General', + description: 'Other notifications', + importance: 3, + }, +]; + +/** + * Create per-type notification channels. Idempotent — Android ignores + * duplicate creates but preserves user-customised settings. + */ +async function ensureNotificationChannels(): Promise { + for (const ch of NOTIFICATION_CHANNELS) { + await PushNotifications.createChannel(ch); + } +} + // --------------------------------------------------------------------------- // Setup Listeners (call once at app startup on native) // --------------------------------------------------------------------------- @@ -272,6 +336,10 @@ function getTargetUrl(data: Record): string { * Also handles FCM token refresh by re-registering with the relay. */ export function setupNativePushListeners(): void { + // Create channels early so they exist before any notification arrives + ensureNotificationChannels().catch((err) => + console.warn('[NativePush] Channel creation failed:', err) + ); // Foreground notification received PushNotifications.addListener('pushNotificationReceived', (notification) => { console.log('[NativePush] Foreground notification received'); From 99fac0abd508a7be3b1c1e58bf42986927cb7452 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Thu, 19 Mar 2026 00:28:47 -0700 Subject: [PATCH 19/26] android wear app --- android/app/build.gradle | 3 + .../java/place/coho/app/MainActivity.java | 1 + .../java/place/coho/app/WearSyncBridge.java | 64 +++++ android/build.gradle | 2 + android/settings.gradle | 1 + android/wear/build.gradle | 74 ++++++ android/wear/proguard-rules.pro | 5 + android/wear/src/main/AndroidManifest.xml | 42 ++++ .../place/coho/app/wear/api/MastodonApi.kt | 40 +++ .../place/coho/app/wear/api/MastodonClient.kt | 64 +++++ .../place/coho/app/wear/api/models/Account.kt | 14 ++ .../app/wear/api/models/MediaAttachment.kt | 13 + .../coho/app/wear/api/models/Notification.kt | 13 + .../place/coho/app/wear/api/models/Status.kt | 23 ++ .../app/wear/data/NotificationRepository.kt | 26 ++ .../coho/app/wear/data/TimelineRepository.kt | 54 ++++ .../coho/app/wear/sync/AuthRepository.kt | 50 ++++ .../coho/app/wear/sync/AuthSyncService.kt | 42 ++++ .../place/coho/app/wear/ui/WearActivity.kt | 18 ++ .../java/place/coho/app/wear/ui/WearApp.kt | 147 +++++++++++ .../app/wear/ui/components/WearPostContent.kt | 38 +++ .../ui/notifications/NotificationsScreen.kt | 190 ++++++++++++++ .../notifications/NotificationsViewModel.kt | 38 +++ .../coho/app/wear/ui/theme/CohoWearTheme.kt | 41 +++ .../coho/app/wear/ui/timeline/PostCard.kt | 192 ++++++++++++++ .../app/wear/ui/timeline/PostDetailScreen.kt | 234 ++++++++++++++++++ .../app/wear/ui/timeline/TimelineScreen.kt | 127 ++++++++++ .../app/wear/ui/timeline/TimelineViewModel.kt | 123 +++++++++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 6 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 6 + .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 2178 bytes .../mipmap-hdpi/ic_launcher_foreground.webp | Bin 0 -> 3542 bytes .../mipmap-hdpi/ic_launcher_monochrome.webp | Bin 0 -> 3872 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 3926 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 1418 bytes .../mipmap-mdpi/ic_launcher_foreground.webp | Bin 0 -> 2024 bytes .../mipmap-mdpi/ic_launcher_monochrome.webp | Bin 0 -> 2304 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 2438 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 3112 bytes .../mipmap-xhdpi/ic_launcher_foreground.webp | Bin 0 -> 5468 bytes .../mipmap-xhdpi/ic_launcher_monochrome.webp | Bin 0 -> 5726 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 5792 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 4918 bytes .../mipmap-xxhdpi/ic_launcher_foreground.webp | Bin 0 -> 9942 bytes .../mipmap-xxhdpi/ic_launcher_monochrome.webp | Bin 0 -> 10934 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 9796 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 7400 bytes .../ic_launcher_foreground.webp | Bin 0 -> 16546 bytes .../ic_launcher_monochrome.webp | Bin 0 -> 18554 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 14286 bytes .../res/values/ic_launcher_background.xml | 4 + android/wear/src/main/res/values/strings.xml | 25 ++ src/app-index.ts | 30 +++ 53 files changed, 1750 insertions(+) create mode 100644 android/app/src/main/java/place/coho/app/WearSyncBridge.java create mode 100644 android/wear/build.gradle create mode 100644 android/wear/proguard-rules.pro create mode 100644 android/wear/src/main/AndroidManifest.xml create mode 100644 android/wear/src/main/java/place/coho/app/wear/api/MastodonApi.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/api/MastodonClient.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/api/models/Account.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/api/models/MediaAttachment.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/api/models/Notification.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/api/models/Status.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/data/NotificationRepository.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/data/TimelineRepository.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/sync/AuthRepository.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/sync/AuthSyncService.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/ui/WearActivity.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/ui/WearApp.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/ui/components/WearPostContent.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsScreen.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsViewModel.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/ui/theme/CohoWearTheme.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostCard.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostDetailScreen.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineScreen.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineViewModel.kt create mode 100644 android/wear/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 android/wear/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 android/wear/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 android/wear/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp create mode 100644 android/wear/src/main/res/mipmap-hdpi/ic_launcher_monochrome.webp create mode 100644 android/wear/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 android/wear/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 android/wear/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp create mode 100644 android/wear/src/main/res/mipmap-mdpi/ic_launcher_monochrome.webp create mode 100644 android/wear/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 android/wear/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 android/wear/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp create mode 100644 android/wear/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.webp create mode 100644 android/wear/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 android/wear/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 android/wear/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp create mode 100644 android/wear/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.webp create mode 100644 android/wear/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 android/wear/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 android/wear/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp create mode 100644 android/wear/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.webp create mode 100644 android/wear/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 android/wear/src/main/res/values/ic_launcher_background.xml create mode 100644 android/wear/src/main/res/values/strings.xml diff --git a/android/app/build.gradle b/android/app/build.gradle index c3c224e..4070504 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -45,6 +45,9 @@ dependencies { implementation 'com.google.mlkit:genai-image-description:1.0.0-beta1' implementation 'com.google.mlkit:genai-proofreading:1.0.0-beta1' + // Wearable Data Layer (phone → watch credential sync) + implementation 'com.google.android.gms:play-services-wearable:19.0.0' + testImplementation "junit:junit:$junitVersion" androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" diff --git a/android/app/src/main/java/place/coho/app/MainActivity.java b/android/app/src/main/java/place/coho/app/MainActivity.java index 53727d8..7e006f9 100644 --- a/android/app/src/main/java/place/coho/app/MainActivity.java +++ b/android/app/src/main/java/place/coho/app/MainActivity.java @@ -21,6 +21,7 @@ protected void onCreate(Bundle savedInstanceState) { registerPlugin(DynamicThemeBridge.class); registerPlugin(ShareTargetBridge.class); registerPlugin(AiBridge.class); + registerPlugin(WearSyncBridge.class); super.onCreate(savedInstanceState); // If launched from a shortcut (ACTION_VIEW with localhost data), diff --git a/android/app/src/main/java/place/coho/app/WearSyncBridge.java b/android/app/src/main/java/place/coho/app/WearSyncBridge.java new file mode 100644 index 0000000..70e9a5a --- /dev/null +++ b/android/app/src/main/java/place/coho/app/WearSyncBridge.java @@ -0,0 +1,64 @@ +package place.coho.app; + +import android.util.Log; + +import com.getcapacitor.JSObject; +import com.getcapacitor.Plugin; +import com.getcapacitor.PluginCall; +import com.getcapacitor.PluginMethod; +import com.getcapacitor.annotation.CapacitorPlugin; +import com.google.android.gms.tasks.Tasks; +import com.google.android.gms.wearable.DataClient; +import com.google.android.gms.wearable.PutDataMapRequest; +import com.google.android.gms.wearable.Wearable; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Capacitor plugin that pushes auth credentials to a paired Wear OS + * device via the Wearable Data Layer API. + * + * The watch-side {@code AuthSyncService} listens for DataItem changes + * at path {@code /coho/auth} and persists the token locally. + */ +@CapacitorPlugin(name = "WearSyncBridge") +public class WearSyncBridge extends Plugin { + + private static final String TAG = "WearSyncBridge"; + private static final String DATA_PATH = "/coho/auth"; + private final ExecutorService executor = Executors.newSingleThreadExecutor(); + + /** + * Push current credentials to the paired watch. + * Expected params: server (String), accessToken (String), acct (String). + */ + @PluginMethod + public void syncCredentials(PluginCall call) { + String server = call.getString("server", ""); + String accessToken = call.getString("accessToken", ""); + String acct = call.getString("acct", ""); + + executor.execute(() -> { + try { + DataClient dataClient = Wearable.getDataClient(getContext()); + PutDataMapRequest putReq = PutDataMapRequest.create(DATA_PATH); + putReq.getDataMap().putString("server", server); + putReq.getDataMap().putString("accessToken", accessToken); + putReq.getDataMap().putString("acct", acct); + // Force update even if data hasn't changed (timestamp trick) + putReq.getDataMap().putLong("timestamp", System.currentTimeMillis()); + putReq.setUrgent(); + + Tasks.await(dataClient.putDataItem(putReq.asPutDataRequest())); + Log.d(TAG, "Credentials synced to Wear OS for " + acct); + + getActivity().runOnUiThread(() -> call.resolve()); + } catch (Exception e) { + Log.w(TAG, "Failed to sync credentials to Wear OS", e); + // Resolve anyway — watch sync is best-effort and should not block the phone app + getActivity().runOnUiThread(() -> call.resolve()); + } + }); + } +} diff --git a/android/build.gradle b/android/build.gradle index 34a92c9..f18cf80 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -9,6 +9,8 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:9.1.0' classpath 'com.google.gms:google-services:4.4.4' + classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0' + classpath 'org.jetbrains.kotlin:compose-compiler-gradle-plugin:2.1.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/android/settings.gradle b/android/settings.gradle index c3c9ec6..9f627b6 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -2,6 +2,7 @@ plugins { id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' } include ':app' +include ':wear' include ':capacitor-cordova-android-plugins' project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') diff --git a/android/wear/build.gradle b/android/wear/build.gradle new file mode 100644 index 0000000..9ac123d --- /dev/null +++ b/android/wear/build.gradle @@ -0,0 +1,74 @@ +apply plugin: 'com.android.application' +apply plugin: 'org.jetbrains.kotlin.android' +apply plugin: 'org.jetbrains.kotlin.plugin.compose' + +android { + namespace = "place.coho.app.wear" + compileSdk = rootProject.ext.compileSdkVersion + + defaultConfig { + applicationId "place.coho.app.wear" + minSdkVersion 30 // Wear OS 3+ + targetSdkVersion rootProject.ext.targetSdkVersion + versionCode 1 + versionName "1.0" + } + + buildTypes { + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + buildFeatures { + compose true + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = '17' + } +} + +dependencies { + // Compose for Wear OS + def composeBom = platform('androidx.compose:compose-bom:2024.12.01') + implementation composeBom + + implementation 'androidx.wear.compose:compose-material3:1.0.0-alpha32' + implementation 'androidx.wear.compose:compose-foundation:1.5.0-alpha06' + implementation 'androidx.wear.compose:compose-navigation:1.5.0-alpha06' + implementation 'androidx.compose.ui:ui-tooling-preview' + debugImplementation 'androidx.compose.ui:ui-tooling' + + // Activity & Lifecycle + implementation 'androidx.activity:activity-compose:1.10.1' + implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.9.0' + implementation 'androidx.lifecycle:lifecycle-runtime-compose:2.9.0' + + // Horologist (Google's Wear OS best-practice library) + implementation 'com.google.android.horologist:horologist-compose-layout:0.6.22' + + // Networking + implementation 'com.squareup.retrofit2:retrofit:2.11.0' + implementation 'com.squareup.retrofit2:converter-moshi:2.11.0' + implementation 'com.squareup.moshi:moshi-kotlin:1.15.2' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' + + // Image loading + implementation 'io.coil-kt:coil-compose:2.7.0' + + // Wearable Data Layer (phone ↔ watch sync) + implementation 'com.google.android.gms:play-services-wearable:19.0.0' + + // DataStore for local credential persistence + implementation 'androidx.datastore:datastore-preferences:1.1.2' + + // Core AndroidX + implementation 'androidx.core:core-ktx:1.15.0' +} diff --git a/android/wear/proguard-rules.pro b/android/wear/proguard-rules.pro new file mode 100644 index 0000000..d71dd32 --- /dev/null +++ b/android/wear/proguard-rules.pro @@ -0,0 +1,5 @@ +# Default ProGuard rules for the Wear module +-keepattributes *Annotation* +-keep class place.coho.app.wear.api.models.** { *; } +-dontwarn okhttp3.** +-dontwarn retrofit2.** diff --git a/android/wear/src/main/AndroidManifest.xml b/android/wear/src/main/AndroidManifest.xml new file mode 100644 index 0000000..be44022 --- /dev/null +++ b/android/wear/src/main/AndroidManifest.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/wear/src/main/java/place/coho/app/wear/api/MastodonApi.kt b/android/wear/src/main/java/place/coho/app/wear/api/MastodonApi.kt new file mode 100644 index 0000000..a7916e6 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/api/MastodonApi.kt @@ -0,0 +1,40 @@ +package place.coho.app.wear.api + +import place.coho.app.wear.api.models.Notification +import place.coho.app.wear.api.models.Status +import retrofit2.http.GET +import retrofit2.http.POST +import retrofit2.http.Path +import retrofit2.http.Query + +interface MastodonApi { + + @GET("api/v1/timelines/home") + suspend fun getHomeTimeline( + @Query("limit") limit: Int = 12, + @Query("max_id") maxId: String? = null, + ): List + + @POST("api/v1/statuses/{id}/favourite") + suspend fun favouriteStatus(@Path("id") id: String): Status + + @POST("api/v1/statuses/{id}/unfavourite") + suspend fun unfavouriteStatus(@Path("id") id: String): Status + + @POST("api/v1/statuses/{id}/reblog") + suspend fun reblogStatus(@Path("id") id: String): Status + + @POST("api/v1/statuses/{id}/unreblog") + suspend fun unreblogStatus(@Path("id") id: String): Status + + @GET("api/v1/trends/statuses") + suspend fun getTrendingStatuses( + @Query("limit") limit: Int = 12, + ): List + + @GET("api/v1/notifications") + suspend fun getNotifications( + @Query("limit") limit: Int = 20, + @Query("max_id") maxId: String? = null, + ): List +} diff --git a/android/wear/src/main/java/place/coho/app/wear/api/MastodonClient.kt b/android/wear/src/main/java/place/coho/app/wear/api/MastodonClient.kt new file mode 100644 index 0000000..80059c0 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/api/MastodonClient.kt @@ -0,0 +1,64 @@ +package place.coho.app.wear.api + +import com.squareup.moshi.Moshi +import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory +import okhttp3.Interceptor +import okhttp3.OkHttpClient +import retrofit2.Retrofit +import retrofit2.converter.moshi.MoshiConverterFactory +import java.util.concurrent.TimeUnit + +/** + * Provides a configured [MastodonApi] instance. + * The base URL and auth token are set dynamically based on the synced credentials. + */ +object MastodonClient { + + private val moshi: Moshi = Moshi.Builder() + .addLast(KotlinJsonAdapterFactory()) + .build() + + /** + * Build an unauthenticated [MastodonApi] for public endpoints. + */ + fun createPublic(server: String = "mastodon.social"): MastodonApi { + val client = OkHttpClient.Builder() + .connectTimeout(15, TimeUnit.SECONDS) + .readTimeout(15, TimeUnit.SECONDS) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://$server/") + .client(client) + .addConverterFactory(MoshiConverterFactory.create(moshi)) + .build() + + return retrofit.create(MastodonApi::class.java) + } + + /** + * Build a [MastodonApi] for the given server and access token. + */ + fun create(server: String, accessToken: String): MastodonApi { + val authInterceptor = Interceptor { chain -> + val request = chain.request().newBuilder() + .addHeader("Authorization", "Bearer $accessToken") + .build() + chain.proceed(request) + } + + val client = OkHttpClient.Builder() + .addInterceptor(authInterceptor) + .connectTimeout(15, TimeUnit.SECONDS) + .readTimeout(15, TimeUnit.SECONDS) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://$server/") + .client(client) + .addConverterFactory(MoshiConverterFactory.create(moshi)) + .build() + + return retrofit.create(MastodonApi::class.java) + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/api/models/Account.kt b/android/wear/src/main/java/place/coho/app/wear/api/models/Account.kt new file mode 100644 index 0000000..d38f541 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/api/models/Account.kt @@ -0,0 +1,14 @@ +package place.coho.app.wear.api.models + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = false) +data class Account( + val id: String, + val username: String, + val acct: String, + @Json(name = "display_name") val displayName: String, + val avatar: String, + val bot: Boolean = false, +) diff --git a/android/wear/src/main/java/place/coho/app/wear/api/models/MediaAttachment.kt b/android/wear/src/main/java/place/coho/app/wear/api/models/MediaAttachment.kt new file mode 100644 index 0000000..c2cc5d5 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/api/models/MediaAttachment.kt @@ -0,0 +1,13 @@ +package place.coho.app.wear.api.models + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = false) +data class MediaAttachment( + val id: String, + val type: String, // "image", "gifv", "video", "audio" + val url: String, + @Json(name = "preview_url") val previewUrl: String?, + val description: String?, +) diff --git a/android/wear/src/main/java/place/coho/app/wear/api/models/Notification.kt b/android/wear/src/main/java/place/coho/app/wear/api/models/Notification.kt new file mode 100644 index 0000000..18ca858 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/api/models/Notification.kt @@ -0,0 +1,13 @@ +package place.coho.app.wear.api.models + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = false) +data class Notification( + val id: String, + val type: String, // follow, mention, reblog, favourite, poll, status, update + @Json(name = "created_at") val createdAt: String, + val account: Account, + val status: Status?, +) diff --git a/android/wear/src/main/java/place/coho/app/wear/api/models/Status.kt b/android/wear/src/main/java/place/coho/app/wear/api/models/Status.kt new file mode 100644 index 0000000..a48cb3c --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/api/models/Status.kt @@ -0,0 +1,23 @@ +package place.coho.app.wear.api.models + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = false) +data class Status( + val id: String, + @Json(name = "created_at") val createdAt: String, + @Json(name = "in_reply_to_id") val inReplyToId: String?, + val sensitive: Boolean = false, + @Json(name = "spoiler_text") val spoilerText: String = "", + val visibility: String = "public", + val content: String, // HTML content + val reblog: Status?, + val account: Account, + @Json(name = "media_attachments") val mediaAttachments: List = emptyList(), + @Json(name = "replies_count") val repliesCount: Int = 0, + @Json(name = "reblogs_count") val reblogsCount: Int = 0, + @Json(name = "favourites_count") val favouritesCount: Int = 0, + val favourited: Boolean = false, + val reblogged: Boolean = false, +) diff --git a/android/wear/src/main/java/place/coho/app/wear/data/NotificationRepository.kt b/android/wear/src/main/java/place/coho/app/wear/data/NotificationRepository.kt new file mode 100644 index 0000000..bf548ca --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/data/NotificationRepository.kt @@ -0,0 +1,26 @@ +package place.coho.app.wear.data + +import place.coho.app.wear.api.MastodonApi +import place.coho.app.wear.api.MastodonClient +import place.coho.app.wear.api.models.Notification +import place.coho.app.wear.sync.AuthState + +class NotificationRepository { + + private var api: MastodonApi? = null + private var currentServer: String? = null + private var currentToken: String? = null + + private fun getApi(auth: AuthState): MastodonApi { + if (api == null || currentServer != auth.server || currentToken != auth.accessToken) { + api = MastodonClient.create(auth.server, auth.accessToken) + currentServer = auth.server + currentToken = auth.accessToken + } + return api!! + } + + suspend fun getNotifications(auth: AuthState): List { + return getApi(auth).getNotifications(limit = 20) + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/data/TimelineRepository.kt b/android/wear/src/main/java/place/coho/app/wear/data/TimelineRepository.kt new file mode 100644 index 0000000..7ba6477 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/data/TimelineRepository.kt @@ -0,0 +1,54 @@ +package place.coho.app.wear.data + +import place.coho.app.wear.api.MastodonApi +import place.coho.app.wear.api.MastodonClient +import place.coho.app.wear.api.models.Status +import place.coho.app.wear.sync.AuthState + +class TimelineRepository { + + private var api: MastodonApi? = null + private var currentServer: String? = null + private var currentToken: String? = null + private var publicApi: MastodonApi? = null + + private fun getApi(auth: AuthState): MastodonApi { + if (api == null || currentServer != auth.server || currentToken != auth.accessToken) { + api = MastodonClient.create(auth.server, auth.accessToken) + currentServer = auth.server + currentToken = auth.accessToken + } + return api!! + } + + private fun getPublicApi(): MastodonApi { + if (publicApi == null) { + publicApi = MastodonClient.createPublic() + } + return publicApi!! + } + + suspend fun getHomeTimeline(auth: AuthState, maxId: String? = null): List { + return getApi(auth).getHomeTimeline(limit = 12, maxId = maxId) + } + + suspend fun getPublicTimeline(): List { + return getPublicApi().getTrendingStatuses(limit = 12) + } + + suspend fun favouriteStatus(auth: AuthState, id: String): Status { + return getApi(auth).favouriteStatus(id) + } + + suspend fun unfavouriteStatus(auth: AuthState, id: String): Status { + return getApi(auth).unfavouriteStatus(id) + } + + suspend fun reblogStatus(auth: AuthState, id: String): Status { + return getApi(auth).reblogStatus(id) + } + + suspend fun unreblogStatus(auth: AuthState, id: String): Status { + return getApi(auth).unreblogStatus(id) + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/sync/AuthRepository.kt b/android/wear/src/main/java/place/coho/app/wear/sync/AuthRepository.kt new file mode 100644 index 0000000..fad858b --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/sync/AuthRepository.kt @@ -0,0 +1,50 @@ +package place.coho.app.wear.sync + +import android.content.Context +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.stringPreferencesKey +import androidx.datastore.preferences.preferencesDataStore +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +private val Context.authDataStore by preferencesDataStore(name = "coho_auth") + +data class AuthState( + val server: String, + val accessToken: String, + val acct: String, +) { + val isAuthenticated: Boolean get() = server.isNotBlank() && accessToken.isNotBlank() +} + +/** + * Single source of truth for watch-side credentials. + * Written by [AuthSyncService] when the phone pushes a DataItem, + * read by the UI layer to build API clients. + */ +class AuthRepository(private val context: Context) { + + private val keyServer = stringPreferencesKey("server") + private val keyAccessToken = stringPreferencesKey("access_token") + private val keyAcct = stringPreferencesKey("acct") + + val authState: Flow = context.authDataStore.data.map { prefs -> + AuthState( + server = prefs[keyServer] ?: "", + accessToken = prefs[keyAccessToken] ?: "", + acct = prefs[keyAcct] ?: "", + ) + } + + suspend fun saveCredentials(server: String, accessToken: String, acct: String) { + context.authDataStore.edit { prefs -> + prefs[keyServer] = server + prefs[keyAccessToken] = accessToken + prefs[keyAcct] = acct + } + } + + suspend fun clear() { + context.authDataStore.edit { it.clear() } + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/sync/AuthSyncService.kt b/android/wear/src/main/java/place/coho/app/wear/sync/AuthSyncService.kt new file mode 100644 index 0000000..527f843 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/sync/AuthSyncService.kt @@ -0,0 +1,42 @@ +package place.coho.app.wear.sync + +import com.google.android.gms.wearable.DataEventBuffer +import com.google.android.gms.wearable.DataMapItem +import com.google.android.gms.wearable.WearableListenerService +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch + +/** + * Receives DataItem updates pushed from the phone app via the Wearable Data Layer. + * When the phone stores or updates credentials at `/coho/auth`, this service + * persists them into local DataStore so the watch can call the Mastodon API. + */ +class AuthSyncService : WearableListenerService() { + + private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) + + override fun onDataChanged(dataEvents: DataEventBuffer) { + val repo = AuthRepository(applicationContext) + for (event in dataEvents) { + val path = event.dataItem.uri.path ?: continue + if (path == "/coho/auth") { + val dataMap = DataMapItem.fromDataItem(event.dataItem).dataMap + val server = dataMap.getString("server") ?: continue + val accessToken = dataMap.getString("accessToken") ?: continue + val acct = dataMap.getString("acct") ?: "" + + scope.launch { + repo.saveCredentials(server, accessToken, acct) + } + } + } + } + + override fun onDestroy() { + super.onDestroy() + scope.cancel() + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/WearActivity.kt b/android/wear/src/main/java/place/coho/app/wear/ui/WearActivity.kt new file mode 100644 index 0000000..64e3c9b --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/ui/WearActivity.kt @@ -0,0 +1,18 @@ +package place.coho.app.wear.ui + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import place.coho.app.wear.sync.AuthRepository + +class WearActivity : ComponentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val authRepository = AuthRepository(applicationContext) + + setContent { + WearApp(authRepository) + } + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/WearApp.kt b/android/wear/src/main/java/place/coho/app/wear/ui/WearApp.kt new file mode 100644 index 0000000..a6f5e04 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/ui/WearApp.kt @@ -0,0 +1,147 @@ +package place.coho.app.wear.ui + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.wear.compose.material3.AppScaffold +import androidx.wear.compose.material3.MaterialTheme +import androidx.wear.compose.navigation.SwipeDismissableNavHost +import androidx.wear.compose.navigation.composable +import androidx.wear.compose.navigation.rememberSwipeDismissableNavController +import kotlinx.coroutines.launch +import place.coho.app.wear.api.models.Status +import place.coho.app.wear.sync.AuthRepository +import place.coho.app.wear.sync.AuthState +import place.coho.app.wear.ui.notifications.NotificationsScreen +import place.coho.app.wear.ui.theme.CohoWearTheme +import place.coho.app.wear.ui.timeline.PostDetailScreen +import place.coho.app.wear.ui.timeline.TimelineScreen +import place.coho.app.wear.ui.timeline.TimelineViewModel + +@Composable +fun WearApp(authRepository: AuthRepository) { + val authState by authRepository.authState.collectAsState( + initial = AuthState("", "", "") + ) + + CohoWearTheme { + val navController = rememberSwipeDismissableNavController() + var selectedStatus by remember { mutableStateOf(null) } + val timelineViewModel: TimelineViewModel = viewModel() + + AppScaffold { + SwipeDismissableNavHost( + navController = navController, + startDestination = "home", + ) { + composable("home") { + if (authState.isAuthenticated) { + val pagerState = rememberPagerState(pageCount = { 2 }) + val coroutineScope = rememberCoroutineScope() + + Box(modifier = Modifier.fillMaxSize()) { + HorizontalPager( + state = pagerState, + modifier = Modifier.fillMaxSize(), + ) { page -> + when (page) { + 0 -> TimelineScreen( + auth = authState, + onNavigateToNotifications = { + coroutineScope.launch { + pagerState.animateScrollToPage(1) + } + }, + onPostClick = { status -> + selectedStatus = status + navController.navigate("postDetail") + }, + viewModel = timelineViewModel, + ) + 1 -> NotificationsScreen(auth = authState) + } + } + + PageIndicator( + pageCount = 2, + currentPage = pagerState.currentPage, + modifier = Modifier + .align(Alignment.BottomCenter) + .padding(bottom = 2.dp), + ) + } + } else { + TimelineScreen( + auth = null, + onNavigateToNotifications = null, + onPostClick = { status -> + selectedStatus = status + navController.navigate("postDetail") + }, + viewModel = timelineViewModel, + ) + } + } + + composable("postDetail") { + val status = selectedStatus + if (status != null) { + PostDetailScreen( + status = status, + onFavourite = if (timelineViewModel.isAuthenticated) { + { timelineViewModel.toggleFavourite(it) } + } else null, + onBoost = if (timelineViewModel.isAuthenticated) { + { timelineViewModel.toggleBoost(it) } + } else null, + ) + } + } + } + } + } +} + +@Composable +private fun PageIndicator( + pageCount: Int, + currentPage: Int, + modifier: Modifier = Modifier, +) { + Row( + horizontalArrangement = Arrangement.Center, + modifier = modifier, + ) { + repeat(pageCount) { index -> + Box( + modifier = Modifier + .padding(horizontal = 3.dp) + .size(if (index == currentPage) 8.dp else 6.dp) + .clip(CircleShape) + .background( + if (index == currentPage) MaterialTheme.colorScheme.primary + else MaterialTheme.colorScheme.onSurface.copy(alpha = 0.3f) + ), + ) + } + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/components/WearPostContent.kt b/android/wear/src/main/java/place/coho/app/wear/ui/components/WearPostContent.kt new file mode 100644 index 0000000..e1ff37e --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/ui/components/WearPostContent.kt @@ -0,0 +1,38 @@ +package place.coho.app.wear.ui.components + +import android.text.Html +import java.time.Duration +import java.time.Instant +import java.time.format.DateTimeParseException + +/** + * Strips HTML tags from Mastodon post content and returns plain text. + * Also converts `
    ` and `

    ` to newlines for readability. + */ +fun htmlToPlainText(html: String): String { + // Use Android's Html parser which handles entities and tags + return Html.fromHtml(html, Html.FROM_HTML_MODE_COMPACT) + .toString() + .trim() +} + +/** + * Returns a human-readable relative time string, e.g. "5m ago", "2h ago". + */ +fun relativeTime(isoTimestamp: String): String { + return try { + val then = Instant.parse(isoTimestamp) + val now = Instant.now() + val duration = Duration.between(then, now) + + when { + duration.toMinutes() < 1 -> "now" + duration.toHours() < 1 -> "${duration.toMinutes()}m" + duration.toDays() < 1 -> "${duration.toHours()}h" + duration.toDays() < 7 -> "${duration.toDays()}d" + else -> "${duration.toDays() / 7}w" + } + } catch (_: DateTimeParseException) { + "" + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsScreen.kt b/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsScreen.kt new file mode 100644 index 0000000..7b1976d --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsScreen.kt @@ -0,0 +1,190 @@ +package place.coho.app.wear.ui.notifications + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.wear.compose.foundation.lazy.ScalingLazyColumn +import androidx.wear.compose.foundation.lazy.items +import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState +import androidx.wear.compose.material3.Card +import androidx.wear.compose.material3.CircularProgressIndicator +import androidx.wear.compose.material3.ListHeader +import androidx.wear.compose.material3.MaterialTheme +import androidx.wear.compose.material3.ScreenScaffold +import androidx.wear.compose.material3.Text +import coil.compose.AsyncImage +import place.coho.app.wear.R +import place.coho.app.wear.api.models.Notification +import place.coho.app.wear.ui.components.htmlToPlainText +import place.coho.app.wear.ui.components.relativeTime +import place.coho.app.wear.sync.AuthState +import androidx.compose.ui.res.stringResource + +@Composable +fun NotificationsScreen( + auth: AuthState, + viewModel: NotificationsViewModel = viewModel(), +) { + val uiState by viewModel.uiState.collectAsState() + + LaunchedEffect(auth) { + viewModel.loadNotifications(auth) + } + + when (val state = uiState) { + is NotificationsUiState.Loading -> { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.fillMaxSize(), + ) { + CircularProgressIndicator() + } + } + + is NotificationsUiState.Error -> { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.fillMaxSize().padding(16.dp), + ) { + Text( + text = stringResource(R.string.error_no_connection), + textAlign = TextAlign.Center, + style = MaterialTheme.typography.bodySmall, + ) + } + } + + is NotificationsUiState.Success -> { + val listState = rememberScalingLazyListState() + + ScreenScaffold( + scrollState = listState, + ) { + ScalingLazyColumn( + state = listState, + verticalArrangement = Arrangement.spacedBy(4.dp), + modifier = Modifier.fillMaxSize(), + ) { + item { + ListHeader { + Text(stringResource(R.string.notifications_title)) + } + } + + items(state.notifications, key = { it.id }) { notification -> + NotificationCard(notification) + } + } + } + } + } +} + +@Composable +private fun NotificationCard(notification: Notification) { + Card( + onClick = { }, + modifier = Modifier.fillMaxWidth(), + ) { + Column(modifier = Modifier.padding(4.dp)) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth(), + ) { + Text( + text = notificationIcon(notification.type), + style = MaterialTheme.typography.titleSmall, + ) + Spacer(modifier = Modifier.width(6.dp)) + AsyncImage( + model = notification.account.avatar, + contentDescription = null, + modifier = Modifier + .size(18.dp) + .clip(CircleShape), + ) + Spacer(modifier = Modifier.width(4.dp)) + Text( + text = notification.account.displayName.ifBlank { + notification.account.username + }, + style = MaterialTheme.typography.labelMedium, + fontWeight = FontWeight.Bold, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.weight(1f), + ) + Text( + text = relativeTime(notification.createdAt), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + + Spacer(modifier = Modifier.height(2.dp)) + + Text( + text = notificationLabel(notification.type), + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + + // Show post preview if available + notification.status?.let { status -> + Spacer(modifier = Modifier.height(2.dp)) + Text( + text = htmlToPlainText(status.content), + style = MaterialTheme.typography.bodySmall, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f), + ) + } + } + } +} + +private fun notificationIcon(type: String): String = when (type) { + "follow" -> "👤" + "follow_request" -> "👤" + "mention" -> "💬" + "reblog" -> "🔁" + "favourite" -> "❤️" + "poll" -> "📊" + "status" -> "📝" + "update" -> "✏️" + else -> "🔔" +} + +private fun notificationLabel(type: String): String = when (type) { + "follow" -> "followed you" + "follow_request" -> "requested to follow you" + "mention" -> "mentioned you" + "reblog" -> "boosted your post" + "favourite" -> "favorited your post" + "poll" -> "poll ended" + "status" -> "posted" + "update" -> "edited a post" + else -> "" +} diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsViewModel.kt b/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsViewModel.kt new file mode 100644 index 0000000..812226d --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsViewModel.kt @@ -0,0 +1,38 @@ +package place.coho.app.wear.ui.notifications + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import place.coho.app.wear.api.models.Notification +import place.coho.app.wear.data.NotificationRepository +import place.coho.app.wear.sync.AuthState + +sealed interface NotificationsUiState { + data object Loading : NotificationsUiState + data class Success(val notifications: List) : NotificationsUiState + data class Error(val message: String) : NotificationsUiState +} + +class NotificationsViewModel( + private val repository: NotificationRepository = NotificationRepository(), +) : ViewModel() { + + private val _uiState = MutableStateFlow(NotificationsUiState.Loading) + val uiState: StateFlow = _uiState + + fun loadNotifications(auth: AuthState) { + viewModelScope.launch { + _uiState.value = NotificationsUiState.Loading + try { + val notifications = repository.getNotifications(auth) + _uiState.value = NotificationsUiState.Success(notifications) + } catch (e: Exception) { + _uiState.value = NotificationsUiState.Error( + e.message ?: "Failed to load notifications" + ) + } + } + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/theme/CohoWearTheme.kt b/android/wear/src/main/java/place/coho/app/wear/ui/theme/CohoWearTheme.kt new file mode 100644 index 0000000..ddabba8 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/ui/theme/CohoWearTheme.kt @@ -0,0 +1,41 @@ +package place.coho.app.wear.ui.theme + +import android.os.Build +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.wear.compose.material3.ColorScheme +import androidx.wear.compose.material3.MaterialTheme +import androidx.wear.compose.material3.dynamicColorScheme + +// Coho brand colors — used as fallback when dynamic colors are unavailable +val CohoPink = Color(0xFFD6325C) +val CohoPinkLight = Color(0xFFE6A3B5) +val CohoPinkDark = Color(0xFFA82048) + +private val FallbackColorScheme = ColorScheme( + primary = CohoPink, + onPrimary = Color.White, + primaryContainer = CohoPinkDark, + onPrimaryContainer = CohoPinkLight, + secondary = CohoPinkLight, + onSecondary = Color.Black, + onSurface = Color(0xFFE6E1E5), + onSurfaceVariant = Color(0xFFCAC4D0), + error = Color(0xFFF2B8B5), + onError = Color(0xFF601410), +) + +@Composable +fun CohoWearTheme(content: @Composable () -> Unit) { + val colorScheme = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + dynamicColorScheme(LocalContext.current) ?: FallbackColorScheme + } else { + FallbackColorScheme + } + + MaterialTheme( + colorScheme = colorScheme, + content = content, + ) +} diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostCard.kt b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostCard.kt new file mode 100644 index 0000000..12a8384 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostCard.kt @@ -0,0 +1,192 @@ +package place.coho.app.wear.ui.timeline + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.wear.compose.material3.Card +import androidx.wear.compose.material3.MaterialTheme +import androidx.wear.compose.material3.Text +import coil.compose.AsyncImage +import place.coho.app.wear.api.models.Status +import place.coho.app.wear.ui.components.htmlToPlainText +import place.coho.app.wear.ui.components.relativeTime + +@Composable +fun PostCard( + status: Status, + onFavourite: ((String) -> Unit)?, + onBoost: ((String) -> Unit)?, + onClick: () -> Unit = {}, + modifier: Modifier = Modifier, +) { + // Show the actual content post (unwrap boosts) + val displayStatus = status.reblog ?: status + val isBoosted = status.reblog != null + + Card( + onClick = onClick, + modifier = modifier.fillMaxWidth(), + ) { + Column(modifier = Modifier.padding(4.dp)) { + // Boost indicator + if (isBoosted) { + Text( + text = "\uD83D\uDD01 ${status.account.displayName} boosted", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + Spacer(modifier = Modifier.height(2.dp)) + } + + // Author row: avatar + name + time + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth(), + ) { + AsyncImage( + model = displayStatus.account.avatar, + contentDescription = null, + modifier = Modifier + .size(20.dp) + .clip(CircleShape), + ) + Spacer(modifier = Modifier.width(6.dp)) + Text( + text = displayStatus.account.displayName.ifBlank { displayStatus.account.username }, + style = MaterialTheme.typography.labelMedium, + fontWeight = FontWeight.Bold, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.weight(1f), + ) + Text( + text = relativeTime(displayStatus.createdAt), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + + Spacer(modifier = Modifier.height(4.dp)) + + // Content warning + if (displayStatus.spoilerText.isNotBlank()) { + Text( + text = "⚠️ ${displayStatus.spoilerText}", + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.error, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + ) + } else { + // Post content (HTML → plain text, truncated) + Text( + text = htmlToPlainText(displayStatus.content), + style = MaterialTheme.typography.bodySmall, + maxLines = 4, + overflow = TextOverflow.Ellipsis, + lineHeight = 16.sp, + ) + } + + // Media indicator + if (displayStatus.mediaAttachments.isNotEmpty()) { + Spacer(modifier = Modifier.height(2.dp)) + Text( + text = "📎 ${displayStatus.mediaAttachments.size} attachment(s)", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + + Spacer(modifier = Modifier.height(4.dp)) + + // Quick actions row (only when authenticated) + if (onFavourite != null || onBoost != null) { + Row( + horizontalArrangement = Arrangement.SpaceEvenly, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth(), + ) { + // Favourite button + if (onFavourite != null) { + ActionChip( + label = if (displayStatus.favourited) "❤\uFE0F" else "\uD83E\uDD0D", + count = displayStatus.favouritesCount, + onClick = { onFavourite(displayStatus.id) }, + ) + } + // Boost button + if (onBoost != null) { + ActionChip( + label = if (displayStatus.reblogged) "\uD83D\uDD01" else "\uD83D\uDD04", + count = displayStatus.reblogsCount, + onClick = { onBoost(displayStatus.id) }, + ) + } + // Reply count (read-only) + Text( + text = "\uD83D\uDCAC ${displayStatus.repliesCount}", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(vertical = 8.dp), + ) + } + } else { + // Read-only stats row + Row( + horizontalArrangement = Arrangement.SpaceEvenly, + modifier = Modifier.fillMaxWidth(), + ) { + Text( + text = "❤\uFE0F ${displayStatus.favouritesCount}", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + Text( + text = "\uD83D\uDD01 ${displayStatus.reblogsCount}", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + Text( + text = "\uD83D\uDCAC ${displayStatus.repliesCount}", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + } + } + } +} + +@Composable +private fun ActionChip( + label: String, + count: Int, + onClick: () -> Unit, +) { + androidx.wear.compose.material3.TextButton( + onClick = onClick, + ) { + Text( + text = "$label $count", + style = MaterialTheme.typography.labelSmall, + ) + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostDetailScreen.kt b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostDetailScreen.kt new file mode 100644 index 0000000..04b5764 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostDetailScreen.kt @@ -0,0 +1,234 @@ +package place.coho.app.wear.ui.timeline + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.wear.compose.foundation.lazy.ScalingLazyColumn +import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState +import androidx.wear.compose.material3.Card +import androidx.wear.compose.material3.MaterialTheme +import androidx.wear.compose.material3.ScreenScaffold +import androidx.wear.compose.material3.Text +import coil.compose.AsyncImage +import place.coho.app.wear.api.models.Status +import place.coho.app.wear.ui.components.htmlToPlainText +import place.coho.app.wear.ui.components.relativeTime + +@Composable +fun PostDetailScreen( + status: Status, + onFavourite: ((String) -> Unit)?, + onBoost: ((String) -> Unit)?, +) { + val displayStatus = status.reblog ?: status + val isBoosted = status.reblog != null + val listState = rememberScalingLazyListState() + + ScreenScaffold( + scrollState = listState, + ) { + ScalingLazyColumn( + state = listState, + verticalArrangement = Arrangement.spacedBy(4.dp), + modifier = Modifier.fillMaxSize(), + ) { + // Boost indicator + if (isBoosted) { + item { + Text( + text = "\uD83D\uDD01 ${status.account.displayName} boosted", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.padding(horizontal = 8.dp), + ) + } + } + + // Author info + item { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 8.dp), + ) { + AsyncImage( + model = displayStatus.account.avatar, + contentDescription = null, + modifier = Modifier + .size(28.dp) + .clip(CircleShape), + ) + Spacer(modifier = Modifier.width(8.dp)) + Column(modifier = Modifier.weight(1f)) { + Text( + text = displayStatus.account.displayName.ifBlank { + displayStatus.account.username + }, + style = MaterialTheme.typography.labelMedium, + fontWeight = FontWeight.Bold, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + Text( + text = "@${displayStatus.account.acct}", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } + } + } + + // Content warning + if (displayStatus.spoilerText.isNotBlank()) { + item { + Text( + text = "⚠\uFE0F ${displayStatus.spoilerText}", + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.error, + modifier = Modifier.padding(horizontal = 8.dp), + ) + } + } + + // Full post content (no truncation) + item { + Text( + text = htmlToPlainText(displayStatus.content), + style = MaterialTheme.typography.bodySmall, + lineHeight = 18.sp, + modifier = Modifier.padding(horizontal = 8.dp), + ) + } + + // Media attachments + if (displayStatus.mediaAttachments.isNotEmpty()) { + items(displayStatus.mediaAttachments.size) { index -> + val attachment = displayStatus.mediaAttachments[index] + val imageUrl = attachment.previewUrl ?: attachment.url + + if (attachment.type == "image" || attachment.type == "gifv") { + Card( + onClick = { }, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 8.dp), + ) { + AsyncImage( + model = imageUrl, + contentDescription = attachment.description, + contentScale = ContentScale.Crop, + modifier = Modifier + .fillMaxWidth() + .aspectRatio(16f / 9f) + .clip(RoundedCornerShape(8.dp)), + ) + } + } else { + Text( + text = "\uD83C\uDFA5 ${attachment.type} attachment", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(horizontal = 8.dp), + ) + } + } + } + + // Timestamp + item { + Text( + text = relativeTime(displayStatus.createdAt), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(horizontal = 8.dp), + ) + } + + // Stats & actions + item { + Row( + horizontalArrangement = Arrangement.SpaceEvenly, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 8.dp), + ) { + if (onFavourite != null) { + ActionChip( + label = if (displayStatus.favourited) "❤\uFE0F" else "\uD83E\uDD0D", + count = displayStatus.favouritesCount, + onClick = { onFavourite(displayStatus.id) }, + ) + } else { + Text( + text = "❤\uFE0F ${displayStatus.favouritesCount}", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + + if (onBoost != null) { + ActionChip( + label = if (displayStatus.reblogged) "\uD83D\uDD01" else "\uD83D\uDD04", + count = displayStatus.reblogsCount, + onClick = { onBoost(displayStatus.id) }, + ) + } else { + Text( + text = "\uD83D\uDD01 ${displayStatus.reblogsCount}", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + + Text( + text = "\uD83D\uDCAC ${displayStatus.repliesCount}", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(vertical = 8.dp), + ) + } + } + } + } +} + +@Composable +private fun ActionChip( + label: String, + count: Int, + onClick: () -> Unit, +) { + androidx.wear.compose.material3.TextButton( + onClick = onClick, + ) { + Text( + text = "$label $count", + style = MaterialTheme.typography.labelSmall, + ) + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineScreen.kt b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineScreen.kt new file mode 100644 index 0000000..10ca751 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineScreen.kt @@ -0,0 +1,127 @@ +package place.coho.app.wear.ui.timeline + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.wear.compose.foundation.lazy.ScalingLazyColumn +import androidx.wear.compose.foundation.lazy.items +import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState +import androidx.wear.compose.material3.CircularProgressIndicator +import androidx.wear.compose.material3.ListHeader +import androidx.wear.compose.material3.MaterialTheme +import androidx.wear.compose.material3.ScreenScaffold +import androidx.wear.compose.material3.Text +import androidx.wear.compose.material3.TextButton +import place.coho.app.wear.R +import place.coho.app.wear.api.models.Status +import place.coho.app.wear.sync.AuthState + +@Composable +fun TimelineScreen( + auth: AuthState?, + onNavigateToNotifications: (() -> Unit)? = null, + onPostClick: ((Status) -> Unit)? = null, + viewModel: TimelineViewModel = viewModel(), +) { + val uiState by viewModel.uiState.collectAsState() + + LaunchedEffect(auth) { + viewModel.loadTimeline(auth) + } + + when (val state = uiState) { + is TimelineUiState.Loading -> { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.fillMaxSize(), + ) { + CircularProgressIndicator() + } + } + + is TimelineUiState.Error -> { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.fillMaxSize().padding(16.dp), + ) { + Text( + text = stringResource(R.string.error_no_connection), + textAlign = TextAlign.Center, + style = MaterialTheme.typography.bodySmall, + ) + } + } + + is TimelineUiState.Success -> { + val listState = rememberScalingLazyListState() + + ScreenScaffold( + scrollState = listState, + ) { + ScalingLazyColumn( + state = listState, + verticalArrangement = Arrangement.spacedBy(4.dp), + modifier = Modifier.fillMaxSize(), + ) { + item { + ListHeader { + Text( + if (auth?.isAuthenticated == true) + stringResource(R.string.timeline_title) + else + stringResource(R.string.trending_title) + ) + } + } + + items(state.posts, key = { it.id }) { status -> + PostCard( + status = status, + onFavourite = if (viewModel.isAuthenticated) { + { viewModel.toggleFavourite(it) } + } else null, + onBoost = if (viewModel.isAuthenticated) { + { viewModel.toggleBoost(it) } + } else null, + onClick = { onPostClick?.invoke(status) }, + ) + } + + // Navigate to notifications (authenticated only) + if (onNavigateToNotifications != null) { + item { + TextButton( + onClick = onNavigateToNotifications, + modifier = Modifier.fillMaxWidth(), + ) { + Text("🔔 ${stringResource(R.string.notifications_title)}") + } + } + } + + // Refresh button at the bottom + item { + TextButton( + onClick = { viewModel.refresh() }, + modifier = Modifier.fillMaxWidth(), + ) { + Text("Refresh") + } + } + } + } + } + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineViewModel.kt b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineViewModel.kt new file mode 100644 index 0000000..bc727b6 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineViewModel.kt @@ -0,0 +1,123 @@ +package place.coho.app.wear.ui.timeline + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import place.coho.app.wear.api.models.Status +import place.coho.app.wear.data.TimelineRepository +import place.coho.app.wear.sync.AuthState + +sealed interface TimelineUiState { + data object Loading : TimelineUiState + data class Success(val posts: List) : TimelineUiState + data class Error(val message: String) : TimelineUiState +} + +class TimelineViewModel( + private val repository: TimelineRepository = TimelineRepository(), +) : ViewModel() { + + private val _uiState = MutableStateFlow(TimelineUiState.Loading) + val uiState: StateFlow = _uiState + + private var currentAuth: AuthState? = null + val isAuthenticated: Boolean get() = currentAuth?.isAuthenticated == true + + fun loadTimeline(auth: AuthState?) { + currentAuth = auth + viewModelScope.launch { + _uiState.value = TimelineUiState.Loading + try { + val posts = if (auth != null && auth.isAuthenticated) { + repository.getHomeTimeline(auth) + } else { + repository.getPublicTimeline() + } + _uiState.value = TimelineUiState.Success(posts) + } catch (e: Exception) { + _uiState.value = TimelineUiState.Error( + e.message ?: "Failed to load timeline" + ) + } + } + } + + fun refresh() { + loadTimeline(currentAuth) + } + + fun toggleFavourite(statusId: String) { + val auth = currentAuth ?: return + val currentState = _uiState.value as? TimelineUiState.Success ?: return + + // Optimistic update + val updatedPosts = currentState.posts.map { status -> + val target = status.reblog ?: status + if (target.id == statusId) { + val updated = target.copy( + favourited = !target.favourited, + favouritesCount = target.favouritesCount + if (target.favourited) -1 else 1, + ) + if (status.reblog != null) status.copy(reblog = updated) else updated + } else { + status + } + } + _uiState.value = TimelineUiState.Success(updatedPosts) + + // Fire API call + viewModelScope.launch { + try { + val target = currentState.posts.firstNotNullOfOrNull { s -> + val t = s.reblog ?: s; if (t.id == statusId) t else null + } ?: return@launch + if (target.favourited) { + repository.unfavouriteStatus(auth, statusId) + } else { + repository.favouriteStatus(auth, statusId) + } + } catch (_: Exception) { + // Revert on failure + refresh() + } + } + } + + fun toggleBoost(statusId: String) { + val auth = currentAuth ?: return + val currentState = _uiState.value as? TimelineUiState.Success ?: return + + // Optimistic update + val updatedPosts = currentState.posts.map { status -> + val target = status.reblog ?: status + if (target.id == statusId) { + val updated = target.copy( + reblogged = !target.reblogged, + reblogsCount = target.reblogsCount + if (target.reblogged) -1 else 1, + ) + if (status.reblog != null) status.copy(reblog = updated) else updated + } else { + status + } + } + _uiState.value = TimelineUiState.Success(updatedPosts) + + // Fire API call + viewModelScope.launch { + try { + val target = currentState.posts.firstNotNullOfOrNull { s -> + val t = s.reblog ?: s; if (t.id == statusId) t else null + } ?: return@launch + if (target.reblogged) { + repository.unreblogStatus(auth, statusId) + } else { + repository.reblogStatus(auth, statusId) + } + } catch (_: Exception) { + refresh() + } + } + } +} diff --git a/android/wear/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/wear/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..4df90c3 --- /dev/null +++ b/android/wear/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/android/wear/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/wear/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..4df90c3 --- /dev/null +++ b/android/wear/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/android/wear/src/main/res/mipmap-hdpi/ic_launcher.webp b/android/wear/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..90ce47cc947f3ffd565cf2765633e68be88514d1 GIT binary patch literal 2178 zcmV-|2z~cbNk&F`2mkiWw(_dWoCM*Cqs=6vNse;Zvj^{j6pcXN@* zUw}wWbol~EKzzXiV;}+=O49Z(l9b;sv$CqIvb}3&aCdjNOR#5UJC5LT1Kq(L*t*-e z`%Jsh<*EN4T1EU5TYgC48Mr6X5o3wF6F~`*ZPT_@a~YRuJ*edYfy|NNs(-M)WT;*4Oo9+-q+wUDFkX!W8uBtmf}uX}uMYa+8C0qx0PT)VZFW-mr+N)WT~bXzCPh?gOXLbD;a&5KN$ zeYcrgrmEohg&*d={)bIXBnX+AHg)~RkMsDV8C>+1P=2QnQBlnFGE+NskqI>YW2o9l zM5N7zp!LV*2+2nvqGW*|6<;<7mWT?#6ln3?=&;UchE#EC8*4_U6RC)Nf6G)il-!^!GM zUylK;DPB^y0FV$zwf+CrTsRiqHP&1*vbF5IDn znZ!u2AYy#rdkY?ZVs+cMTw5U0wDpKlj(P)~=>Ual% z<`gceUCOcc($|*X^-R5d82cpd{(zO<-H-t`{)F$w5*uTCh7v2?@QRt~G{{n38DzQG zQ^_;5l7PUSR$lkQ;EXrKVdS&t+vNKMEUbVwgaE`+mKlRc`z4j8v+@6|%9x`R$q}N9 zXcg2R)?M<_ij(h@Whz~8*ugp5J#os0JZ=ClR1vV>zAbf%s`HjXF%tYPHXj$q_IcF9s-It zr)Mev8IuEX8b=fe0kX!fHuetJ+w3E$0K~EYIxASGgTp7@G5q5}SQBSA0KlTS^a}@m z{)ib4BTcSZ`iG3&rmvnJSY-e<6mhu-xq#LsG42tVo}JPH;Ou7Nm!aa2up zUAB^*U3YtTzS(Isy*=n?30a5*eB{Cy>n-R#p@T0l?`DeE1f9d!<9W;s{cFCk=TBeg z+H>^*+J*Kx{*}?uoS)keXuudu2_K;MM^nH6GE$`JPP4vp$h$u<8wP+(DMvh#xkE{} zY$?Gg>+6r8y9*vn{P?d;RfELjPmF&X@>rFz>)fxs0FcYT01mz*b_XCaQz65J)L4jM zKok@&`p<3;!7e=$(mRpVYP672)@ zJCh3l*tTrt7L;>Q3arz{H|9K zIspLK*27%6XV=Pa*lqH~ogJ8O9A-DY2XKFVFWhsmpZ^*#Bj$S=1V9f!?+(~o7(fDe zbx5Ojgu#CgT+I6W?luq2pTz~IIdcyEnb=Q#16AdrkXjrOLcpY8Xoj809tP6%|CQWS z>k>wTl9Sgs%bxpOy(eIgDGI4^pLoDix1lsd0ZjN^Hv{&w{Ko?AA;yO6jgeX^T$mnw zvEs!$GSYTBEnGWU>62k=Rv2K2bwh?6XgSEpDc^qdK!-c0<**JfW(D~yton@GI%EKN z6=dVvHbU@;b^t15P-_wzVqorTdw>0v%sEs#OJDj)Wxz+|M;5YfeCBF262b%{6*INs zpErsqV2cA4QHsdVz3KV&F03&4*l*NP>|IxVqlY~q2Ki%6oKcTBzKwsrPXrK!$CDBs zPOutlEZ!{qg~`q&cO`%#M<9v)gyG|J zhgEw;GiMK4(8;H8dkO?0^qqk{AhMBykcWL5zfnu$V2GNnU*ZYz{6jS8ux<5?0ghdzHf*7}o>LQ=q@C#$g_O)Z>yz-0r}9VW{|=r< E1z4{a;Q#;t literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/android/wear/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..5db16075550506a0fde6a146a5a16220462cbdb1 GIT binary patch literal 3542 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 literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-mdpi/ic_launcher.webp b/android/wear/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..6b52f44292a751d2884245b7a9ae5d95ea18ef06 GIT binary patch literal 1418 zcmV;51$FvTNk&G31pok7MM6+kP&iC=1pojqFTe{BO`vVtHjwPi|6iQ;hlu`9z^*@& zhi;%9kcEP_jU3;A@ceP^$Dy`uBZv37`u)fJIzmm`NKz0ie|Rnr!dvt|03s^@L$jo` z0k(C=mH@81DSQB$Pk(@UiTI2~lC*7V8~xpeFf%hVXPZOhAaeuXVBiQ-v&tEUVHaj* zW-_b02OL-0HQ9f|6ddM~bKADDJ!?ORZQHhOci(vH*mnMalisdu+h%9mukk(4b0kQT zZQ52a z{IeMe1pfqo+I}4$`*BQ=5zEhsV(my;H1UY|bbfw(!0~w*SpU3^m|ZmxR2d}b{tpJVoxhHdz#Pv2n|}z&R1lcX41t3=R|JR%2tST+ zGEo2(iSi%^tgOE3dWo;TR1(HZh*yvwA%8$+L?slm0OrQfBVJrwJ2x^3LaelSC9s+^ zQ$49R#Xf}b2;z-+DDM>j3aol7qqLw`{N=juwlSeS^6 zp%E9Gq;?4c3dw>tPD+IWz-7{);sfBWtm#;FZm98Twb$%FiX@7){zO|@U2|6H6M`d) zTie$q5`ZR|EahOmtGXA|P?wpjCPKbJdQg)6H|R`VDtGZnN$nJD5b@f%35HBalT6p* zNQ^9~{T5(lfUx($5JaHa>smV%o9`4XSR!m+jG&ydtdxcX&sfsY0f8oI{_4f7rOcYv~RsECO~kCoHNwz=M1pz5{ta*6aNzF#aOkRY|+M5_>$5KJ2l$ zRz;4SKWgT-)(r+CpkGl@JtC+&!aIh!#-zOBq@w7F>bWnKO?-ib)n{7STh0>z01vWL znk)n%mDBDW@K8AdleiZrd?ff_7|$jDf&diQCf)ThQa$unC*PGox!%dsm{fl@H&qYuG2!jNQ;vh<)$%1k; z;{>F%7{=s@Z#p);GyQqLqiPMKY}iCqu?04Rd-{KTt< z`^?7N=>|)W751zqY_rBeTFh7k27nV1z5u*|E}bB>lJeyO5;a~tbisaNbwUQ28|(SEBk+}zOXH)`V0o4 zw1{SA`(;<*G@T;EIxZ`9YrAD1EgD3IPn(f!B1-$RW{=z0kNaqWij;*zXnD_R z*j*n5REuHVc8;)}A^8Fb>VvoVxW4K-jITi34WKs&+;GO>uy{Lxzhy=I6WkC~p!;W8 YE&ky*L2jKzPRXyKt@S_o+`s2J0JyHBnE(I) literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/android/wear/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..79b266c8b153c46a5919ffc07cd0d74e19696992 GIT binary patch literal 2024 zcmVA=j)%wnd~1GF<|?2F8hPP~ehwW&>)`2!d$GuvyPRFN5?HnTleO{q3EiPkh` zr)_MrKOmO26m?00003kg*|u%lwr$(Cy(&p}->5O$wr$(iNw94)m_)@Y66T;&(qE71rB+8o1{!o>+L?|4EZ3Np&Zb2CcIj*9{OPG?z)z z$g(U?n%kLadKlPnP4ty;4kPQgV164u?5czl(%bA;03s+IM4 z7(o~sQIEZIxDv(T>uyth7+X~P{FkBd$9$P?Y0@oDkS>aG-`1D)K8AUXVDUYsyV{A=9(bVM zIK!3+7T*VCxzmVbMJpjo{QX|r{*{oAYf5!#Qj7FI%K9Q9agiuUM1CHkBvJu{S*VD|-I; z5GF5Vb4}Amvd6xL8yq2*ER{<`BR5Og>-#-JxSYh-bv<4Qfuw@f;Sf}?&$m>@s{ngk}HWGr(7JNL`IMS6Q%pPDS&XN{MX(sqVWxhSHm+A%u{o9VdU^L%~s{*odk*~Xnx<(wLZeu1D7PP|yFq#%5PY`<1c56leOlN31;RBf z-`BKwpGAnhSgWaxCa=BCW@~lSdJM>6`*Yx*6|x4>HC^l;!Qsa$tj8!w8mEQ{B815# zgmBg@a|7z|jqXjA!nE^r)(9?5C}}(2??2HFT{Pf zro?cBdidc)NY{03%t6|FE~Q`zx~2mKBaGvBfHApkwQrHJ2sFdcZb>*?kyI{<9D50b z5Yl>z-+LQx0N>wuzik7tZC)(-|Myn;cXAEu_hs3BKxnQB>RZ?Fna6xYA4*X*9(U+I6_Dt zOk;b@j2pfNQkRg$uoZ*_#BDH{G@#Kb*iey-WbqFs#)bJ#fz&;4F>C{MoDt4VqSF8} z`R-w=u1hW0X|~7XaX*KhhE8FtT9LcG6C5s|WEhXzB5^PB@^8CxH$bo=_&1Um!RdRM zWPr<@1c?i)1r{A6>IAu)o@P2ktaJnz!?kmb z0;Fa9jj;^^#&}`1d?Fno)K}P_JWXw4ZU;&kW2|j-fMnkFSkjVH3k{w0z~PLJoPMlO zL7zwFI-chP!r|T-A-NE>j=k*wm`L#5Kz)lfNeNtnOG--E!-XvFYn4Dp>-oltWl*vk z*ug1;*&dGvg*>WVrAXNicSZphcn9JIw~DqSzo6yX?SZ z763*N77z+!Rf`QY^xo1n#2Di`X>_$p)ROc5o&}*IrW?%Y^G^z@gOboeyQf5VOJ2dcQew6^*IK+hehq1JF`+ ztW?H_GhmoL@lOk=3S+EW@B$E}pLGw~O_QT$igiBealMh?sO0ddBi377Uc#SJO8su9 zMot(3E{IAbYUTM^?X3K<5fBO2LJtahfZMoMiKnEG)Y4TpR$+{#q4X?&zMRF0m~0=T zg;W=nB;s`1N8V+s`9H&~ex?_fe>gXG4qerX?0Z%#*NV~qqM+*$e0JD5i`W0X^PzK2 GSuO;sSKvbc literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-mdpi/ic_launcher_monochrome.webp b/android/wear/src/main/res/mipmap-mdpi/ic_launcher_monochrome.webp new file mode 100644 index 0000000000000000000000000000000000000000..f8234fa21697b83626d3370e341fb70da01c2e71 GIT binary patch literal 2304 zcmV+b3IFy|Nk&Ha2mk)H$Q9q*lnxy%j2xwlVV}h04g#ww8i^qRz1; z%4HSGV?*A2M4|FYQ9{uoT2bZvpd=}RCgP5qOEIOn;?uqo$zYM{plx*NCM#(sQ7x-@ z{-xh}*^ijvGM0mu3!g;UF-m!yeDA0 zpv6bQ-7PLv6w+e=^8xxNRKwyu_!f{?l2^h+eiHSMRS>;>tO@hQ^W&Wd*LnZh*{P0> zzG(p3M2CP)?>C8A14dPugVZUPo%1>-ot=qi)Efl2*sRig=lcOexXe6&f~S3J@=&Z?d#D;J`T9j)rz zk955wT=8!@@O0-6(5kToSpl2B8bu-tU3RvA#FRCei(J4P+8Hamx=z7~xI= z1B}?c{MGnI2@1sdtmO_%5aC`>WwAx&@n7XZWif~z^46TY=jj@_sV;AatI~5P$FtCR z+%Br@NCepwlK=n=!!-*5%k~?&3uxa zkyfTq0=D1I7L>0qk2GHt)MuzkGQ=jiU3+veh*lWj(LFm2n8uwaIr>s*90 zAET)sd3EH-((|W>Mp_1vyTQW(b|{Z$VN@HdQLMbD}x(t+Q?0v`y1g`3e!{ zXCpjn4Kh*$qiK0}&%yyXBR!I4Th>U&8Q1>JCYf?mt~>pdrw~i!@k?cE!$3BRGRpFZ zt{jpNX{2RYj^mKY(EVJKa-(IRI{7g~SkN@hj<9$e=4-6#Jf>pQ<$;Mvc1kqoe{!0p*(zUeROjqB$Y^mHg$ZIWk5stdNuj}t}IS31&(mprZ$fQ;;s*6i7pX1cI*iD7Hkr3eR| z>!weal>8C5=Cn7WyxY?83rAXt@RGX(0hpV;S%nu{H+q`wLF(3J(qd>4wmuwt16?Gg zza?Ew7fBYdxZb5HrXXw_0sJJwPEv#bXX!d-@(|IG!|QMSrtLxqps^5czKGHg_eQ<{^A70+?+cOtsFE>(`=Q;$w5YnWH+{~ zYqS%D{n2$KfN!5tgb}p8s1pQT*Lj2kY6e?ni>5u?WE8KLTIq=yV|~4nOw>7J3jP|9eK&4jHZ5MX#xm3>bj2Gw{qIKpWNPuH<$mJPAn0==Or!+II@Pe{Y)W}&XSaV zmq;H)`N2AI!2d)5BBCH{CRG@Z+=i&@1OZzQbmq}FhV(W;)wd|Z_ej8g28xZ(y$`jJ zmOZ+RG3Eo-@qqvJ3Cf8g!rIftyL2Vzkx!8zO-Nul7hIJg9C&({l9Unyszy5tx%fSC zL-mdps`lyIh_Fr^T0;)m){FdFM!2l(?-7v~UXd=0$exb?KIsz@h`TqM_CK*prP6(O zRpll@0x^Nn98ei>KBNpp5~-$HdO%DdVggYR z#tY;F%0c{^NGnPk#x3fpd5OJ&rKUx+4VwChOp4G}M^t0o$7H8;!00Dp?o)=$}qEjfEUpSKp z6Ifc*GFl@2Ec*0)ARh+z-Bo{&NQXA&JdClLGg4$3>D@fw?-ys_*MI*lU~fSw#+ayc z646`AGtr|3B$6W%$pdBMzw|6xKuP9D&fyV15p|sauDwC6o9bP9O2?zkCWucT>VKD= aKZ*<^7%K}cE)Uk20G0{@3m+L~3`Z@Z7+iAz literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/android/wear/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..65f0f453c8bf9c2a4de0b49917a04cc2c1d38900 GIT binary patch literal 2438 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 E0CCU7EC2ui literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-xhdpi/ic_launcher.webp b/android/wear/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..9ae37ce9b24e14289026b78e4d3e7c5afa127edd GIT binary patch literal 3112 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 CuK*+f literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/android/wear/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..90c0dabf3c9c8b28b67d3637f4cfc2db0359930e GIT binary patch literal 5468 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 S*Z&1I`cI?(T%`+*X6iWKE0wGO literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.webp b/android/wear/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.webp new file mode 100644 index 0000000000000000000000000000000000000000..da5474261e7ad01ebcdc7289b8c5045d129d8758 GIT binary patch literal 5726 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 QxQ1oZf13W&^q&bMaVhUH)Bpeg literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/android/wear/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..1be4151c3fcedf6128dd5cbbe558efe4083a012d GIT binary patch literal 5792 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 literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/android/wear/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..2118bb4824c5a97d3deda63fde01c27bc3a760c4 GIT binary patch literal 4918 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 Uf8&4Sf8&1x&j@mbjQ@?|0TF%O7ytkO literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.webp b/android/wear/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.webp new file mode 100644 index 0000000000000000000000000000000000000000..1a4adf80fef147447db9215093fb60ad83bc7eaa GIT binary patch literal 10934 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 YkpB<)|B(L=`Tvmr5BdL){|^Bd0Cd#icmMzZ literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/android/wear/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..67b59bb8147d13253f8a96b0dfbea219ddee0015 GIT binary patch literal 9796 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 aG<+Ajbh|WzX-diqWS1`Q2<$d}-xF-jhG(t- literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/android/wear/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..3de3ee8738de9f94bfdcee5b0d78419489e6ae51 GIT binary patch literal 16546 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 literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.webp b/android/wear/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.webp new file mode 100644 index 0000000000000000000000000000000000000000..63908e3f2db941e734c545205078562de7c40e65 GIT binary patch literal 18554 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 F<`E}UJb(ZI literal 0 HcmV?d00001 diff --git a/android/wear/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/android/wear/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..6f11068246e6b01bf90277865c7851730fa8a0d0 GIT binary patch literal 14286 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 + + #EFC4C4 + diff --git a/android/wear/src/main/res/values/strings.xml b/android/wear/src/main/res/values/strings.xml new file mode 100644 index 0000000..3b6a120 --- /dev/null +++ b/android/wear/src/main/res/values/strings.xml @@ -0,0 +1,25 @@ + + + Coho + Home + Trending + Notifications + Loading… + Can\'t connect. Check your watch\'s internet. + Open Coho on your phone to connect. + Pull to refresh + Favorite + Boost + %s boosted + followed you + favorited your post + boosted your post + mentioned you + poll ended + posted + edited a post + just now + %dm ago + %dh ago + %dd ago + diff --git a/src/app-index.ts b/src/app-index.ts index b9592b8..847e7fc 100644 --- a/src/app-index.ts +++ b/src/app-index.ts @@ -313,6 +313,9 @@ export class AppIndex extends LitElement { // Sync server URL to native SharedPreferences for the Android widget this.syncServerToNativeWidget(); + + // Sync credentials to paired Wear OS watch + this.syncCredentialsToWearOS(); } /** @@ -334,6 +337,33 @@ export class AppIndex extends LitElement { } } + /** + * Pushes auth credentials to the paired Wear OS watch via the + * WearSyncBridge Capacitor plugin so the watch can independently + * call the Mastodon API. + */ + private async syncCredentialsToWearOS() { + try { + const { isNativePlatform } = await import('./utils/platform.js'); + if (!isNativePlatform()) return; + + const { registerPlugin } = await import('@capacitor/core'); + const WearSyncBridge = registerPlugin('WearSyncBridge'); + const server = localStorage.getItem('server') || ''; + const accessToken = localStorage.getItem('accessToken') || ''; + const acct = localStorage.getItem('acct') || ''; + if (!server || !accessToken) return; + + await (WearSyncBridge as any).syncCredentials({ + server, + accessToken, + acct, + }); + } catch { + // Wear sync bridge not available — ignore + } + } + /** * Check if the user has valid authentication credentials * Sets isAuthenticated to true for returning users, false for new users From f7020609739b8d93cc13e3422b8a43521661a28d Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Fri, 20 Mar 2026 00:01:55 -0700 Subject: [PATCH 20/26] layout fixes + udpate deps + posting from the watch app --- android/build.gradle | 2 +- android/wear/build.gradle | 12 +- .../place/coho/app/wear/api/MastodonApi.kt | 10 + .../app/wear/data/NotificationRepository.kt | 4 +- .../coho/app/wear/data/TimelineRepository.kt | 9 + .../java/place/coho/app/wear/ui/WearApp.kt | 23 ++- .../coho/app/wear/ui/compose/ComposeScreen.kt | 186 ++++++++++++++++++ .../app/wear/ui/compose/ComposeViewModel.kt | 43 ++++ .../ui/notifications/NotificationsScreen.kt | 62 +++++- .../notifications/NotificationsViewModel.kt | 51 ++++- .../coho/app/wear/ui/timeline/PostCard.kt | 8 +- .../app/wear/ui/timeline/PostDetailScreen.kt | 32 +-- .../app/wear/ui/timeline/TimelineScreen.kt | 88 ++++++++- .../app/wear/ui/timeline/TimelineViewModel.kt | 54 ++++- android/wear/src/main/res/drawable/ic_add.xml | 9 + android/wear/src/main/res/drawable/ic_mic.xml | 9 + android/wear/src/main/res/values/strings.xml | 8 + 17 files changed, 571 insertions(+), 39 deletions(-) create mode 100644 android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeScreen.kt create mode 100644 android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeViewModel.kt create mode 100644 android/wear/src/main/res/drawable/ic_add.xml create mode 100644 android/wear/src/main/res/drawable/ic_mic.xml diff --git a/android/build.gradle b/android/build.gradle index f18cf80..b469df0 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - + repositories { google() mavenCentral() diff --git a/android/wear/build.gradle b/android/wear/build.gradle index 9ac123d..253cf97 100644 --- a/android/wear/build.gradle +++ b/android/wear/build.gradle @@ -7,7 +7,7 @@ android { compileSdk = rootProject.ext.compileSdkVersion defaultConfig { - applicationId "place.coho.app.wear" + applicationId "place.coho.app" minSdkVersion 30 // Wear OS 3+ targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 @@ -40,9 +40,10 @@ dependencies { def composeBom = platform('androidx.compose:compose-bom:2024.12.01') implementation composeBom - implementation 'androidx.wear.compose:compose-material3:1.0.0-alpha32' - implementation 'androidx.wear.compose:compose-foundation:1.5.0-alpha06' - implementation 'androidx.wear.compose:compose-navigation:1.5.0-alpha06' + implementation 'androidx.wear.compose:compose-material3:1.5.6' + implementation 'androidx.wear.compose:compose-foundation:1.5.6' + implementation 'androidx.wear.compose:compose-navigation:1.5.6' + implementation 'androidx.compose.material3:material3:1.3.1' implementation 'androidx.compose.ui:ui-tooling-preview' debugImplementation 'androidx.compose.ui:ui-tooling' @@ -51,9 +52,6 @@ dependencies { implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.9.0' implementation 'androidx.lifecycle:lifecycle-runtime-compose:2.9.0' - // Horologist (Google's Wear OS best-practice library) - implementation 'com.google.android.horologist:horologist-compose-layout:0.6.22' - // Networking implementation 'com.squareup.retrofit2:retrofit:2.11.0' implementation 'com.squareup.retrofit2:converter-moshi:2.11.0' diff --git a/android/wear/src/main/java/place/coho/app/wear/api/MastodonApi.kt b/android/wear/src/main/java/place/coho/app/wear/api/MastodonApi.kt index a7916e6..e442c37 100644 --- a/android/wear/src/main/java/place/coho/app/wear/api/MastodonApi.kt +++ b/android/wear/src/main/java/place/coho/app/wear/api/MastodonApi.kt @@ -2,6 +2,8 @@ package place.coho.app.wear.api import place.coho.app.wear.api.models.Notification import place.coho.app.wear.api.models.Status +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded import retrofit2.http.GET import retrofit2.http.POST import retrofit2.http.Path @@ -37,4 +39,12 @@ interface MastodonApi { @Query("limit") limit: Int = 20, @Query("max_id") maxId: String? = null, ): List + + @FormUrlEncoded + @POST("api/v1/statuses") + suspend fun postStatus( + @Field("status") status: String, + @Field("visibility") visibility: String = "public", + @Field("in_reply_to_id") inReplyToId: String? = null, + ): Status } diff --git a/android/wear/src/main/java/place/coho/app/wear/data/NotificationRepository.kt b/android/wear/src/main/java/place/coho/app/wear/data/NotificationRepository.kt index bf548ca..ffd0869 100644 --- a/android/wear/src/main/java/place/coho/app/wear/data/NotificationRepository.kt +++ b/android/wear/src/main/java/place/coho/app/wear/data/NotificationRepository.kt @@ -20,7 +20,7 @@ class NotificationRepository { return api!! } - suspend fun getNotifications(auth: AuthState): List { - return getApi(auth).getNotifications(limit = 20) + suspend fun getNotifications(auth: AuthState, maxId: String? = null): List { + return getApi(auth).getNotifications(limit = 20, maxId = maxId) } } diff --git a/android/wear/src/main/java/place/coho/app/wear/data/TimelineRepository.kt b/android/wear/src/main/java/place/coho/app/wear/data/TimelineRepository.kt index 7ba6477..e937ecd 100644 --- a/android/wear/src/main/java/place/coho/app/wear/data/TimelineRepository.kt +++ b/android/wear/src/main/java/place/coho/app/wear/data/TimelineRepository.kt @@ -51,4 +51,13 @@ class TimelineRepository { suspend fun unreblogStatus(auth: AuthState, id: String): Status { return getApi(auth).unreblogStatus(id) } + + suspend fun postStatus( + auth: AuthState, + status: String, + visibility: String = "public", + inReplyToId: String? = null, + ): Status { + return getApi(auth).postStatus(status, visibility, inReplyToId) + } } diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/WearApp.kt b/android/wear/src/main/java/place/coho/app/wear/ui/WearApp.kt index a6f5e04..a9056f3 100644 --- a/android/wear/src/main/java/place/coho/app/wear/ui/WearApp.kt +++ b/android/wear/src/main/java/place/coho/app/wear/ui/WearApp.kt @@ -31,6 +31,7 @@ import kotlinx.coroutines.launch import place.coho.app.wear.api.models.Status import place.coho.app.wear.sync.AuthRepository import place.coho.app.wear.sync.AuthState +import place.coho.app.wear.ui.compose.ComposeScreen import place.coho.app.wear.ui.notifications.NotificationsScreen import place.coho.app.wear.ui.theme.CohoWearTheme import place.coho.app.wear.ui.timeline.PostDetailScreen @@ -75,9 +76,18 @@ fun WearApp(authRepository: AuthRepository) { selectedStatus = status navController.navigate("postDetail") }, + onCompose = { + navController.navigate("compose") + }, viewModel = timelineViewModel, ) - 1 -> NotificationsScreen(auth = authState) + 1 -> NotificationsScreen( + auth = authState, + onPostClick = { status -> + selectedStatus = status + navController.navigate("postDetail") + }, + ) } } @@ -116,6 +126,17 @@ fun WearApp(authRepository: AuthRepository) { ) } } + + composable("compose") { + ComposeScreen( + auth = authState, + onDismiss = { navController.popBackStack() }, + onPosted = { + navController.popBackStack() + timelineViewModel.refresh() + }, + ) + } } } } diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeScreen.kt b/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeScreen.kt new file mode 100644 index 0000000..e40ffd6 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeScreen.kt @@ -0,0 +1,186 @@ +package place.coho.app.wear.ui.compose + +import android.app.Activity +import android.content.Intent +import android.speech.RecognizerIntent +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.wear.compose.foundation.lazy.ScalingLazyColumn +import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState +import androidx.wear.compose.material3.CircularProgressIndicator +import androidx.wear.compose.material3.FilledTonalButton +import androidx.wear.compose.material3.ListHeader +import androidx.wear.compose.material3.MaterialTheme +import androidx.wear.compose.material3.ScreenScaffold +import androidx.wear.compose.material3.Text +import place.coho.app.wear.R +import place.coho.app.wear.sync.AuthState + +@Composable +fun ComposeScreen( + auth: AuthState, + onDismiss: () -> Unit, + onPosted: () -> Unit, + viewModel: ComposeViewModel = viewModel(), +) { + val composeState by viewModel.uiState.collectAsState() + var voiceText by remember { mutableStateOf("") } + var hasLaunched by remember { mutableStateOf(false) } + + val voiceIntent = remember { + Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply { + putExtra( + RecognizerIntent.EXTRA_LANGUAGE_MODEL, + RecognizerIntent.LANGUAGE_MODEL_FREE_FORM, + ) + putExtra(RecognizerIntent.EXTRA_PROMPT, "What's on your mind?") + } + } + + val voiceLauncher = rememberLauncherForActivityResult( + ActivityResultContracts.StartActivityForResult(), + ) { result -> + if (result.resultCode == Activity.RESULT_OK) { + val results = result.data?.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS) + voiceText = results?.firstOrNull() ?: "" + } + } + + // Auto-launch voice recognizer on first composition + LaunchedEffect(Unit) { + if (!hasLaunched) { + hasLaunched = true + voiceLauncher.launch(voiceIntent) + } + } + + // Navigate back on successful post + LaunchedEffect(composeState) { + if (composeState is ComposeUiState.Sent) { + viewModel.resetState() + onPosted() + } + } + + val listState = rememberScalingLazyListState() + val config = LocalConfiguration.current + val horizontalPadding = (config.screenWidthDp * 0.052f).dp + val verticalPadding = if (config.isScreenRound) (config.screenHeightDp * 0.22f).dp else 24.dp + val columnPadding = PaddingValues( + horizontal = horizontalPadding, + vertical = verticalPadding, + ) + + ScreenScaffold( + scrollState = listState, + ) { + when (composeState) { + is ComposeUiState.Sending -> { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.fillMaxSize(), + ) { + CircularProgressIndicator() + } + } + else -> { + ScalingLazyColumn( + state = listState, + verticalArrangement = Arrangement.spacedBy(4.dp), + contentPadding = columnPadding, + modifier = Modifier.fillMaxSize(), + ) { + item { + ListHeader { + Text(stringResource(R.string.compose_title)) + } + } + + // Voice text display + item { + Text( + text = voiceText.ifBlank { + stringResource(R.string.voice_no_speech) + }, + style = MaterialTheme.typography.bodySmall, + lineHeight = 18.sp, + textAlign = TextAlign.Center, + color = if (voiceText.isBlank()) { + MaterialTheme.colorScheme.onSurfaceVariant + } else { + MaterialTheme.colorScheme.onSurface + }, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 4.dp), + ) + } + + // Error message + if (composeState is ComposeUiState.Error) { + item { + Text( + text = (composeState as ComposeUiState.Error).message, + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.error, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth(), + ) + } + } + + // Action buttons + if (voiceText.isNotBlank()) { + item { + FilledTonalButton( + onClick = { voiceLauncher.launch(voiceIntent) }, + modifier = Modifier.fillMaxWidth(), + ) { + Text(stringResource(R.string.voice_retry)) + } + } + + item { + FilledTonalButton( + onClick = { viewModel.postStatus(auth, voiceText) }, + modifier = Modifier.fillMaxWidth(), + ) { + Text(stringResource(R.string.compose_post)) + } + } + } else { + item { + FilledTonalButton( + onClick = { voiceLauncher.launch(voiceIntent) }, + modifier = Modifier.fillMaxWidth(), + ) { + Text(stringResource(R.string.voice_retry)) + } + } + } + } + } + } + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeViewModel.kt b/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeViewModel.kt new file mode 100644 index 0000000..184fcf8 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeViewModel.kt @@ -0,0 +1,43 @@ +package place.coho.app.wear.ui.compose + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import place.coho.app.wear.data.TimelineRepository +import place.coho.app.wear.sync.AuthState + +sealed interface ComposeUiState { + data object Idle : ComposeUiState + data object Sending : ComposeUiState + data object Sent : ComposeUiState + data class Error(val message: String) : ComposeUiState +} + +class ComposeViewModel( + private val repository: TimelineRepository = TimelineRepository(), +) : ViewModel() { + + private val _uiState = MutableStateFlow(ComposeUiState.Idle) + val uiState: StateFlow = _uiState + + fun postStatus(auth: AuthState, text: String, visibility: String = "public") { + if (text.isBlank()) return + viewModelScope.launch { + _uiState.value = ComposeUiState.Sending + try { + repository.postStatus(auth, text, visibility) + _uiState.value = ComposeUiState.Sent + } catch (e: Exception) { + _uiState.value = ComposeUiState.Error( + e.message ?: "Failed to post" + ) + } + } + } + + fun resetState() { + _uiState.value = ComposeUiState.Idle + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsScreen.kt b/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsScreen.kt index 7b1976d..a38a1ee 100644 --- a/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsScreen.kt +++ b/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsScreen.kt @@ -12,10 +12,14 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -36,17 +40,21 @@ import androidx.wear.compose.material3.Text import coil.compose.AsyncImage import place.coho.app.wear.R import place.coho.app.wear.api.models.Notification +import place.coho.app.wear.api.models.Status import place.coho.app.wear.ui.components.htmlToPlainText import place.coho.app.wear.ui.components.relativeTime import place.coho.app.wear.sync.AuthState import androidx.compose.ui.res.stringResource +@OptIn(ExperimentalMaterial3Api::class) @Composable fun NotificationsScreen( auth: AuthState, + onPostClick: ((Status) -> Unit)? = null, viewModel: NotificationsViewModel = viewModel(), ) { val uiState by viewModel.uiState.collectAsState() + val isRefreshing by viewModel.isRefreshing.collectAsState() LaunchedEffect(auth) { viewModel.loadNotifications(auth) @@ -77,13 +85,40 @@ fun NotificationsScreen( is NotificationsUiState.Success -> { val listState = rememberScalingLazyListState() + val config = androidx.compose.ui.platform.LocalConfiguration.current + val horizontalPadding = (config.screenWidthDp * 0.052f).dp + val verticalPadding = if (config.isScreenRound) (config.screenHeightDp * 0.22f).dp else 24.dp + val columnPadding = androidx.compose.foundation.layout.PaddingValues( + horizontal = horizontalPadding, + vertical = verticalPadding, + ) + + // Trigger load-more when near the end of the list + val shouldLoadMore by remember { + derivedStateOf { + val lastVisibleIndex = listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0 + val totalItems = listState.layoutInfo.totalItemsCount + lastVisibleIndex >= totalItems - 3 && totalItems > 0 + } + } + LaunchedEffect(shouldLoadMore) { + if (shouldLoadMore && state.canLoadMore && !state.isLoadingMore) { + viewModel.loadMore() + } + } ScreenScaffold( scrollState = listState, ) { + PullToRefreshBox( + isRefreshing = isRefreshing, + onRefresh = { viewModel.refresh() }, + modifier = Modifier.fillMaxSize(), + ) { ScalingLazyColumn( state = listState, verticalArrangement = Arrangement.spacedBy(4.dp), + contentPadding = columnPadding, modifier = Modifier.fillMaxSize(), ) { item { @@ -93,18 +128,39 @@ fun NotificationsScreen( } items(state.notifications, key = { it.id }) { notification -> - NotificationCard(notification) + NotificationCard( + notification = notification, + onPostClick = onPostClick, + ) + } + + // Loading more indicator + if (state.isLoadingMore) { + item { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.fillMaxWidth().padding(8.dp), + ) { + CircularProgressIndicator() + } + } } } + } } } } } @Composable -private fun NotificationCard(notification: Notification) { +private fun NotificationCard( + notification: Notification, + onPostClick: ((Status) -> Unit)? = null, +) { Card( - onClick = { }, + onClick = { + notification.status?.let { status -> onPostClick?.invoke(status) } + }, modifier = Modifier.fillMaxWidth(), ) { Column(modifier = Modifier.padding(4.dp)) { diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsViewModel.kt b/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsViewModel.kt index 812226d..e6e1e2f 100644 --- a/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsViewModel.kt +++ b/android/wear/src/main/java/place/coho/app/wear/ui/notifications/NotificationsViewModel.kt @@ -11,7 +11,11 @@ import place.coho.app.wear.sync.AuthState sealed interface NotificationsUiState { data object Loading : NotificationsUiState - data class Success(val notifications: List) : NotificationsUiState + data class Success( + val notifications: List, + val isLoadingMore: Boolean = false, + val canLoadMore: Boolean = true, + ) : NotificationsUiState data class Error(val message: String) : NotificationsUiState } @@ -22,7 +26,13 @@ class NotificationsViewModel( private val _uiState = MutableStateFlow(NotificationsUiState.Loading) val uiState: StateFlow = _uiState + private val _isRefreshing = MutableStateFlow(false) + val isRefreshing: StateFlow = _isRefreshing + + private var currentAuth: AuthState? = null + fun loadNotifications(auth: AuthState) { + currentAuth = auth viewModelScope.launch { _uiState.value = NotificationsUiState.Loading try { @@ -35,4 +45,43 @@ class NotificationsViewModel( } } } + + fun refresh() { + val auth = currentAuth ?: return + viewModelScope.launch { + _isRefreshing.value = true + try { + val notifications = repository.getNotifications(auth) + _uiState.value = NotificationsUiState.Success(notifications) + } catch (_: Exception) { + // Keep existing content on refresh failure + } finally { + _isRefreshing.value = false + } + } + } + + fun loadMore() { + val auth = currentAuth ?: return + val currentState = _uiState.value as? NotificationsUiState.Success ?: return + if (currentState.isLoadingMore || !currentState.canLoadMore) return + val lastId = currentState.notifications.lastOrNull()?.id ?: return + + _uiState.value = currentState.copy(isLoadingMore = true) + + viewModelScope.launch { + try { + val olderNotifications = repository.getNotifications(auth, maxId = lastId) + val current = (_uiState.value as? NotificationsUiState.Success) ?: return@launch + _uiState.value = current.copy( + notifications = current.notifications + olderNotifications, + isLoadingMore = false, + canLoadMore = olderNotifications.isNotEmpty(), + ) + } catch (_: Exception) { + val current = (_uiState.value as? NotificationsUiState.Success) ?: return@launch + _uiState.value = current.copy(isLoadingMore = false) + } + } + } } diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostCard.kt b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostCard.kt index 12a8384..3482db5 100644 --- a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostCard.kt +++ b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostCard.kt @@ -14,6 +14,8 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.hapticfeedback.HapticFeedbackType +import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp @@ -181,8 +183,12 @@ private fun ActionChip( count: Int, onClick: () -> Unit, ) { + val haptic = LocalHapticFeedback.current androidx.wear.compose.material3.TextButton( - onClick = onClick, + onClick = { + haptic.performHapticFeedback(HapticFeedbackType.Confirm) + onClick() + }, ) { Text( text = "$label $count", diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostDetailScreen.kt b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostDetailScreen.kt index 04b5764..8465aa2 100644 --- a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostDetailScreen.kt +++ b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostDetailScreen.kt @@ -22,6 +22,10 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.ui.hapticfeedback.HapticFeedbackType +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.platform.LocalHapticFeedback import androidx.wear.compose.foundation.lazy.ScalingLazyColumn import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState import androidx.wear.compose.material3.Card @@ -42,6 +46,13 @@ fun PostDetailScreen( val displayStatus = status.reblog ?: status val isBoosted = status.reblog != null val listState = rememberScalingLazyListState() + val config = LocalConfiguration.current + val horizontalPadding = (config.screenWidthDp * 0.052f).dp + val verticalPadding = if (config.isScreenRound) (config.screenHeightDp * 0.22f).dp else 24.dp + val columnPadding = PaddingValues( + horizontal = horizontalPadding, + vertical = verticalPadding, + ) ScreenScaffold( scrollState = listState, @@ -49,6 +60,7 @@ fun PostDetailScreen( ScalingLazyColumn( state = listState, verticalArrangement = Arrangement.spacedBy(4.dp), + contentPadding = columnPadding, modifier = Modifier.fillMaxSize(), ) { // Boost indicator @@ -60,7 +72,6 @@ fun PostDetailScreen( color = MaterialTheme.colorScheme.onSurfaceVariant, maxLines = 1, overflow = TextOverflow.Ellipsis, - modifier = Modifier.padding(horizontal = 8.dp), ) } } @@ -70,8 +81,7 @@ fun PostDetailScreen( Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp), + .fillMaxWidth(), ) { AsyncImage( model = displayStatus.account.avatar, @@ -109,7 +119,6 @@ fun PostDetailScreen( text = "⚠\uFE0F ${displayStatus.spoilerText}", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.error, - modifier = Modifier.padding(horizontal = 8.dp), ) } } @@ -120,7 +129,6 @@ fun PostDetailScreen( text = htmlToPlainText(displayStatus.content), style = MaterialTheme.typography.bodySmall, lineHeight = 18.sp, - modifier = Modifier.padding(horizontal = 8.dp), ) } @@ -134,8 +142,7 @@ fun PostDetailScreen( Card( onClick = { }, modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp), + .fillMaxWidth(), ) { AsyncImage( model = imageUrl, @@ -152,7 +159,6 @@ fun PostDetailScreen( text = "\uD83C\uDFA5 ${attachment.type} attachment", style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(horizontal = 8.dp), ) } } @@ -164,7 +170,6 @@ fun PostDetailScreen( text = relativeTime(displayStatus.createdAt), style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(horizontal = 8.dp), ) } @@ -174,8 +179,7 @@ fun PostDetailScreen( horizontalArrangement = Arrangement.SpaceEvenly, verticalAlignment = Alignment.CenterVertically, modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp), + .fillMaxWidth(), ) { if (onFavourite != null) { ActionChip( @@ -223,8 +227,12 @@ private fun ActionChip( count: Int, onClick: () -> Unit, ) { + val haptic = LocalHapticFeedback.current androidx.wear.compose.material3.TextButton( - onClick = onClick, + onClick = { + haptic.performHapticFeedback(HapticFeedbackType.Confirm) + onClick() + }, ) { Text( text = "$label $count", diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineScreen.kt b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineScreen.kt index 10ca751..cd8a79c 100644 --- a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineScreen.kt +++ b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineScreen.kt @@ -5,20 +5,30 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.pulltorefresh.PullToRefreshBox +import androidx.compose.ui.platform.LocalConfiguration import androidx.lifecycle.viewmodel.compose.viewModel import androidx.wear.compose.foundation.lazy.ScalingLazyColumn import androidx.wear.compose.foundation.lazy.items import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState +import androidx.wear.compose.material3.Button import androidx.wear.compose.material3.CircularProgressIndicator +import androidx.wear.compose.material3.Icon import androidx.wear.compose.material3.ListHeader import androidx.wear.compose.material3.MaterialTheme import androidx.wear.compose.material3.ScreenScaffold @@ -28,14 +38,17 @@ import place.coho.app.wear.R import place.coho.app.wear.api.models.Status import place.coho.app.wear.sync.AuthState +@OptIn(ExperimentalMaterial3Api::class) @Composable fun TimelineScreen( auth: AuthState?, onNavigateToNotifications: (() -> Unit)? = null, onPostClick: ((Status) -> Unit)? = null, + onCompose: (() -> Unit)? = null, viewModel: TimelineViewModel = viewModel(), ) { val uiState by viewModel.uiState.collectAsState() + val isRefreshing by viewModel.isRefreshing.collectAsState() LaunchedEffect(auth) { viewModel.loadTimeline(auth) @@ -66,13 +79,40 @@ fun TimelineScreen( is TimelineUiState.Success -> { val listState = rememberScalingLazyListState() + val config = LocalConfiguration.current + val horizontalPadding = (config.screenWidthDp * 0.052f).dp + val verticalPadding = if (config.isScreenRound) (config.screenHeightDp * 0.22f).dp else 24.dp + val columnPadding = PaddingValues( + horizontal = horizontalPadding, + vertical = verticalPadding, + ) + + // Trigger load-more when near the end of the list + val shouldLoadMore by remember { + derivedStateOf { + val lastVisibleIndex = listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0 + val totalItems = listState.layoutInfo.totalItemsCount + lastVisibleIndex >= totalItems - 3 && totalItems > 0 + } + } + LaunchedEffect(shouldLoadMore) { + if (shouldLoadMore && state.canLoadMore && !state.isLoadingMore) { + viewModel.loadMore() + } + } ScreenScaffold( scrollState = listState, ) { + PullToRefreshBox( + isRefreshing = isRefreshing, + onRefresh = { viewModel.refresh() }, + modifier = Modifier.fillMaxSize(), + ) { ScalingLazyColumn( state = listState, verticalArrangement = Arrangement.spacedBy(4.dp), + contentPadding = columnPadding, modifier = Modifier.fillMaxSize(), ) { item { @@ -86,6 +126,33 @@ fun TimelineScreen( } } + // New post button (authenticated only) + if (onCompose != null) { + item { + Button( + onClick = onCompose, + modifier = Modifier.fillMaxWidth(), + icon = { + Icon( + painter = painterResource(R.drawable.ic_add), + contentDescription = null, + modifier = Modifier.size(20.dp), + ) + }, + label = { Text(stringResource(R.string.voice_compose)) }, + ) + } + } + + // Spacer between button and posts + if (onCompose != null) { + item { + androidx.compose.foundation.layout.Spacer( + modifier = Modifier.padding(bottom = 4.dp), + ) + } + } + items(state.posts, key = { it.id }) { status -> PostCard( status = status, @@ -99,6 +166,18 @@ fun TimelineScreen( ) } + // Loading more indicator + if (state.isLoadingMore) { + item { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.fillMaxWidth().padding(8.dp), + ) { + CircularProgressIndicator() + } + } + } + // Navigate to notifications (authenticated only) if (onNavigateToNotifications != null) { item { @@ -110,15 +189,6 @@ fun TimelineScreen( } } } - - // Refresh button at the bottom - item { - TextButton( - onClick = { viewModel.refresh() }, - modifier = Modifier.fillMaxWidth(), - ) { - Text("Refresh") - } } } } diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineViewModel.kt b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineViewModel.kt index bc727b6..d43f7b8 100644 --- a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineViewModel.kt +++ b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineViewModel.kt @@ -11,7 +11,11 @@ import place.coho.app.wear.sync.AuthState sealed interface TimelineUiState { data object Loading : TimelineUiState - data class Success(val posts: List) : TimelineUiState + data class Success( + val posts: List, + val isLoadingMore: Boolean = false, + val canLoadMore: Boolean = true, + ) : TimelineUiState data class Error(val message: String) : TimelineUiState } @@ -22,6 +26,9 @@ class TimelineViewModel( private val _uiState = MutableStateFlow(TimelineUiState.Loading) val uiState: StateFlow = _uiState + private val _isRefreshing = MutableStateFlow(false) + val isRefreshing: StateFlow = _isRefreshing + private var currentAuth: AuthState? = null val isAuthenticated: Boolean get() = currentAuth?.isAuthenticated == true @@ -45,7 +52,50 @@ class TimelineViewModel( } fun refresh() { - loadTimeline(currentAuth) + val auth = currentAuth + viewModelScope.launch { + _isRefreshing.value = true + try { + val posts = if (auth != null && auth.isAuthenticated) { + repository.getHomeTimeline(auth) + } else { + repository.getPublicTimeline() + } + _uiState.value = TimelineUiState.Success(posts) + } catch (_: Exception) { + // Keep existing content on refresh failure + } finally { + _isRefreshing.value = false + } + } + } + + fun loadMore() { + val auth = currentAuth + val currentState = _uiState.value as? TimelineUiState.Success ?: return + if (currentState.isLoadingMore || !currentState.canLoadMore) return + val lastId = currentState.posts.lastOrNull()?.id ?: return + + _uiState.value = currentState.copy(isLoadingMore = true) + + viewModelScope.launch { + try { + val olderPosts = if (auth != null && auth.isAuthenticated) { + repository.getHomeTimeline(auth, maxId = lastId) + } else { + emptyList() + } + val current = (_uiState.value as? TimelineUiState.Success) ?: return@launch + _uiState.value = current.copy( + posts = current.posts + olderPosts, + isLoadingMore = false, + canLoadMore = olderPosts.isNotEmpty(), + ) + } catch (_: Exception) { + val current = (_uiState.value as? TimelineUiState.Success) ?: return@launch + _uiState.value = current.copy(isLoadingMore = false) + } + } } fun toggleFavourite(statusId: String) { diff --git a/android/wear/src/main/res/drawable/ic_add.xml b/android/wear/src/main/res/drawable/ic_add.xml new file mode 100644 index 0000000..357eec7 --- /dev/null +++ b/android/wear/src/main/res/drawable/ic_add.xml @@ -0,0 +1,9 @@ + + + diff --git a/android/wear/src/main/res/drawable/ic_mic.xml b/android/wear/src/main/res/drawable/ic_mic.xml new file mode 100644 index 0000000..0211736 --- /dev/null +++ b/android/wear/src/main/res/drawable/ic_mic.xml @@ -0,0 +1,9 @@ + + + diff --git a/android/wear/src/main/res/values/strings.xml b/android/wear/src/main/res/values/strings.xml index 3b6a120..a4b33a0 100644 --- a/android/wear/src/main/res/values/strings.xml +++ b/android/wear/src/main/res/values/strings.xml @@ -22,4 +22,12 @@ %dm ago %dh ago %dd ago + Compose + What\'s on your mind? + Try again + Post + Posting… + Failed to post + No speech detected. Tap to try again. + New post From b41126bceb21684102db6f82e8036b45bdfdb164 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Fri, 20 Mar 2026 21:38:29 -0700 Subject: [PATCH 21/26] reply, threads and settings for the watch app + a sync to watch button in the android app --- android/app/build.gradle | 4 +- android/wear/build.gradle | 4 +- .../place/coho/app/wear/api/MastodonApi.kt | 3 + .../coho/app/wear/data/TimelineRepository.kt | 4 + .../java/place/coho/app/wear/ui/WearApp.kt | 31 ++++++- .../coho/app/wear/ui/compose/ComposeScreen.kt | 18 +++- .../app/wear/ui/compose/ComposeViewModel.kt | 4 +- .../wear/ui/settings/WatchSettingsScreen.kt | 86 +++++++++++++++++++ .../app/wear/ui/timeline/PostDetailScreen.kt | 80 +++++++++++++++-- .../app/wear/ui/timeline/TimelineScreen.kt | 29 +++++++ android/wear/src/main/res/values/strings.xml | 8 +- src/app-index.ts | 33 +------ src/components/settings-drawer-content.ts | 78 ++++++++++++++++- src/generated/locales/de.ts | 8 ++ src/generated/locales/es.ts | 8 ++ src/services/wear-sync.ts | 30 +++++++ 16 files changed, 381 insertions(+), 47 deletions(-) create mode 100644 android/wear/src/main/java/place/coho/app/wear/ui/settings/WatchSettingsScreen.kt create mode 100644 src/services/wear-sync.ts diff --git a/android/app/build.gradle b/android/app/build.gradle index 4070504..c2889e9 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "place.coho.app" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 3 - versionName "1.2" + versionCode 6 + versionName "4.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/android/wear/build.gradle b/android/wear/build.gradle index 253cf97..ec50b35 100644 --- a/android/wear/build.gradle +++ b/android/wear/build.gradle @@ -10,8 +10,8 @@ android { applicationId "place.coho.app" minSdkVersion 30 // Wear OS 3+ targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 1 - versionName "1.0" + versionCode 7 + versionName "5.0" } buildTypes { diff --git a/android/wear/src/main/java/place/coho/app/wear/api/MastodonApi.kt b/android/wear/src/main/java/place/coho/app/wear/api/MastodonApi.kt index e442c37..5c9996b 100644 --- a/android/wear/src/main/java/place/coho/app/wear/api/MastodonApi.kt +++ b/android/wear/src/main/java/place/coho/app/wear/api/MastodonApi.kt @@ -34,6 +34,9 @@ interface MastodonApi { @Query("limit") limit: Int = 12, ): List + @GET("api/v1/statuses/{id}") + suspend fun getStatus(@Path("id") id: String): Status + @GET("api/v1/notifications") suspend fun getNotifications( @Query("limit") limit: Int = 20, diff --git a/android/wear/src/main/java/place/coho/app/wear/data/TimelineRepository.kt b/android/wear/src/main/java/place/coho/app/wear/data/TimelineRepository.kt index e937ecd..ab04f93 100644 --- a/android/wear/src/main/java/place/coho/app/wear/data/TimelineRepository.kt +++ b/android/wear/src/main/java/place/coho/app/wear/data/TimelineRepository.kt @@ -36,6 +36,10 @@ class TimelineRepository { return getPublicApi().getTrendingStatuses(limit = 12) } + suspend fun getStatus(auth: AuthState, id: String): Status { + return getApi(auth).getStatus(id) + } + suspend fun favouriteStatus(auth: AuthState, id: String): Status { return getApi(auth).favouriteStatus(id) } diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/WearApp.kt b/android/wear/src/main/java/place/coho/app/wear/ui/WearApp.kt index a9056f3..cef51ff 100644 --- a/android/wear/src/main/java/place/coho/app/wear/ui/WearApp.kt +++ b/android/wear/src/main/java/place/coho/app/wear/ui/WearApp.kt @@ -33,6 +33,7 @@ import place.coho.app.wear.sync.AuthRepository import place.coho.app.wear.sync.AuthState import place.coho.app.wear.ui.compose.ComposeScreen import place.coho.app.wear.ui.notifications.NotificationsScreen +import place.coho.app.wear.ui.settings.WatchSettingsScreen import place.coho.app.wear.ui.theme.CohoWearTheme import place.coho.app.wear.ui.timeline.PostDetailScreen import place.coho.app.wear.ui.timeline.TimelineScreen @@ -47,6 +48,8 @@ fun WearApp(authRepository: AuthRepository) { CohoWearTheme { val navController = rememberSwipeDismissableNavController() var selectedStatus by remember { mutableStateOf(null) } + var replyToId by remember { mutableStateOf(null) } + var replyToAuthor by remember { mutableStateOf(null) } val timelineViewModel: TimelineViewModel = viewModel() AppScaffold { @@ -56,7 +59,7 @@ fun WearApp(authRepository: AuthRepository) { ) { composable("home") { if (authState.isAuthenticated) { - val pagerState = rememberPagerState(pageCount = { 2 }) + val pagerState = rememberPagerState(pageCount = { 3 }) val coroutineScope = rememberCoroutineScope() Box(modifier = Modifier.fillMaxSize()) { @@ -77,6 +80,8 @@ fun WearApp(authRepository: AuthRepository) { navController.navigate("postDetail") }, onCompose = { + replyToId = null + replyToAuthor = null navController.navigate("compose") }, viewModel = timelineViewModel, @@ -88,11 +93,15 @@ fun WearApp(authRepository: AuthRepository) { navController.navigate("postDetail") }, ) + 2 -> WatchSettingsScreen( + authRepository = authRepository, + onLoggedOut = {}, + ) } } PageIndicator( - pageCount = 2, + pageCount = 3, currentPage = pagerState.currentPage, modifier = Modifier .align(Alignment.BottomCenter) @@ -117,12 +126,20 @@ fun WearApp(authRepository: AuthRepository) { if (status != null) { PostDetailScreen( status = status, + auth = if (timelineViewModel.isAuthenticated) authState else null, onFavourite = if (timelineViewModel.isAuthenticated) { { timelineViewModel.toggleFavourite(it) } } else null, onBoost = if (timelineViewModel.isAuthenticated) { { timelineViewModel.toggleBoost(it) } } else null, + onReply = if (timelineViewModel.isAuthenticated) { + { id, author -> + replyToId = id + replyToAuthor = author + navController.navigate("compose") + } + } else null, ) } } @@ -130,8 +147,16 @@ fun WearApp(authRepository: AuthRepository) { composable("compose") { ComposeScreen( auth = authState, - onDismiss = { navController.popBackStack() }, + replyToId = replyToId, + replyToAuthor = replyToAuthor, + onDismiss = { + replyToId = null + replyToAuthor = null + navController.popBackStack() + }, onPosted = { + replyToId = null + replyToAuthor = null navController.popBackStack() timelineViewModel.refresh() }, diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeScreen.kt b/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeScreen.kt index e40ffd6..2e0f6ab 100644 --- a/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeScreen.kt +++ b/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeScreen.kt @@ -40,6 +40,8 @@ import place.coho.app.wear.sync.AuthState @Composable fun ComposeScreen( auth: AuthState, + replyToId: String? = null, + replyToAuthor: String? = null, onDismiss: () -> Unit, onPosted: () -> Unit, viewModel: ComposeViewModel = viewModel(), @@ -117,6 +119,20 @@ fun ComposeScreen( } } + // Reply context + if (replyToAuthor != null) { + item { + Text( + text = stringResource(R.string.replying_to, "@$replyToAuthor"), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.primary, + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 4.dp), + ) + } + } + // Voice text display item { Text( @@ -163,7 +179,7 @@ fun ComposeScreen( item { FilledTonalButton( - onClick = { viewModel.postStatus(auth, voiceText) }, + onClick = { viewModel.postStatus(auth, voiceText, inReplyToId = replyToId) }, modifier = Modifier.fillMaxWidth(), ) { Text(stringResource(R.string.compose_post)) diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeViewModel.kt b/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeViewModel.kt index 184fcf8..345d3e8 100644 --- a/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeViewModel.kt +++ b/android/wear/src/main/java/place/coho/app/wear/ui/compose/ComposeViewModel.kt @@ -22,12 +22,12 @@ class ComposeViewModel( private val _uiState = MutableStateFlow(ComposeUiState.Idle) val uiState: StateFlow = _uiState - fun postStatus(auth: AuthState, text: String, visibility: String = "public") { + fun postStatus(auth: AuthState, text: String, visibility: String = "public", inReplyToId: String? = null) { if (text.isBlank()) return viewModelScope.launch { _uiState.value = ComposeUiState.Sending try { - repository.postStatus(auth, text, visibility) + repository.postStatus(auth, text, visibility, inReplyToId) _uiState.value = ComposeUiState.Sent } catch (e: Exception) { _uiState.value = ComposeUiState.Error( diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/settings/WatchSettingsScreen.kt b/android/wear/src/main/java/place/coho/app/wear/ui/settings/WatchSettingsScreen.kt new file mode 100644 index 0000000..b755956 --- /dev/null +++ b/android/wear/src/main/java/place/coho/app/wear/ui/settings/WatchSettingsScreen.kt @@ -0,0 +1,86 @@ +package place.coho.app.wear.ui.settings + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.wear.compose.foundation.lazy.ScalingLazyColumn +import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState +import androidx.wear.compose.material3.FilledTonalButton +import androidx.wear.compose.material3.ListHeader +import androidx.wear.compose.material3.MaterialTheme +import androidx.wear.compose.material3.ScreenScaffold +import androidx.wear.compose.material3.Text +import kotlinx.coroutines.launch +import place.coho.app.wear.R +import place.coho.app.wear.sync.AuthRepository + +@Composable +fun WatchSettingsScreen( + authRepository: AuthRepository, + onLoggedOut: () -> Unit, +) { + val listState = rememberScalingLazyListState() + val config = LocalConfiguration.current + val horizontalPadding = (config.screenWidthDp * 0.052f).dp + val verticalPadding = if (config.isScreenRound) (config.screenHeightDp * 0.22f).dp else 24.dp + val columnPadding = PaddingValues( + horizontal = horizontalPadding, + vertical = verticalPadding, + ) + val scope = rememberCoroutineScope() + var confirmingLogout by remember { mutableStateOf(false) } + + ScreenScaffold( + scrollState = listState, + ) { + ScalingLazyColumn( + state = listState, + verticalArrangement = Arrangement.spacedBy(4.dp), + contentPadding = columnPadding, + modifier = Modifier.fillMaxSize(), + ) { + item { + ListHeader { + Text(stringResource(R.string.settings_title)) + } + } + + item { + if (confirmingLogout) { + FilledTonalButton( + onClick = { + scope.launch { + authRepository.clear() + onLoggedOut() + } + }, + modifier = Modifier.fillMaxWidth(), + ) { + Text( + text = stringResource(R.string.logout_confirm), + color = MaterialTheme.colorScheme.error, + ) + } + } else { + FilledTonalButton( + onClick = { confirmingLogout = true }, + modifier = Modifier.fillMaxWidth(), + ) { + Text(stringResource(R.string.logout_button)) + } + } + } + } + } +} diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostDetailScreen.kt b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostDetailScreen.kt index 8465aa2..ef49a0b 100644 --- a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostDetailScreen.kt +++ b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/PostDetailScreen.kt @@ -14,6 +14,11 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -33,19 +38,39 @@ import androidx.wear.compose.material3.MaterialTheme import androidx.wear.compose.material3.ScreenScaffold import androidx.wear.compose.material3.Text import coil.compose.AsyncImage +import place.coho.app.wear.R import place.coho.app.wear.api.models.Status +import place.coho.app.wear.data.TimelineRepository +import place.coho.app.wear.sync.AuthState import place.coho.app.wear.ui.components.htmlToPlainText import place.coho.app.wear.ui.components.relativeTime +import androidx.compose.ui.res.stringResource @Composable fun PostDetailScreen( status: Status, + auth: AuthState? = null, onFavourite: ((String) -> Unit)?, onBoost: ((String) -> Unit)?, + onReply: ((String, String) -> Unit)? = null, ) { val displayStatus = status.reblog ?: status val isBoosted = status.reblog != null val listState = rememberScalingLazyListState() + + // Fetch parent post if this is a reply + var parentStatus by remember { mutableStateOf(null) } + if (displayStatus.inReplyToId != null && auth != null) { + LaunchedEffect(displayStatus.inReplyToId) { + try { + val repo = TimelineRepository() + parentStatus = repo.getStatus(auth, displayStatus.inReplyToId) + } catch (_: Exception) { + // Parent fetch is best-effort + } + } + } + val config = LocalConfiguration.current val horizontalPadding = (config.screenWidthDp * 0.052f).dp val verticalPadding = if (config.isScreenRound) (config.screenHeightDp * 0.22f).dp else 24.dp @@ -63,6 +88,36 @@ fun PostDetailScreen( contentPadding = columnPadding, modifier = Modifier.fillMaxSize(), ) { + // Parent post context (if this is a reply) + val parent = parentStatus + if (parent != null) { + item { + Card( + onClick = {}, + modifier = Modifier.fillMaxWidth(), + ) { + Column(modifier = Modifier.padding(4.dp)) { + Text( + text = stringResource( + R.string.in_reply_to, + parent.account.displayName.ifBlank { parent.account.username }, + ), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.primary, + ) + Spacer(modifier = Modifier.height(2.dp)) + Text( + text = htmlToPlainText(parent.content), + style = MaterialTheme.typography.bodySmall, + maxLines = 3, + overflow = TextOverflow.Ellipsis, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + } + } + } + // Boost indicator if (isBoosted) { item { @@ -209,12 +264,25 @@ fun PostDetailScreen( ) } - Text( - text = "\uD83D\uDCAC ${displayStatus.repliesCount}", - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(vertical = 8.dp), - ) + if (onReply != null) { + ActionChip( + label = "💬", + count = displayStatus.repliesCount, + onClick = { + onReply( + displayStatus.id, + displayStatus.account.acct, + ) + }, + ) + } else { + Text( + text = "💬 ${displayStatus.repliesCount}", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(vertical = 8.dp), + ) + } } } } diff --git a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineScreen.kt b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineScreen.kt index cd8a79c..d25dd5a 100644 --- a/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineScreen.kt +++ b/android/wear/src/main/java/place/coho/app/wear/ui/timeline/TimelineScreen.kt @@ -27,6 +27,7 @@ import androidx.wear.compose.foundation.lazy.ScalingLazyColumn import androidx.wear.compose.foundation.lazy.items import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState import androidx.wear.compose.material3.Button +import androidx.wear.compose.material3.Card import androidx.wear.compose.material3.CircularProgressIndicator import androidx.wear.compose.material3.Icon import androidx.wear.compose.material3.ListHeader @@ -37,6 +38,10 @@ import androidx.wear.compose.material3.TextButton import place.coho.app.wear.R import place.coho.app.wear.api.models.Status import place.coho.app.wear.sync.AuthState +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.ui.text.font.FontWeight @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -126,6 +131,30 @@ fun TimelineScreen( } } + // Sync prompt (unauthenticated only) + if (auth?.isAuthenticated != true) { + item { + Card( + onClick = {}, + modifier = Modifier.fillMaxWidth(), + ) { + Column(modifier = Modifier.padding(4.dp)) { + Text( + text = stringResource(R.string.sync_prompt_title), + style = MaterialTheme.typography.titleSmall, + fontWeight = FontWeight.Bold, + ) + Spacer(modifier = Modifier.height(4.dp)) + Text( + text = stringResource(R.string.error_not_authenticated), + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + } + } + } + // New post button (authenticated only) if (onCompose != null) { item { diff --git a/android/wear/src/main/res/values/strings.xml b/android/wear/src/main/res/values/strings.xml index a4b33a0..038028c 100644 --- a/android/wear/src/main/res/values/strings.xml +++ b/android/wear/src/main/res/values/strings.xml @@ -6,7 +6,8 @@ Notifications Loading… Can\'t connect. Check your watch\'s internet. - Open Coho on your phone to connect. + Open Coho on your phone and tap \"Sync to Watch\" in Settings. + Connect your account Pull to refresh Favorite Boost @@ -30,4 +31,9 @@ Failed to post No speech detected. Tap to try again. New post + Settings + Log out + Tap again to log out + Replying to %s + In reply to %s diff --git a/src/app-index.ts b/src/app-index.ts index 847e7fc..ffebe05 100644 --- a/src/app-index.ts +++ b/src/app-index.ts @@ -314,8 +314,10 @@ export class AppIndex extends LitElement { // Sync server URL to native SharedPreferences for the Android widget this.syncServerToNativeWidget(); - // Sync credentials to paired Wear OS watch - this.syncCredentialsToWearOS(); + // Keep watch in sync automatically (best-effort, non-blocking) + import('./services/wear-sync.js') + .then((m) => m.syncCredentialsToWearOS()) + .catch(() => {}); } /** @@ -337,33 +339,6 @@ export class AppIndex extends LitElement { } } - /** - * Pushes auth credentials to the paired Wear OS watch via the - * WearSyncBridge Capacitor plugin so the watch can independently - * call the Mastodon API. - */ - private async syncCredentialsToWearOS() { - try { - const { isNativePlatform } = await import('./utils/platform.js'); - if (!isNativePlatform()) return; - - const { registerPlugin } = await import('@capacitor/core'); - const WearSyncBridge = registerPlugin('WearSyncBridge'); - const server = localStorage.getItem('server') || ''; - const accessToken = localStorage.getItem('accessToken') || ''; - const acct = localStorage.getItem('acct') || ''; - if (!server || !accessToken) return; - - await (WearSyncBridge as any).syncCredentials({ - server, - accessToken, - acct, - }); - } catch { - // Wear sync bridge not available — ignore - } - } - /** * Check if the user has valid authentication credentials * Sets isAuthenticated to true for returning users, false for new users diff --git a/src/components/settings-drawer-content.ts b/src/components/settings-drawer-content.ts index 44080ca..c61d949 100644 --- a/src/components/settings-drawer-content.ts +++ b/src/components/settings-drawer-content.ts @@ -1,5 +1,5 @@ import { LitElement, html, css, nothing } from 'lit'; -import { customElement, property } from 'lit/decorators.js'; +import { customElement, property, state } from 'lit/decorators.js'; import { msg, str } from '@lit/localize'; import { localized } from '@lit/localize'; @@ -14,8 +14,11 @@ import './md/md-menu-item'; import './md/md-button'; import './md/md-card'; import './md/md-divider'; +import './md/md-toast'; import './account-settings'; +import type { MdToast } from './md/md-toast'; + import type { Account } from '../mastodon/types/account'; import type { Instance } from '../mastodon/types/instance'; import { router } from '../router/routes'; @@ -36,6 +39,10 @@ export class SettingsDrawerContent extends LitElement { @property({ type: Boolean }) userTermsLoaded = false; @property({ type: Boolean }) appThemeLoaded = false; + @state() private isAndroid = false; + @state() private syncingToWatch = false; + @state() private syncedToWatch = false; + static styles = css` :host { display: block; @@ -166,6 +173,49 @@ export class SettingsDrawerContent extends LitElement { } `; + connectedCallback() { + super.connectedCallback(); + this.detectPlatform(); + } + + private async detectPlatform() { + try { + const { getPlatform } = await import('../utils/platform.js'); + this.isAndroid = getPlatform() === 'android'; + } catch { + this.isAndroid = false; + } + } + + private async syncToWatch() { + this.syncingToWatch = true; + try { + const { syncCredentialsToWearOS } = + await import('../services/wear-sync.js'); + const success = await syncCredentialsToWearOS(); + if (success) { + this.syncedToWatch = true; + } + this.showSyncToast( + success ? msg('Synced to watch') : msg('No credentials to sync'), + success ? 'success' : 'error' + ); + } catch { + this.showSyncToast(msg('Failed to sync to watch'), 'error'); + } finally { + this.syncingToWatch = false; + } + } + + private showSyncToast(message: string, type: 'success' | 'error') { + const toast = this.shadowRoot?.querySelector('md-toast'); + if (toast) { + toast.setAttribute('message', message); + toast.setAttribute('type', type); + toast.show(); + } + } + private goToFollowers() { if (!this.user) return; router.navigate(`/followers?id=${this.user.id}`); @@ -367,8 +417,34 @@ export class SettingsDrawerContent extends LitElement {

    ${msg('Data Saver Mode reduces the amount of data used by Coho.')}

    + + ${this.isAndroid + ? html` + + +
    +

    ${msg('Sync to Watch')}

    + + ${this.syncedToWatch + ? msg('Synced ✓') + : this.syncingToWatch + ? msg('Syncing…') + : msg('Sync')} + +
    +

    + ${msg('Send your account credentials to your Wear OS watch.')} +

    + ` + : nothing} + + diff --git a/src/generated/locales/de.ts b/src/generated/locales/de.ts index ed593a4..1603338 100644 --- a/src/generated/locales/de.ts +++ b/src/generated/locales/de.ts @@ -318,7 +318,15 @@ export const templates = { s70dbcf49cc261e8e: `Default Post Language`, s64a08ea7e5de1afa: `Account & Privacy`, sef8b008b85e8d725: `Posting Defaults`, + s288fdb61a9ecaffb: `Synced to watch`, + s804676468ea1af74: `No credentials to sync`, + sfa39c2b9c0dd0c02: `Failed to sync to watch`, s2b5047d39b9baf3d: `Preferences`, + s5ddb4ae6884197c4: `Sync to Watch`, + s36c13bb456523146: `Synced ✓`, + s9cd4984f1a746b40: `Syncing…`, + s05073d2537b45d1a: `Sync`, + s0c61be2ad8538497: `Send your account credentials to your Wear OS watch.`, saab875d8cfcfe712: `Theme`, s0d29a53a04e80406: `Content & Safety`, s3d8f0d63cd31d3c9: `Content Filters`, diff --git a/src/generated/locales/es.ts b/src/generated/locales/es.ts index 3462ebf..5d6f4c7 100644 --- a/src/generated/locales/es.ts +++ b/src/generated/locales/es.ts @@ -318,7 +318,15 @@ export const templates = { s70dbcf49cc261e8e: `Default Post Language`, s64a08ea7e5de1afa: `Account & Privacy`, sef8b008b85e8d725: `Posting Defaults`, + s288fdb61a9ecaffb: `Synced to watch`, + s804676468ea1af74: `No credentials to sync`, + sfa39c2b9c0dd0c02: `Failed to sync to watch`, s2b5047d39b9baf3d: `Preferences`, + s5ddb4ae6884197c4: `Sync to Watch`, + s36c13bb456523146: `Synced ✓`, + s9cd4984f1a746b40: `Syncing…`, + s05073d2537b45d1a: `Sync`, + s0c61be2ad8538497: `Send your account credentials to your Wear OS watch.`, saab875d8cfcfe712: `Theme`, s0d29a53a04e80406: `Content & Safety`, s3d8f0d63cd31d3c9: `Content Filters`, diff --git a/src/services/wear-sync.ts b/src/services/wear-sync.ts new file mode 100644 index 0000000..56d3ace --- /dev/null +++ b/src/services/wear-sync.ts @@ -0,0 +1,30 @@ +/** + * Pushes auth credentials to a paired Wear OS watch via the + * WearSyncBridge Capacitor plugin so the watch can independently + * call the Mastodon API. + * + * Returns true if sync succeeded, false otherwise. + */ +export async function syncCredentialsToWearOS(): Promise { + try { + const { isNativePlatform } = await import('../utils/platform.js'); + if (!isNativePlatform()) return false; + + const { registerPlugin } = await import('@capacitor/core'); + const WearSyncBridge = registerPlugin('WearSyncBridge'); + const server = localStorage.getItem('server') || ''; + const accessToken = localStorage.getItem('accessToken') || ''; + const acct = localStorage.getItem('acct') || ''; + if (!server || !accessToken) return false; + + await (WearSyncBridge as any).syncCredentials({ + server, + accessToken, + acct, + }); + return true; + } catch { + // Wear sync bridge not available + return false; + } +} From 57c7158a13b3751af242a9a3644d32e65f7b5981 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Fri, 20 Mar 2026 21:56:12 -0700 Subject: [PATCH 22/26] fix alt text generation on Android --- src/components/image-preview-dialog.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/image-preview-dialog.ts b/src/components/image-preview-dialog.ts index 56f5a42..92e6e0a 100644 --- a/src/components/image-preview-dialog.ts +++ b/src/components/image-preview-dialog.ts @@ -248,9 +248,9 @@ export class ImagePreviewDialog extends LitElement { await new Promise((resolve) => requestAnimationFrame(resolve)); this.updatePlaceholderSize(); - // Lazy load AI service to keep it out of main bundle - const { isPromptAPIAvailable } = await import('../services/ai'); - if (isPromptAPIAvailable() && (!this.alt || this.alt.trim() === '')) { + // Always attempt alt text generation when missing — generateAltText has + // its own fallback chain: native Android → Chrome Prompt API → cloud function + if (!this.alt || this.alt.trim() === '') { this.alt = 'Loading alt text...'; this.handleGenerateAlt(); } From 03646965272efcbeb80a502621fd4303ef63265c Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Fri, 20 Mar 2026 21:56:44 -0700 Subject: [PATCH 23/26] localize --- xliff/de.xlf | 30 ++++++++++++++++++++++++++++++ xliff/es.xlf | 30 ++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/xliff/de.xlf b/xliff/de.xlf index e5fc1d1..b69c202 100644 --- a/xliff/de.xlf +++ b/xliff/de.xlf @@ -1898,6 +1898,36 @@ Current account avatar + + Synced to watch + + + No credentials to sync + + + Failed to sync to watch + + + Sync to Watch + + + Synced ✓ + + + Syncing… + + + Sync + + + Send your account credentials to your Wear OS watch. + + + Back to login + + + Signing in… + diff --git a/xliff/es.xlf b/xliff/es.xlf index e96658d..c63ca5e 100644 --- a/xliff/es.xlf +++ b/xliff/es.xlf @@ -1898,6 +1898,36 @@ Current account avatar + + Synced to watch + + + No credentials to sync + + + Failed to sync to watch + + + Sync to Watch + + + Synced ✓ + + + Syncing… + + + Sync + + + Send your account credentials to your Wear OS watch. + + + Back to login + + + Signing in… + From 84733b555196e4dc50c4a7e29ae798ffbc51241b Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Fri, 20 Mar 2026 22:20:06 -0700 Subject: [PATCH 24/26] improved haptics system --- package-lock.json | 10 +++ package.json | 1 + src/components/header.ts | 13 +-- src/components/post-composer.ts | 4 + src/components/settings-drawer-content.ts | 25 ++++++ src/components/timeline.ts | 4 +- src/components/user-profile.ts | 9 -- src/generated/locales/de.ts | 2 + src/generated/locales/es.ts | 2 + src/pages/app-home.ts | 23 +++-- src/pages/app-login.ts | 12 --- src/pages/app-profile.ts | 8 ++ src/services/settings.ts | 5 ++ src/utils/handle-vibrate.ts | 16 +--- src/utils/haptics.ts | 103 ++++++++++++++++++++++ src/utils/timeline-actions.ts | 4 + tests/services/settings.test.ts | 1 + 17 files changed, 188 insertions(+), 54 deletions(-) create mode 100644 src/utils/haptics.ts diff --git a/package-lock.json b/package-lock.json index 40d3c86..1f68eda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@capacitor/app": "^8.0.1", "@capacitor/browser": "^8.0.2", "@capacitor/core": "^8.2.0", + "@capacitor/haptics": "^8.0.1", "@capacitor/push-notifications": "^8.0.2", "@capacitor/share": "^8.0.1", "@huggingface/transformers": "^4.0.0-next.2", @@ -238,6 +239,15 @@ "tslib": "^2.1.0" } }, + "node_modules/@capacitor/haptics": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-8.0.1.tgz", + "integrity": "sha512-8v8rowLBMeb3CryqoQvXndwyUsoi4pPXf0qFw7IGA4D32Uk7+K6juN2SjRowqunoovkvvbFmU9TD7JIAz2zmFw==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=8.0.0" + } + }, "node_modules/@capacitor/push-notifications": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@capacitor/push-notifications/-/push-notifications-8.0.2.tgz", diff --git a/package.json b/package.json index c31d881..134ce4b 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@capacitor/app": "^8.0.1", "@capacitor/browser": "^8.0.2", "@capacitor/core": "^8.2.0", + "@capacitor/haptics": "^8.0.1", "@capacitor/push-notifications": "^8.0.2", "@capacitor/share": "^8.0.1", "@huggingface/transformers": "^4.0.0-next.2", diff --git a/src/components/header.ts b/src/components/header.ts index 7df62e4..61a502a 100644 --- a/src/components/header.ts +++ b/src/components/header.ts @@ -1,11 +1,10 @@ -import { LitElement, css, html, PropertyValueMap, nothing } from 'lit'; +import { LitElement, css, html, nothing } from 'lit'; import { property, customElement } from 'lit/decorators.js'; import { localized, msg } from '@lit/localize'; import './md/md-icon.js'; import './md/md-icon-button.js'; -import { enableVibrate } from '../utils/handle-vibrate'; import { setAuthRedirect } from '../utils/auth-redirect'; import type { @@ -158,16 +157,6 @@ export class AppHeader extends LitElement { `; } - protected firstUpdated( - _changedProperties: PropertyValueMap | Map - ): void { - window.requestIdleCallback(() => { - if (this.shadowRoot) { - enableVibrate(this.shadowRoot); - } - }); - } - openSettings() { // fire custom event this.dispatchEvent(new CustomEvent('open-settings') as OpenSettingsEvent); diff --git a/src/components/post-composer.ts b/src/components/post-composer.ts index 6d35f37..62df664 100644 --- a/src/components/post-composer.ts +++ b/src/components/post-composer.ts @@ -2318,6 +2318,10 @@ export class PostComposer extends LitElement { this.isPublishing = false; this.publishSuccess = true; + import('../utils/haptics').then(({ hapticNotification }) => + hapticNotification('success') + ); + // Brief success flash, then reset and dispatch setTimeout(() => { this.publishSuccess = false; diff --git a/src/components/settings-drawer-content.ts b/src/components/settings-drawer-content.ts index c61d949..97b4781 100644 --- a/src/components/settings-drawer-content.ts +++ b/src/components/settings-drawer-content.ts @@ -36,6 +36,7 @@ export class SettingsDrawerContent extends LitElement { @property({ type: Object }) instanceInfo: Instance | null = null; @property({ type: Boolean }) wellnessMode = false; @property({ type: Boolean }) dataSaverMode = false; + @property({ type: Boolean }) hapticsEnabled = true; @property({ type: Boolean }) userTermsLoaded = false; @property({ type: Boolean }) appThemeLoaded = false; @@ -307,6 +308,17 @@ export class SettingsDrawerContent extends LitElement { ); } + private handleHapticsToggle(e: Event) { + const checked = (e.target as HTMLInputElement).checked; + this.dispatchEvent( + new CustomEvent('haptics-change', { + detail: { checked }, + bubbles: true, + composed: true, + }) + ); + } + render() { return html`
    @@ -418,6 +430,19 @@ export class SettingsDrawerContent extends LitElement { ${msg('Data Saver Mode reduces the amount of data used by Coho.')}

    + + +
    +

    ${msg('Haptic Feedback')}

    + +
    +

    + ${msg('Vibrate on actions like likes, boosts, and publishing.')} +

    + ${this.isAndroid ? html` diff --git a/src/components/timeline.ts b/src/components/timeline.ts index 7324434..01044ce 100644 --- a/src/components/timeline.ts +++ b/src/components/timeline.ts @@ -905,7 +905,9 @@ export class Timeline extends LitElement { }); if (this._pullDistance >= this._threshold && !this._hapticTriggered) { - if (navigator.vibrate) navigator.vibrate(10); + import('../utils/haptics').then(({ hapticImpact }) => + hapticImpact('medium') + ); this._hapticTriggered = true; } else if (this._pullDistance < this._threshold) { this._hapticTriggered = false; diff --git a/src/components/user-profile.ts b/src/components/user-profile.ts index 6a51e61..e962157 100644 --- a/src/components/user-profile.ts +++ b/src/components/user-profile.ts @@ -94,15 +94,6 @@ export class UserProfile extends LitElement { `, ]; - async firstUpdated() { - window.requestIdleCallback(async () => { - if (this.shadowRoot) { - const { enableVibrate } = await import('../utils/handle-vibrate'); - enableVibrate(this.shadowRoot); - } - }); - } - async openUser() { // Set viewTransitionName for cross-document view transition // @ts-expect-error - viewTransitionName not yet in CSSStyleDeclaration types diff --git a/src/generated/locales/de.ts b/src/generated/locales/de.ts index 1603338..58c44ce 100644 --- a/src/generated/locales/de.ts +++ b/src/generated/locales/de.ts @@ -322,6 +322,8 @@ export const templates = { s804676468ea1af74: `No credentials to sync`, sfa39c2b9c0dd0c02: `Failed to sync to watch`, s2b5047d39b9baf3d: `Preferences`, + s399b2152de758495: `Haptic Feedback`, + s1210a6c6ad65d97b: `Vibrate on actions like likes, boosts, and publishing.`, s5ddb4ae6884197c4: `Sync to Watch`, s36c13bb456523146: `Synced ✓`, s9cd4984f1a746b40: `Syncing…`, diff --git a/src/generated/locales/es.ts b/src/generated/locales/es.ts index 5d6f4c7..1750db1 100644 --- a/src/generated/locales/es.ts +++ b/src/generated/locales/es.ts @@ -322,6 +322,8 @@ export const templates = { s804676468ea1af74: `No credentials to sync`, sfa39c2b9c0dd0c02: `Failed to sync to watch`, s2b5047d39b9baf3d: `Preferences`, + s399b2152de758495: `Haptic Feedback`, + s1210a6c6ad65d97b: `Vibrate on actions like likes, boosts, and publishing.`, s5ddb4ae6884197c4: `Sync to Watch`, s36c13bb456523146: `Synced ✓`, s9cd4984f1a746b40: `Syncing…`, diff --git a/src/pages/app-home.ts b/src/pages/app-home.ts index 2528a47..8d657d3 100644 --- a/src/pages/app-home.ts +++ b/src/pages/app-home.ts @@ -90,6 +90,7 @@ export class AppHome extends LitElement { @state() wellnessMode: boolean = false; @state() dataSaverMode: boolean = false; + @state() hapticsEnabled: boolean = true; @state() summary: string = ''; @@ -277,6 +278,8 @@ export class AppHome extends LitElement { this.handleWellnessMode(settings.wellness || false); this.handleDataSaverMode(settings.data_saver || false); + + this.handleHapticsMode(settings.haptics !== false); } // Only check notifications for authenticated users @@ -320,13 +323,6 @@ export class AppHome extends LitElement { this.tabController.openATab(tabToOpen); } - window.requestIdleCallback(async () => { - if (this.shadowRoot) { - const { enableVibrate } = await import('../utils/handle-vibrate'); - enableVibrate(this.shadowRoot); - } - }); - // Defer right-click menu and install prompt check - not needed immediately window.requestIdleCallback(() => { this.loadRightClick(); @@ -543,6 +539,16 @@ export class AppHome extends LitElement { setSettings({ data_saver: mode }); } + async handleHapticsMode(enabled: boolean) { + this.hapticsEnabled = enabled; + + const { setHapticsEnabled } = await import('../utils/haptics'); + setHapticsEnabled(enabled); + + const { setSettings } = await import('../services/settings'); + setSettings({ haptics: enabled }); + } + async handleTabChange(event: TabChangeEvent) { // Determine the load callback: // If we were passed a panel, we might need simple loading @@ -1104,12 +1110,15 @@ export class AppHome extends LitElement { .instanceInfo="${this.instanceInfo}" .wellnessMode="${this.wellnessMode}" .dataSaverMode="${this.dataSaverMode}" + .hapticsEnabled="${this.hapticsEnabled}" .userTermsLoaded="${this.userTermsLoaded}" .appThemeLoaded="${this.appThemeLoaded}" @wellness-change="${(e: CustomEvent<{ checked: boolean }>) => this.handleWellnessMode(e.detail.checked)}" @data-saver-change="${(e: CustomEvent<{ checked: boolean }>) => this.handleDataSaverMode(e.detail.checked)}" + @haptics-change="${(e: CustomEvent<{ checked: boolean }>) => + this.handleHapticsMode(e.detail.checked)}" @open-filters="${() => this.openFiltersDialog()}" @open-scheduled-statuses="${() => this.openScheduledStatusesDialog()}" diff --git a/src/pages/app-login.ts b/src/pages/app-login.ts index 86900d1..fd8383f 100644 --- a/src/pages/app-login.ts +++ b/src/pages/app-login.ts @@ -141,18 +141,6 @@ export class AppLogin extends LitElement { timeout: 8000, } ); - - requestIdleCallback( - async () => { - if (this.shadowRoot) { - const { enableVibrate } = await import('../utils/handle-vibrate'); - enableVibrate(this.shadowRoot); - } - }, - { - timeout: 8000, - } - ); } private async init() { diff --git a/src/pages/app-profile.ts b/src/pages/app-profile.ts index f749917..00f6458 100644 --- a/src/pages/app-profile.ts +++ b/src/pages/app-profile.ts @@ -1026,6 +1026,10 @@ export class AppProfile extends LitElement { // Store original state for rollback const originalFollowed = this.followed; + import('../utils/haptics').then(({ hapticImpact }) => + hapticImpact('light') + ); + await withOptimisticUpdate( // Apply optimistic update () => { @@ -1210,6 +1214,10 @@ export class AppProfile extends LitElement { // Store original state for rollback const originalFollowed = this.followed; + import('../utils/haptics').then(({ hapticImpact }) => + hapticImpact('light') + ); + await withOptimisticUpdate( // Apply optimistic update () => { diff --git a/src/services/settings.ts b/src/services/settings.ts index fd36eb3..4fad344 100644 --- a/src/services/settings.ts +++ b/src/services/settings.ts @@ -5,6 +5,7 @@ export interface Settings { wellness?: boolean; focus?: boolean; sensitive?: boolean; + haptics?: boolean; } const defaultSettings = { @@ -14,6 +15,7 @@ const defaultSettings = { wellness: false, focus: false, sensitive: false, + haptics: true, }; export async function getSettings(): Promise { @@ -41,6 +43,9 @@ export async function setSettings(settings: Settings) { sensitive: Object.keys(settings).includes('sensitive') ? settings.sensitive : currentSettings.sensitive, + haptics: Object.keys(settings).includes('haptics') + ? settings.haptics + : currentSettings.haptics, }; // Also store theme color in localStorage for instant access on page load diff --git a/src/utils/handle-vibrate.ts b/src/utils/handle-vibrate.ts index 250f9c0..8d4a8a9 100644 --- a/src/utils/handle-vibrate.ts +++ b/src/utils/handle-vibrate.ts @@ -1,13 +1,3 @@ -export function enableVibrate(root: ShadowRoot) { - // find all md-button elements in the shadow root - const buttons = root.querySelectorAll('md-button'); - const slButtons = root.querySelectorAll('sl-button'); - - // add a click event listener to each button - [...buttons, ...slButtons].forEach((button) => { - button.addEventListener('click', () => { - // vibrate for 10ms - navigator.vibrate(10); - }); - }); -} +// This file is intentionally empty. +// Haptics are now handled by src/utils/haptics.ts. +// This file can be safely deleted. diff --git a/src/utils/haptics.ts b/src/utils/haptics.ts new file mode 100644 index 0000000..8777ae0 --- /dev/null +++ b/src/utils/haptics.ts @@ -0,0 +1,103 @@ +import { Capacitor } from '@capacitor/core'; + +type ImpactStyle = 'light' | 'medium' | 'heavy'; +type NotificationType = 'success' | 'warning' | 'error'; + +let _hapticsEnabled: boolean | null = null; + +async function isEnabled(): Promise { + if (_hapticsEnabled !== null) return _hapticsEnabled; + try { + const { getSettings } = await import('../services/settings'); + const settings = await getSettings(); + _hapticsEnabled = settings.haptics !== false; + } catch { + _hapticsEnabled = true; + } + return _hapticsEnabled; +} + +/** Call after the user changes the haptics setting to update the cache. */ +export function setHapticsEnabled(enabled: boolean) { + _hapticsEnabled = enabled; +} + +const vibrateDurations: Record = { + light: 10, + medium: 20, + heavy: 30, +}; + +const notificationDurations: Record = { + success: 15, + warning: 20, + error: 30, +}; + +/** + * Trigger an impact haptic. Use for discrete user actions like tapping + * a like/boost/bookmark button. + */ +export async function hapticImpact(style: ImpactStyle = 'light') { + try { + if (!(await isEnabled())) return; + + if (Capacitor.isNativePlatform()) { + const { Haptics, ImpactStyle } = await import('@capacitor/haptics'); + const map: Record = { + light: ImpactStyle.Light, + medium: ImpactStyle.Medium, + heavy: ImpactStyle.Heavy, + }; + await Haptics.impact({ style: map[style] }); + } else if (navigator.vibrate) { + navigator.vibrate(vibrateDurations[style]); + } + } catch { + // Haptics should never throw or block the UI + } +} + +/** + * Trigger a notification haptic. Use for outcome feedback like + * successfully publishing a post. + */ +export async function hapticNotification(type: NotificationType = 'success') { + try { + if (!(await isEnabled())) return; + + if (Capacitor.isNativePlatform()) { + const { Haptics, NotificationType } = await import('@capacitor/haptics'); + const map: Record = + { + success: NotificationType.Success, + warning: NotificationType.Warning, + error: NotificationType.Error, + }; + await Haptics.notification({ type: map[type] }); + } else if (navigator.vibrate) { + navigator.vibrate(notificationDurations[type]); + } + } catch { + // Haptics should never throw or block the UI + } +} + +/** + * Trigger a light selection tick. Use for selection changes or + * pull-to-refresh thresholds. + */ +export async function hapticSelection() { + try { + if (!(await isEnabled())) return; + + if (Capacitor.isNativePlatform()) { + const { Haptics } = await import('@capacitor/haptics'); + await Haptics.selectionChanged(); + } else if (navigator.vibrate) { + navigator.vibrate(5); + } + } catch { + // Haptics should never throw or block the UI + } +} diff --git a/src/utils/timeline-actions.ts b/src/utils/timeline-actions.ts index 84e61c2..6de8f9d 100644 --- a/src/utils/timeline-actions.ts +++ b/src/utils/timeline-actions.ts @@ -73,6 +73,8 @@ export async function toggleStatusAction(options: ToggleOptions) { return; } + import('./haptics').then(({ hapticImpact }) => hapticImpact('light')); + if (isActive) { // UNDO await withOptimisticUpdate( @@ -105,6 +107,8 @@ export async function performOneWayAction( return; } + import('./haptics').then(({ hapticImpact }) => hapticImpact('light')); + await withOptimisticUpdate(onOptimisticUpdate, apiCall, onRollback, { errorMessage, }); diff --git a/tests/services/settings.test.ts b/tests/services/settings.test.ts index 50f19a2..dd2cd7c 100644 --- a/tests/services/settings.test.ts +++ b/tests/services/settings.test.ts @@ -118,6 +118,7 @@ describe('settings service', () => { wellness: true, focus: true, sensitive: true, + haptics: true, }; await setSettings(fullSettings); From 2405af6efb6673c01ad20602c784e9fc89728588 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Fri, 20 Mar 2026 22:21:43 -0700 Subject: [PATCH 25/26] localize --- xliff/de.xlf | 6 ++++++ xliff/es.xlf | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/xliff/de.xlf b/xliff/de.xlf index b69c202..28aa788 100644 --- a/xliff/de.xlf +++ b/xliff/de.xlf @@ -1928,6 +1928,12 @@ Signing in… + + Haptic Feedback + + + Vibrate on actions like likes, boosts, and publishing. + diff --git a/xliff/es.xlf b/xliff/es.xlf index c63ca5e..a3d1110 100644 --- a/xliff/es.xlf +++ b/xliff/es.xlf @@ -1928,6 +1928,12 @@ Signing in… + + Haptic Feedback + + + Vibrate on actions like likes, boosts, and publishing. + From 4c2f14c359d3a04c00608b6de9ffcce5991d6e23 Mon Sep 17 00:00:00 2001 From: Justin Willis Date: Fri, 20 Mar 2026 22:58:42 -0700 Subject: [PATCH 26/26] bundle size back below cutoff --- src/app-index.ts | 7 +++---- vite.config.ts | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/app-index.ts b/src/app-index.ts index ffebe05..b1dcc39 100644 --- a/src/app-index.ts +++ b/src/app-index.ts @@ -172,15 +172,14 @@ export class AppIndex extends LitElement { } firstUpdated() { - // Sync localStorage credentials to IndexedDB for service worker access - // and determine authentication state - this.syncCredentialsToIndexedDB(); - // Check initial authentication state this.checkAuthenticationState(); console.log('[App] isAuthenticated:', this.isAuthenticated); if (this.isAuthenticated) { + // Sync localStorage credentials to IndexedDB for service worker access + this.syncCredentialsToIndexedDB(); + this.handleInitTheme(); // Preload data during idle time, then precache critical components. diff --git a/vite.config.ts b/vite.config.ts index 8566aff..0011448 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -179,7 +179,7 @@ customPlugins.push({ handler(html: string, { bundle }: { bundle?: Record }) { if (!bundle) return html; - const chunksToPreload = ['vendor-idb-keyval', 'preload-']; + const chunksToPreload = ['vendor-idb-keyval']; const preloadLinks: string[] = []; for (const chunkPattern of chunksToPreload) {