diff --git a/mobile/package.json b/mobile/package.json index 9d66794..e528fdb 100644 --- a/mobile/package.json +++ b/mobile/package.json @@ -28,6 +28,7 @@ "@bytelyst/survey-client": "^0.1.0", "@bytelyst/telemetry-client": "^0.1.0", "expo": "~55.0.4", + "expo-constants": "~18.0.13", "expo-router": "~6.0.4", "expo-status-bar": "~3.0.9", "react": "19.2.0", diff --git a/mobile/src/app/(tabs)/_layout.tsx b/mobile/src/app/(tabs)/_layout.tsx index 4477ae2..f9f218b 100644 --- a/mobile/src/app/(tabs)/_layout.tsx +++ b/mobile/src/app/(tabs)/_layout.tsx @@ -3,11 +3,11 @@ import { Tabs } from 'expo-router'; export default function TabLayout() { return ( - - - - - + + + + + ); } diff --git a/mobile/src/app/(tabs)/capture.tsx b/mobile/src/app/(tabs)/capture.tsx index c1afe3c..188f9e7 100644 --- a/mobile/src/app/(tabs)/capture.tsx +++ b/mobile/src/app/(tabs)/capture.tsx @@ -64,6 +64,7 @@ export default function CaptureScreen() { textAlignVertical="top" /> { const didSave = await saveDraft(activeWorkspaceId, title, body); setSaved(didSave); diff --git a/mobile/src/app/(tabs)/inbox.tsx b/mobile/src/app/(tabs)/inbox.tsx index a212df8..8645e30 100644 --- a/mobile/src/app/(tabs)/inbox.tsx +++ b/mobile/src/app/(tabs)/inbox.tsx @@ -40,6 +40,7 @@ export default function InboxScreen() { Status: {item.status} {errorMessage ? {errorMessage} : null} { const didAuthenticate = mode === 'signin' @@ -87,6 +88,7 @@ export default function AuthScreen() { { setErrorMessage(null); setMode((current) => (current === 'signin' ? 'register' : 'signin')); diff --git a/mobile/src/lib/app-metadata.ts b/mobile/src/lib/app-metadata.ts new file mode 100644 index 0000000..246e108 --- /dev/null +++ b/mobile/src/lib/app-metadata.ts @@ -0,0 +1,12 @@ +import Constants from 'expo-constants'; +import { Platform } from 'react-native'; + +export const APP_PLATFORM: 'ios' | 'android' = Platform.OS === 'android' ? 'android' : 'ios'; + +export const APP_VERSION = Constants.expoConfig?.version ?? '0.1.0'; + +export const BUILD_NUMBER = + Constants.expoConfig?.ios?.buildNumber ?? + (Constants.expoConfig?.android?.versionCode ? String(Constants.expoConfig.android.versionCode) : '1'); + +export const OS_VERSION = typeof Platform.Version === 'string' ? Platform.Version : String(Platform.Version ?? 'unknown'); diff --git a/mobile/src/lib/broadcast-client.ts b/mobile/src/lib/broadcast-client.ts index 7d9a7bf..2b93137 100644 --- a/mobile/src/lib/broadcast-client.ts +++ b/mobile/src/lib/broadcast-client.ts @@ -1,6 +1,7 @@ import { createBroadcastClient, type BroadcastClient } from '@bytelyst/broadcast-client'; import { API_CONFIG, PRODUCT_ID } from '../api/config'; import { getAuthClient } from '../api/auth'; +import { APP_PLATFORM, APP_VERSION, OS_VERSION } from './app-metadata'; let broadcastClient: BroadcastClient | null = null; @@ -10,9 +11,9 @@ export function getBroadcastClient(): BroadcastClient { baseUrl: API_CONFIG.platformBaseUrl, productId: PRODUCT_ID, getAuthToken: () => getAuthClient().getAccessToken() ?? '', - platform: 'ios', - appVersion: '0.1.0', - osVersion: 'unknown', + platform: APP_PLATFORM, + appVersion: APP_VERSION, + osVersion: OS_VERSION, }); } diff --git a/mobile/src/lib/platform.ts b/mobile/src/lib/platform.ts index b28e368..32bdb5f 100644 --- a/mobile/src/lib/platform.ts +++ b/mobile/src/lib/platform.ts @@ -5,6 +5,7 @@ import { createBlobClient } from '@bytelyst/blob-client'; import { DiagnosticsClient } from '@bytelyst/diagnostics-client'; import { API_CONFIG, PRODUCT_ID } from '../api/config'; import { mmkvStorage } from '../store/mmkv-storage'; +import { APP_VERSION, BUILD_NUMBER, OS_VERSION } from './app-metadata'; function getAccessToken(): string | null { return mmkvStorage.getItem(`${PRODUCT_ID}_access_token`); @@ -17,10 +18,10 @@ export const telemetryClient = createTelemetryClient({ platform: 'mobile', channel: 'notelett_mobile', transport: 'fetch', - appVersion: '0.1.0', - buildNumber: '1', + appVersion: APP_VERSION, + buildNumber: BUILD_NUMBER, releaseChannel: 'dev', - osFamily: 'other', + osFamily: OS_VERSION, }); export const featureFlagClient = createFeatureFlagClient({ @@ -54,9 +55,9 @@ export function getDiagnosticsClient() { platform: 'mobile', channel: 'notelett_mobile', anonymousInstallId: mmkvStorage.getItem(`${PRODUCT_ID}_install_id`) ?? 'unknown', - osFamily: 'other', - appVersion: '0.1.0', - buildNumber: '1', + osFamily: OS_VERSION, + appVersion: APP_VERSION, + buildNumber: BUILD_NUMBER, releaseChannel: 'dev', getAuthToken: () => getAccessToken() ?? '', }); diff --git a/mobile/src/lib/survey-client.ts b/mobile/src/lib/survey-client.ts index c195401..aab844f 100644 --- a/mobile/src/lib/survey-client.ts +++ b/mobile/src/lib/survey-client.ts @@ -1,6 +1,7 @@ import { createSurveyClient, type SurveyClient } from '@bytelyst/survey-client'; import { API_CONFIG, PRODUCT_ID } from '../api/config'; import { getAuthClient } from '../api/auth'; +import { APP_PLATFORM, APP_VERSION, OS_VERSION } from './app-metadata'; let surveyClient: SurveyClient | null = null; @@ -10,9 +11,9 @@ export function getSurveyClient(): SurveyClient { baseUrl: API_CONFIG.platformBaseUrl, productId: PRODUCT_ID, getAuthToken: () => getAuthClient().getAccessToken() ?? '', - platform: 'ios', - appVersion: '0.1.0', - osVersion: 'unknown', + platform: APP_PLATFORM, + appVersion: APP_VERSION, + osVersion: OS_VERSION, }); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e1f67bb..fd71078 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -126,9 +126,12 @@ importers: expo: specifier: ~55.0.4 version: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(expo-router@6.0.23)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo-constants: + specifier: ~18.0.13 + version: 18.0.13(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0)) expo-router: specifier: ~6.0.4 - version: 6.0.23(fbac16d1b6e18492193348f9e089f0a0) + version: 6.0.23(8f4d8b3ea945913a36065f8394178341) expo-status-bar: specifier: ~3.0.9 version: 3.0.9(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) @@ -7335,7 +7338,7 @@ snapshots: '@exodus/bytes@1.15.0': {} - '@expo/cli@55.0.18(@expo/dom-webview@55.0.3)(expo-constants@55.0.9)(expo-font@55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(expo-router@6.0.23)(expo@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)': + '@expo/cli@55.0.18(@expo/dom-webview@55.0.3)(expo-constants@55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3))(expo-font@55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(expo-router@6.0.23)(expo@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)': dependencies: '@expo/code-signing-certificates': 0.0.6 '@expo/config': 55.0.10(typescript@5.9.3) @@ -7352,7 +7355,7 @@ snapshots: '@expo/plist': 0.5.2 '@expo/prebuild-config': 55.0.10(expo@55.0.8)(typescript@5.9.3) '@expo/require-utils': 55.0.3(typescript@5.9.3) - '@expo/router-server': 55.0.11(expo-constants@55.0.9)(expo-font@55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(expo-router@6.0.23)(expo-server@55.0.6)(expo@55.0.8)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@expo/router-server': 55.0.11(expo-constants@55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3))(expo-font@55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(expo-router@6.0.23)(expo-server@55.0.6)(expo@55.0.8)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@expo/schema-utils': 55.0.2 '@expo/spawn-async': 1.7.2 '@expo/ws-tunnel': 1.0.6 @@ -7396,7 +7399,7 @@ snapshots: ws: 8.20.0 zod: 3.25.76 optionalDependencies: - expo-router: 6.0.23(fbac16d1b6e18492193348f9e089f0a0) + expo-router: 6.0.23(8f4d8b3ea945913a36065f8394178341) react-native: 0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0) transitivePeerDependencies: - '@expo/dom-webview' @@ -7679,7 +7682,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/router-server@55.0.11(expo-constants@55.0.9)(expo-font@55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(expo-router@6.0.23)(expo-server@55.0.6)(expo@55.0.8)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@expo/router-server@55.0.11(expo-constants@55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3))(expo-font@55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(expo-router@6.0.23)(expo-server@55.0.6)(expo@55.0.8)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: debug: 4.4.3 expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(expo-router@6.0.23)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) @@ -7688,7 +7691,7 @@ snapshots: expo-server: 55.0.6 react: 19.2.0 optionalDependencies: - expo-router: 6.0.23(fbac16d1b6e18492193348f9e089f0a0) + expo-router: 6.0.23(8f4d8b3ea945913a36065f8394178341) react-dom: 19.2.0(react@19.2.0) transitivePeerDependencies: - supports-color @@ -8409,9 +8412,7 @@ snapshots: metro-runtime: 0.83.5 transitivePeerDependencies: - '@babel/core' - - bufferutil - supports-color - - utf-8-validate '@react-native/normalize-colors@0.83.2': {} @@ -10365,7 +10366,7 @@ snapshots: react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0) - expo-router@6.0.23(fbac16d1b6e18492193348f9e089f0a0): + expo-router@6.0.23(8f4d8b3ea945913a36065f8394178341): dependencies: '@expo/schema-utils': 0.1.8 '@radix-ui/react-slot': 1.2.0(@types/react@19.2.14)(react@19.2.0) @@ -10377,7 +10378,7 @@ snapshots: debug: 4.4.3 escape-string-regexp: 4.0.0 expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(expo-router@6.0.23)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-constants: 55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) + expo-constants: 18.0.13(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0)) expo-linking: 8.0.11(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) expo-server: 1.0.5 fast-deep-equal: 3.1.3 @@ -10419,7 +10420,7 @@ snapshots: expo@55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(expo-router@6.0.23)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): dependencies: '@babel/runtime': 7.29.2 - '@expo/cli': 55.0.18(@expo/dom-webview@55.0.3)(expo-constants@55.0.9)(expo-font@55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(expo-router@6.0.23)(expo@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + '@expo/cli': 55.0.18(@expo/dom-webview@55.0.3)(expo-constants@55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3))(expo-font@55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(expo-router@6.0.23)(expo@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) '@expo/config': 55.0.10(typescript@5.9.3) '@expo/config-plugins': 55.0.7 '@expo/devtools': 55.0.2(react-native@0.83.2(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)