wip bsky client for the web & android bbell.vt3e.cat

feat: deep linking :D

vt3e.cat e784ab23 673507a3

verified
+41 -3
+1
.gitignore
··· 1 .android-sdk 2 3 # Logs 4 logs
··· 1 .android-sdk 2 + _keep/ 3 4 # Logs 5 logs
+7
android/app/src/main/AndroidManifest.xml
··· 22 <category android:name="android.intent.category.LAUNCHER" /> 23 </intent-filter> 24 25 </activity> 26 27 <provider
··· 22 <category android:name="android.intent.category.LAUNCHER" /> 23 </intent-filter> 24 25 + <intent-filter android:autoVerify="true"> 26 + <action android:name="android.intent.action.VIEW" /> 27 + <category android:name="android.intent.category.DEFAULT" /> 28 + <category android:name="android.intent.category.BROWSABLE" /> 29 + <data android:scheme="https" android:host="bbell.vt3e.cat" /> 30 + </intent-filter> 31 + 32 </activity> 33 34 <provider
+9 -1
src/App.vue
··· 1 <script setup lang="ts"> 2 import { onMounted, computed, ref, onUnmounted } from 'vue' 3 - import { App } from '@capacitor/app' 4 5 import { useNavigationStore } from './stores/navigation' 6 import { useEnvironmentStore } from './stores/environment' ··· 64 App.addListener('backButton', handleBackNavigation) 65 document.addEventListener('keyup', (e) => { 66 if (e.key === 'e' && e.altKey) handleBackNavigation() 67 }) 68 69 theme.init()
··· 1 <script setup lang="ts"> 2 import { onMounted, computed, ref, onUnmounted } from 'vue' 3 + import { App, type URLOpenListenerEvent } from '@capacitor/app' 4 5 import { useNavigationStore } from './stores/navigation' 6 import { useEnvironmentStore } from './stores/environment' ··· 64 App.addListener('backButton', handleBackNavigation) 65 document.addEventListener('keyup', (e) => { 66 if (e.key === 'e' && e.altKey) handleBackNavigation() 67 + }) 68 + 69 + App.addListener('appUrlOpen', function (event: URLOpenListenerEvent) { 70 + const slug = event.url.split('https://bbell.vt3e.cat').pop() 71 + console.log(slug, window.location.href, event) 72 + if (!slug) return 73 + if (slug.startsWith('/oauth/callback')) isCallback.value = true 74 + else nav.navigateToUrl(slug) 75 }) 76 77 theme.init()
+24 -2
src/stores/navigation.ts
··· 228 } 229 } 230 231 - function parseUrl() { 232 - const path = window.location.pathname 233 const searchParams = new URLSearchParams(window.location.search) 234 235 const match = matchPageByPath(path) ··· 286 isInitialized.value = true 287 } 288 289 return { 290 activeTab, 291 stacks, 292 canGoBack, 293 pendingPop, 294 init, 295 switchTab, 296 resetTab,
··· 228 } 229 } 230 231 + function parseUrl(path: string = window.location.pathname) { 232 const searchParams = new URLSearchParams(window.location.search) 233 234 const match = matchPageByPath(path) ··· 285 isInitialized.value = true 286 } 287 288 + function navigateToUrl(path: string) { 289 + const { page, root, props } = parseUrl(path) 290 + 291 + console.log(page, root, props) 292 + activeTab.value = 'home' 293 + 294 + const stack = stacks.value['home'] 295 + const rootEntry = stack[0] 296 + if (!rootEntry) return 297 + 298 + const subPageEntry: StackEntry = { 299 + id: generateId(page), 300 + page: page as PageKey, 301 + props, 302 + } 303 + 304 + stacks.value['home'] = [rootEntry, subPageEntry] 305 + updateHistory('replace', 'home', rootEntry) 306 + updateHistory('push', 'home', subPageEntry) 307 + } 308 + 309 return { 310 activeTab, 311 stacks, 312 canGoBack, 313 pendingPop, 314 + parseUrl, 315 + navigateToUrl, 316 init, 317 switchTab, 318 resetTab,