feat(watch-connectivity): add WearOS support alongside Apple Watch
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { useState } from "react";
|
||||
import { Platform } from "react-native";
|
||||
import WatchConnectivity from "../../../modules/watch-connectivity";
|
||||
import WearConnectivity from "../../../modules/wear-connectivity";
|
||||
import type { WorkoutSet } from "@types/workout";
|
||||
|
||||
type SyncResult = { status: string } | { error: string };
|
||||
@@ -15,20 +17,6 @@ export function useSyncWorkout() {
|
||||
): Promise<SyncResult> => {
|
||||
setIsSyncing(true);
|
||||
try {
|
||||
console.log("[useSyncWorkout] Checking module availability...");
|
||||
|
||||
const supported = await WatchConnectivity.isSupported();
|
||||
console.log("[useSyncWorkout] isSupported:", supported);
|
||||
|
||||
const paired = await WatchConnectivity.isPaired();
|
||||
console.log("[useSyncWorkout] isPaired:", paired);
|
||||
|
||||
const installed = await WatchConnectivity.isWatchAppInstalled();
|
||||
console.log("[useSyncWorkout] isWatchAppInstalled:", installed);
|
||||
|
||||
const reachable = await WatchConnectivity.isReachable();
|
||||
console.log("[useSyncWorkout] isReachable:", reachable);
|
||||
|
||||
const plan = {
|
||||
id: workoutId,
|
||||
name: name ?? "Workout",
|
||||
@@ -39,16 +27,37 @@ export function useSyncWorkout() {
|
||||
repCount: s.repCount,
|
||||
restType: s.restType,
|
||||
restDuration: s.restDuration,
|
||||
targetTime: s.targetTime ?? null,
|
||||
...(s.targetTime != null ? { targetTime: s.targetTime } : {}),
|
||||
})),
|
||||
};
|
||||
|
||||
console.log("[useSyncWorkout] Sending plan:", JSON.stringify(plan).slice(0, 200));
|
||||
const result = await WatchConnectivity.sendWorkoutPlan(plan);
|
||||
console.log("[useSyncWorkout] Result:", JSON.stringify(result));
|
||||
return result as SyncResult;
|
||||
if (Platform.OS === "ios") {
|
||||
const supported = await WatchConnectivity.isSupported();
|
||||
const paired = await WatchConnectivity.isPaired();
|
||||
const installed = await WatchConnectivity.isWatchAppInstalled();
|
||||
const reachable = await WatchConnectivity.isReachable();
|
||||
|
||||
if (!supported || !paired || !installed) {
|
||||
return { error: "Apple Watch not available" };
|
||||
}
|
||||
|
||||
const result = await WatchConnectivity.sendWorkoutPlan(plan);
|
||||
return result as SyncResult;
|
||||
} else if (Platform.OS === "android") {
|
||||
const supported = await WearConnectivity.isSupported();
|
||||
const paired = await WearConnectivity.isPaired();
|
||||
const reachable = await WearConnectivity.isReachable();
|
||||
|
||||
if (!supported || !paired) {
|
||||
return { error: "WearOS watch not available" };
|
||||
}
|
||||
|
||||
const result = await WearConnectivity.sendWorkoutPlan(plan);
|
||||
return result as SyncResult;
|
||||
}
|
||||
|
||||
return { error: "Platform not supported" };
|
||||
} catch (error: any) {
|
||||
console.log("[useSyncWorkout] Error:", error.message, error.code);
|
||||
return { error: error.message ?? "Failed to sync" };
|
||||
} finally {
|
||||
setIsSyncing(false);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { Platform } from "react-native";
|
||||
import WatchConnectivity from "../../../modules/watch-connectivity";
|
||||
import WearConnectivity from "../../../modules/wear-connectivity";
|
||||
|
||||
type WatchConnectionStatus = "connected" | "disconnected" | "pending";
|
||||
|
||||
@@ -16,19 +18,36 @@ export function useWatchConnection() {
|
||||
|
||||
const checkStatus = async () => {
|
||||
try {
|
||||
const supported = await WatchConnectivity.isSupported();
|
||||
if (!supported) {
|
||||
if (Platform.OS === "ios") {
|
||||
const supported = await WatchConnectivity.isSupported();
|
||||
if (!supported) {
|
||||
setStatus("disconnected");
|
||||
return;
|
||||
}
|
||||
|
||||
const paired = await WatchConnectivity.isPaired();
|
||||
const installed = await WatchConnectivity.isWatchAppInstalled();
|
||||
const reachable = await WatchConnectivity.isReachable();
|
||||
|
||||
setIsPaired(paired);
|
||||
setIsInstalled(installed);
|
||||
setStatus(reachable ? "connected" : paired ? "disconnected" : "disconnected");
|
||||
} else if (Platform.OS === "android") {
|
||||
const supported = await WearConnectivity.isSupported();
|
||||
if (!supported) {
|
||||
setStatus("disconnected");
|
||||
return;
|
||||
}
|
||||
|
||||
const paired = await WearConnectivity.isPaired();
|
||||
const reachable = await WearConnectivity.isReachable();
|
||||
|
||||
setIsPaired(paired);
|
||||
setIsInstalled(paired); // WearOS doesn't have a separate install check
|
||||
setStatus(reachable ? "connected" : paired ? "disconnected" : "disconnected");
|
||||
} else {
|
||||
setStatus("disconnected");
|
||||
return;
|
||||
}
|
||||
|
||||
const paired = await WatchConnectivity.isPaired();
|
||||
const installed = await WatchConnectivity.isWatchAppInstalled();
|
||||
const reachable = await WatchConnectivity.isReachable();
|
||||
|
||||
setIsPaired(paired);
|
||||
setIsInstalled(installed);
|
||||
setStatus(reachable ? "connected" : paired ? "disconnected" : "disconnected");
|
||||
} catch {
|
||||
setStatus("disconnected");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { Platform } from "react-native";
|
||||
import WatchConnectivity from "../../../modules/watch-connectivity";
|
||||
import WearConnectivity from "../../../modules/wear-connectivity";
|
||||
import { saveWatchCompletedWorkout } from "@db/operations";
|
||||
|
||||
export function useWatchWorkoutSync() {
|
||||
@@ -8,10 +10,16 @@ export function useWatchWorkoutSync() {
|
||||
useEffect(() => {
|
||||
pollingRef.current = setInterval(async () => {
|
||||
try {
|
||||
const events = (await WatchConnectivity.pollEvents()) as any[];
|
||||
let events: any[] = [];
|
||||
|
||||
if (Platform.OS === "ios") {
|
||||
events = (await WatchConnectivity.pollEvents()) as any[];
|
||||
} else if (Platform.OS === "android") {
|
||||
events = (await WearConnectivity.pollEvents()) as any[];
|
||||
}
|
||||
|
||||
for (const event of events) {
|
||||
if (event.type === "workoutCompleted") {
|
||||
console.log("[useWatchWorkoutSync] Received workoutCompleted:", event.workoutId);
|
||||
await saveWatchCompletedWorkout({
|
||||
workoutId: event.workoutId,
|
||||
duration: event.duration ?? 0,
|
||||
@@ -19,7 +27,6 @@ export function useWatchWorkoutSync() {
|
||||
calories: event.calories ?? 0,
|
||||
laps: event.laps ?? [],
|
||||
});
|
||||
console.log("[useWatchWorkoutSync] Saved completed workout to DB");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user