feat(watch): add workout deletion sync and optimize delete operations

This commit is contained in:
2026-08-12 13:52:23 +02:00
parent 2096489fd1
commit ca9259d5bd
6 changed files with 95 additions and 64 deletions
+25
View File
@@ -166,6 +166,31 @@ public class WatchConnectivityModule: Module {
}
}
AsyncFunction("sendWorkoutDeleted") { (id: String, promise: Promise) in
guard let session = self.session else {
promise.reject("NO_SESSION", "WCSession not available")
return
}
func doSend() {
let message: [String: Any] = ["type": "workoutDeleted", "id": id]
guard let cleaned = self.cleanForWCSession(message) as? [String: Any] else {
promise.resolve(["status": "sent"])
return
}
session.transferUserInfo(cleaned)
promise.resolve(["status": "sent"])
}
if self.isActivated {
doSend()
} else {
self.pendingPromises.append(doSend)
}
}
AsyncFunction("getApplicationContext") { () -> [String: Any]? in
return self.session?.receivedApplicationContext as? [String: Any]
}
+61 -60
View File
@@ -1,62 +1,63 @@
{
"name": "swimbuddy",
"version": "1.0.0",
"main": "index.ts",
"dependencies": {
"@bacons/apple-targets": "^5.0.0",
"@expo/vector-icons": "^15.0.2",
"@react-navigation/bottom-tabs": "^7.18.14",
"@react-navigation/native": "^7.3.14",
"@react-navigation/native-stack": "^7.18.6",
"@sentry/react-native": "^8.22.0",
"@tailwindcss/postcss": "^4.3.3",
"drizzle-orm": "^0.45.2",
"expo": "~57.0.10",
"expo-application": "~57.0.2",
"expo-localization": "~57.0.1",
"expo-splash-screen": "~57.0.6",
"expo-sqlite": "~57.0.1",
"expo-status-bar": "~57.0.1",
"expo-system-ui": "~57.0.2",
"expo-updates": "^57.0.12",
"i18next": "^26.3.6",
"nativewind": "^5.0.0-preview.4",
"react": "19.2.3",
"react-i18next": "^17.0.11",
"react-native": "0.86.2",
"react-native-css": "^3.0.7",
"react-native-gesture-handler": "~2.32.0",
"react-native-mmkv": "^4.3.2",
"react-native-reanimated": "4.5.1",
"react-native-safe-area-context": "~5.7.0",
"react-native-screens": "~4.26.0"
},
"devDependencies": {
"@types/react": "~19.2.2",
"babel-plugin-inline-import": "^3.0.0",
"drizzle-kit": "^0.31.10",
"tailwindcss": "^4",
"typescript": "~6.0.3"
},
"scripts": {
"start": "expo start",
"android": "expo run:android",
"ios": "expo run:ios",
"web": "expo start --web",
"db:generate": "drizzle-kit generate",
"prebuild": "expo prebuild && npm run eas-build-post-install",
"prebuild:clean": "expo prebuild --clean && npm run eas-build-post-install",
"eas-build-post-install": "node scripts/add-sentry-watch.js",
"build:wearos:debug": "./scripts/build-wearos.sh debug",
"build:wearos:release": "./scripts/build-wearos.sh release",
"deploy:ios": "eas build --platform ios --profile ${1:-preview} && eas submit --platform ios --profile ${1:-preview}",
"deploy:android": "eas build --platform android --profile ${1:-preview} && eas submit --platform android --profile ${1:-preview}",
"deploy:wearos": "./scripts/build-wearos.sh release ${2:-}",
"update": "eas update --branch ${1:-preview}",
"update:production": "eas update --branch production"
},
"private": true,
"overrides": {
"lightningcss": "1.30.1"
}
"name": "swimbuddy",
"version": "1.0.0",
"main": "index.ts",
"dependencies": {
"@bacons/apple-targets": "^5.0.0",
"@expo/vector-icons": "^15.0.2",
"@react-navigation/bottom-tabs": "^7.18.14",
"@react-navigation/native": "^7.3.14",
"@react-navigation/native-stack": "^7.18.6",
"@sentry/react-native": "^8.22.0",
"@tailwindcss/postcss": "^4.3.3",
"drizzle-orm": "^0.45.2",
"expo": "~57.0.10",
"expo-application": "~57.0.2",
"expo-localization": "~57.0.1",
"expo-splash-screen": "~57.0.6",
"expo-sqlite": "~57.0.1",
"expo-status-bar": "~57.0.1",
"expo-system-ui": "~57.0.2",
"expo-updates": "^57.0.12",
"i18next": "^26.3.6",
"nativewind": "^5.0.0-preview.4",
"react": "19.2.3",
"react-i18next": "^17.0.11",
"react-native": "0.86.2",
"react-native-css": "^3.0.7",
"react-native-gesture-handler": "~2.32.0",
"react-native-mmkv": "^4.3.2",
"react-native-reanimated": "4.5.1",
"react-native-safe-area-context": "~5.7.0",
"react-native-screens": "~4.26.0"
},
"devDependencies": {
"@types/react": "~19.2.2",
"babel-plugin-inline-import": "^3.0.0",
"drizzle-kit": "^0.31.10",
"tailwindcss": "^4",
"typescript": "~6.0.3"
},
"scripts": {
"start": "expo start",
"android": "expo run:android",
"ios": "expo run:ios",
"web": "expo start --web",
"clean": "rm -rf .expo ios android node_modules && npm i",
"db:generate": "drizzle-kit generate",
"prebuild": "expo prebuild && npm run eas-build-post-install",
"prebuild:clean": "expo prebuild --clean && npm run eas-build-post-install",
"eas-build-post-install": "node scripts/add-sentry-watch.js",
"build:wearos:debug": "./scripts/build-wearos.sh debug",
"build:wearos:release": "./scripts/build-wearos.sh release",
"deploy:ios": "eas build --platform ios --profile ${1:-preview} && eas submit --platform ios --profile ${1:-preview}",
"deploy:android": "eas build --platform android --profile ${1:-preview} && eas submit --platform android --profile ${1:-preview}",
"deploy:wearos": "./scripts/build-wearos.sh release ${2:-}",
"update": "eas update --branch ${1:-preview}",
"update:production": "eas update --branch production"
},
"private": true,
"overrides": {
"lightningcss": "1.30.1"
}
}
+6 -2
View File
@@ -253,7 +253,9 @@ export async function deleteSession(sessionId: string) {
export async function deleteSessionAndSync(sessionId: string) {
await deleteSession(sessionId);
await WatchConnectivity.sendWorkoutDeleted(sessionId);
WatchConnectivity.sendWorkoutDeleted(sessionId).catch((err) =>
console.warn("[ops] sync failed:", err)
);
}
export async function deleteWorkout(id: string) {
@@ -272,7 +274,9 @@ export async function deleteWorkout(id: string) {
export async function deleteWorkoutAndSync(id: string) {
await deleteWorkout(id);
await WatchConnectivity.sendWorkoutDeleted(id);
WatchConnectivity.sendWorkoutDeleted(id).catch((err) =>
console.warn("[ops] sync failed:", err)
);
}
// ─── Stats ───────────────────────────────────────────────────
@@ -52,7 +52,7 @@ export function HistoryScreen() {
style: "destructive",
onPress: async () => {
await deleteSessionAndSync(id);
await loadSessions();
setSessions((prev) => prev.filter((s) => s.id !== id));
},
},
]);
@@ -64,7 +64,7 @@ export function WorkoutListScreen() {
style: "destructive",
onPress: async () => {
await deleteWorkoutAndSync(id);
await loadWorkouts();
setWorkouts((prev) => prev.filter((w) => w.id !== id));
},
},
]);
+1
View File
@@ -9,6 +9,7 @@ WatchConnectivity = requireOptionalNativeModule("WatchConnectivity") ?? {
isReachable: async () => false,
sendWorkoutPlan: async () => ({ error: "WatchConnectivity native module not available" }),
sendWorkoutCompletion: async () => ({ error: "WatchConnectivity native module not available" }),
sendWorkoutDeleted: async () => ({ error: "WatchConnectivity native module not available" }),
pollEvents: async () => [],
getApplicationContext: async () => null,
updateApplicationContext: async () => {},