feat(watch): add workout deletion sync and optimize delete operations
This commit is contained in:
@@ -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
|
AsyncFunction("getApplicationContext") { () -> [String: Any]? in
|
||||||
return self.session?.receivedApplicationContext as? [String: Any]
|
return self.session?.receivedApplicationContext as? [String: Any]
|
||||||
}
|
}
|
||||||
|
|||||||
+61
-60
@@ -1,62 +1,63 @@
|
|||||||
{
|
{
|
||||||
"name": "swimbuddy",
|
"name": "swimbuddy",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bacons/apple-targets": "^5.0.0",
|
"@bacons/apple-targets": "^5.0.0",
|
||||||
"@expo/vector-icons": "^15.0.2",
|
"@expo/vector-icons": "^15.0.2",
|
||||||
"@react-navigation/bottom-tabs": "^7.18.14",
|
"@react-navigation/bottom-tabs": "^7.18.14",
|
||||||
"@react-navigation/native": "^7.3.14",
|
"@react-navigation/native": "^7.3.14",
|
||||||
"@react-navigation/native-stack": "^7.18.6",
|
"@react-navigation/native-stack": "^7.18.6",
|
||||||
"@sentry/react-native": "^8.22.0",
|
"@sentry/react-native": "^8.22.0",
|
||||||
"@tailwindcss/postcss": "^4.3.3",
|
"@tailwindcss/postcss": "^4.3.3",
|
||||||
"drizzle-orm": "^0.45.2",
|
"drizzle-orm": "^0.45.2",
|
||||||
"expo": "~57.0.10",
|
"expo": "~57.0.10",
|
||||||
"expo-application": "~57.0.2",
|
"expo-application": "~57.0.2",
|
||||||
"expo-localization": "~57.0.1",
|
"expo-localization": "~57.0.1",
|
||||||
"expo-splash-screen": "~57.0.6",
|
"expo-splash-screen": "~57.0.6",
|
||||||
"expo-sqlite": "~57.0.1",
|
"expo-sqlite": "~57.0.1",
|
||||||
"expo-status-bar": "~57.0.1",
|
"expo-status-bar": "~57.0.1",
|
||||||
"expo-system-ui": "~57.0.2",
|
"expo-system-ui": "~57.0.2",
|
||||||
"expo-updates": "^57.0.12",
|
"expo-updates": "^57.0.12",
|
||||||
"i18next": "^26.3.6",
|
"i18next": "^26.3.6",
|
||||||
"nativewind": "^5.0.0-preview.4",
|
"nativewind": "^5.0.0-preview.4",
|
||||||
"react": "19.2.3",
|
"react": "19.2.3",
|
||||||
"react-i18next": "^17.0.11",
|
"react-i18next": "^17.0.11",
|
||||||
"react-native": "0.86.2",
|
"react-native": "0.86.2",
|
||||||
"react-native-css": "^3.0.7",
|
"react-native-css": "^3.0.7",
|
||||||
"react-native-gesture-handler": "~2.32.0",
|
"react-native-gesture-handler": "~2.32.0",
|
||||||
"react-native-mmkv": "^4.3.2",
|
"react-native-mmkv": "^4.3.2",
|
||||||
"react-native-reanimated": "4.5.1",
|
"react-native-reanimated": "4.5.1",
|
||||||
"react-native-safe-area-context": "~5.7.0",
|
"react-native-safe-area-context": "~5.7.0",
|
||||||
"react-native-screens": "~4.26.0"
|
"react-native-screens": "~4.26.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "~19.2.2",
|
"@types/react": "~19.2.2",
|
||||||
"babel-plugin-inline-import": "^3.0.0",
|
"babel-plugin-inline-import": "^3.0.0",
|
||||||
"drizzle-kit": "^0.31.10",
|
"drizzle-kit": "^0.31.10",
|
||||||
"tailwindcss": "^4",
|
"tailwindcss": "^4",
|
||||||
"typescript": "~6.0.3"
|
"typescript": "~6.0.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "expo start",
|
"start": "expo start",
|
||||||
"android": "expo run:android",
|
"android": "expo run:android",
|
||||||
"ios": "expo run:ios",
|
"ios": "expo run:ios",
|
||||||
"web": "expo start --web",
|
"web": "expo start --web",
|
||||||
"db:generate": "drizzle-kit generate",
|
"clean": "rm -rf .expo ios android node_modules && npm i",
|
||||||
"prebuild": "expo prebuild && npm run eas-build-post-install",
|
"db:generate": "drizzle-kit generate",
|
||||||
"prebuild:clean": "expo prebuild --clean && npm run eas-build-post-install",
|
"prebuild": "expo prebuild && npm run eas-build-post-install",
|
||||||
"eas-build-post-install": "node scripts/add-sentry-watch.js",
|
"prebuild:clean": "expo prebuild --clean && npm run eas-build-post-install",
|
||||||
"build:wearos:debug": "./scripts/build-wearos.sh debug",
|
"eas-build-post-install": "node scripts/add-sentry-watch.js",
|
||||||
"build:wearos:release": "./scripts/build-wearos.sh release",
|
"build:wearos:debug": "./scripts/build-wearos.sh debug",
|
||||||
"deploy:ios": "eas build --platform ios --profile ${1:-preview} && eas submit --platform ios --profile ${1:-preview}",
|
"build:wearos:release": "./scripts/build-wearos.sh release",
|
||||||
"deploy:android": "eas build --platform android --profile ${1:-preview} && eas submit --platform android --profile ${1:-preview}",
|
"deploy:ios": "eas build --platform ios --profile ${1:-preview} && eas submit --platform ios --profile ${1:-preview}",
|
||||||
"deploy:wearos": "./scripts/build-wearos.sh release ${2:-}",
|
"deploy:android": "eas build --platform android --profile ${1:-preview} && eas submit --platform android --profile ${1:-preview}",
|
||||||
"update": "eas update --branch ${1:-preview}",
|
"deploy:wearos": "./scripts/build-wearos.sh release ${2:-}",
|
||||||
"update:production": "eas update --branch production"
|
"update": "eas update --branch ${1:-preview}",
|
||||||
},
|
"update:production": "eas update --branch production"
|
||||||
"private": true,
|
},
|
||||||
"overrides": {
|
"private": true,
|
||||||
"lightningcss": "1.30.1"
|
"overrides": {
|
||||||
}
|
"lightningcss": "1.30.1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -253,7 +253,9 @@ export async function deleteSession(sessionId: string) {
|
|||||||
|
|
||||||
export async function deleteSessionAndSync(sessionId: string) {
|
export async function deleteSessionAndSync(sessionId: string) {
|
||||||
await deleteSession(sessionId);
|
await deleteSession(sessionId);
|
||||||
await WatchConnectivity.sendWorkoutDeleted(sessionId);
|
WatchConnectivity.sendWorkoutDeleted(sessionId).catch((err) =>
|
||||||
|
console.warn("[ops] sync failed:", err)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteWorkout(id: string) {
|
export async function deleteWorkout(id: string) {
|
||||||
@@ -272,7 +274,9 @@ export async function deleteWorkout(id: string) {
|
|||||||
|
|
||||||
export async function deleteWorkoutAndSync(id: string) {
|
export async function deleteWorkoutAndSync(id: string) {
|
||||||
await deleteWorkout(id);
|
await deleteWorkout(id);
|
||||||
await WatchConnectivity.sendWorkoutDeleted(id);
|
WatchConnectivity.sendWorkoutDeleted(id).catch((err) =>
|
||||||
|
console.warn("[ops] sync failed:", err)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Stats ───────────────────────────────────────────────────
|
// ─── Stats ───────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export function HistoryScreen() {
|
|||||||
style: "destructive",
|
style: "destructive",
|
||||||
onPress: async () => {
|
onPress: async () => {
|
||||||
await deleteSessionAndSync(id);
|
await deleteSessionAndSync(id);
|
||||||
await loadSessions();
|
setSessions((prev) => prev.filter((s) => s.id !== id));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export function WorkoutListScreen() {
|
|||||||
style: "destructive",
|
style: "destructive",
|
||||||
onPress: async () => {
|
onPress: async () => {
|
||||||
await deleteWorkoutAndSync(id);
|
await deleteWorkoutAndSync(id);
|
||||||
await loadWorkouts();
|
setWorkouts((prev) => prev.filter((w) => w.id !== id));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ WatchConnectivity = requireOptionalNativeModule("WatchConnectivity") ?? {
|
|||||||
isReachable: async () => false,
|
isReachable: async () => false,
|
||||||
sendWorkoutPlan: async () => ({ error: "WatchConnectivity native module not available" }),
|
sendWorkoutPlan: async () => ({ error: "WatchConnectivity native module not available" }),
|
||||||
sendWorkoutCompletion: 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 () => [],
|
pollEvents: async () => [],
|
||||||
getApplicationContext: async () => null,
|
getApplicationContext: async () => null,
|
||||||
updateApplicationContext: async () => {},
|
updateApplicationContext: async () => {},
|
||||||
|
|||||||
Reference in New Issue
Block a user