wip bsky client for the web & android
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: handle back gesture; fix padding

vi 673507a3 c715e65b

+52 -4
+1 -1
android/app/capacitor.build.gradle
··· 9 9 10 10 apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" 11 11 dependencies { 12 - 12 + implementation project(':capacitor-app') 13 13 14 14 } 15 15
+3
android/capacitor.settings.gradle
··· 1 1 // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 2 include ':capacitor-android' 3 3 project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') 4 + 5 + include ':capacitor-app' 6 + project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/android')
+3
bun.lock
··· 11 11 "@atcute/lexicons": "^1.2.5", 12 12 "@atcute/oauth-browser-client": "^2.0.3", 13 13 "@capacitor/android": "^8.0.0", 14 + "@capacitor/app": "^8.0.0", 14 15 "@capacitor/core": "^8.0.0", 15 16 "@iconify-prerendered/vue-material-symbols": "^0.28.1755063979", 16 17 "add": "^2.0.6", ··· 131 132 "@bufbuild/protobuf": ["@bufbuild/protobuf@2.10.2", "", {}, "sha512-uFsRXwIGyu+r6AMdz+XijIIZJYpoWeYzILt5yZ2d3mCjQrWUTVpVD9WL/jZAbvp+Ed04rOhrsk7FiTcEDseB5A=="], 132 133 133 134 "@capacitor/android": ["@capacitor/android@8.0.0", "", { "peerDependencies": { "@capacitor/core": "^8.0.0" } }, "sha512-FrBSvVAC5JuLaYHNyDnwQny0/SYnP+xDQbc/KA4wInmRkMXLDv22fkx9aBJIDrxjuUVd+jsRih4SAt8FgMEzCw=="], 135 + 136 + "@capacitor/app": ["@capacitor/app@8.0.0", "", { "peerDependencies": { "@capacitor/core": ">=8.0.0" } }, "sha512-OwzIkUs4w433Bu9WWAEbEYngXEfJXZ9Wmdb8eoaqzYBgB0W9/3Ed/mh6sAYPNBAZlpyarmewgP7Nb+d3Vrh+xA=="], 134 137 135 138 "@capacitor/cli": ["@capacitor/cli@8.0.0", "", { "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.1", "open": "^8.4.0", "plist": "^3.1.0", "prompts": "^2.4.2", "rimraf": "^6.0.1", "semver": "^7.6.3", "tar": "^6.1.11", "tslib": "^2.8.1", "xml2js": "^0.6.2" }, "bin": { "cap": "bin/capacitor", "capacitor": "bin/capacitor" } }, "sha512-v9hEBi69xGxuuZhg55N031bMEenKaPSv71Il8C22VOOH6surDyv/MPeImN0oVfFc7eiklaW3rDFYVz6cmXfJWQ=="], 136 139
+1
package.json
··· 25 25 "@atcute/lexicons": "^1.2.5", 26 26 "@atcute/oauth-browser-client": "^2.0.3", 27 27 "@capacitor/android": "^8.0.0", 28 + "@capacitor/app": "^8.0.0", 28 29 "@capacitor/core": "^8.0.0", 29 30 "@iconify-prerendered/vue-material-symbols": "^0.28.1755063979", 30 31 "add": "^2.0.6",
+24 -1
src/App.vue
··· 1 1 <script setup lang="ts"> 2 - import { onMounted, computed, ref } from 'vue' 2 + import { onMounted, computed, ref, onUnmounted } from 'vue' 3 + import { App } from '@capacitor/app' 4 + 3 5 import { useNavigationStore } from './stores/navigation' 4 6 import { useEnvironmentStore } from './stores/environment' 5 7 import { useThemeStore } from './stores/theme' ··· 47 49 } 48 50 } 49 51 52 + const handleBackNavigation = () => { 53 + if (!nav.canGoBack) { 54 + if (activeTab.value !== 'home') { 55 + nav.switchTab('home') 56 + return 57 + } 58 + App.exitApp().catch(() => {}) 59 + } 60 + nav.pop() 61 + } 62 + 50 63 onMounted(async () => { 64 + App.addListener('backButton', handleBackNavigation) 65 + document.addEventListener('keyup', (e) => { 66 + if (e.key === 'e' && e.altKey) handleBackNavigation() 67 + }) 68 + 51 69 theme.init() 52 70 env.init() 53 71 54 72 if (!showIntro.value && !isCallback.value) { 55 73 nav.init() 56 74 } 75 + }) 76 + 77 + onUnmounted(() => { 78 + App.removeAllListeners() 79 + document.removeEventListener('keyup', () => {}) 57 80 }) 58 81 </script> 59 82
+3 -1
src/components/Navigation/PageLayout.vue
··· 113 113 width: 100%; 114 114 max-width: 800px; 115 115 padding: 0 1rem; 116 - padding-top: calc(var(--inset-top, 0) + 4.5rem); 117 116 118 117 h1, 119 118 h2, ··· 157 156 } 158 157 159 158 .no-padding { 159 + .page-content { 160 + padding-top: calc(var(--safe-area-inset-top, 3.5rem)); 161 + } 160 162 .content-container { 161 163 padding: 0; 162 164 }
+17 -1
src/stores/navigation.ts
··· 1 1 import { defineStore } from 'pinia' 2 - import { ref } from 'vue' 2 + import { computed, ref } from 'vue' 3 3 import { 4 4 compileUrl, 5 5 getPageByName, ··· 38 38 const activeTab = ref<TabKey>('home') 39 39 const pendingPop = ref<{ tab: TabKey; count: number } | null>(null) 40 40 41 + const isRoot = computed(() => { 42 + const stack = stacks.value[activeTab.value] 43 + if (!stack) return true 44 + return stack.length <= 1 45 + }) 46 + 41 47 const stacks = ref<Record<TabKey, StackEntry[]>>( 42 48 stackRoots.reduce( 43 49 (acc, page) => { ··· 49 55 {} as Record<TabKey, StackEntry[]>, 50 56 ), 51 57 ) 58 + 59 + const canGoBack = computed(() => { 60 + const stack = stacks.value[activeTab.value] 61 + const isHomeTab = activeTab.value === 'home' 62 + if (!stack) return false 63 + if (stack.length > 1) return true 64 + 65 + return !isHomeTab 66 + }) 52 67 53 68 function updateHistory(method: 'push' | 'replace', tab: TabKey, entry: StackEntry) { 54 69 const pageConfig = getPageByName(entry.page) ··· 274 289 return { 275 290 activeTab, 276 291 stacks, 292 + canGoBack, 277 293 pendingPop, 278 294 init, 279 295 switchTab,