feat(sync-play): squash feature/sync-play

This commit is contained in:
Alex Kim
2026-05-31 19:03:03 +10:00
parent ed7928b4d3
commit d06daef933
25 changed files with 4889 additions and 136 deletions

View File

@@ -4,11 +4,16 @@ import { Platform, TouchableOpacity, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Text } from "@/components/common/Text";
import { Loader } from "@/components/Loader";
import { SyncPlaySpinner } from "@/components/syncplay/SyncPlaySpinner";
import { useSyncPlay } from "@/providers/SyncPlay/SyncPlayProvider";
import { useSettings } from "@/utils/atoms/settings";
import AudioSlider from "./AudioSlider";
import BrightnessSlider from "./BrightnessSlider";
import { ICON_SIZES } from "./constants";
// SyncPlay cyan color (matches Jellyfin-web)
const SYNC_PLAY_COLOR = "#00a4dc";
interface CenterControlsProps {
showControls: boolean;
isPlaying: boolean;
@@ -44,6 +49,18 @@ export const CenterControls: FC<CenterControlsProps> = ({
const { settings } = useSettings();
const insets = useSafeAreaInsets();
// SyncPlay state from global provider
const {
isEnabled: isSyncPlayEnabled,
groupInfo,
pendingPlaybackCommand,
} = useSyncPlay();
const isSyncPlayWaiting = isSyncPlayEnabled && groupInfo?.State === "Waiting";
// Show the rotating SyncPlay icon ("schedule-play" in jellyfin-web) while a
// play/pause request is in flight to the server.
const isSyncPlayScheduling =
isSyncPlayEnabled && pendingPlaybackCommand !== null;
return (
<View
style={{
@@ -121,7 +138,17 @@ export const CenterControls: FC<CenterControlsProps> = ({
<View style={Platform.isTV ? { flex: 1, alignItems: "center" } : {}}>
<TouchableOpacity onPress={togglePlay}>
{!isBuffering ? (
{isSyncPlayScheduling ? (
// SyncPlay command in flight - rotating spinner ("schedule-play")
<SyncPlaySpinner size={ICON_SIZES.CENTER} />
) : isSyncPlayWaiting ? (
// SyncPlay waiting indicator - clock icon, still pressable to toggle
<Ionicons
name='time'
size={ICON_SIZES.CENTER}
color={SYNC_PLAY_COLOR}
/>
) : !isBuffering ? (
<Ionicons
name={isPlaying ? "pause" : "play"}
size={ICON_SIZES.CENTER}