mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
fix(connection): ignore spurious navigator.onLine offline hint in Tauri (#1234)
This commit is contained in:
@@ -4,11 +4,12 @@ import {
|
||||
} from '@/store/devOfflineBrowseStore';
|
||||
import { useConnectionStatus } from '@/lib/hooks/useConnectionStatus';
|
||||
import { isActiveServerReachable } from '@/lib/network/activeServerReachability';
|
||||
import { isNavigatorOfflineHint } from '@/lib/network/navigatorOnlineHint';
|
||||
|
||||
/** True when browse/detail pages should use local-bytes-only data sources. */
|
||||
export function isOfflineBrowseActive(): boolean {
|
||||
if (isDevOfflineBrowseForced()) return true;
|
||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return true;
|
||||
if (isNavigatorOfflineHint()) return true;
|
||||
return !isActiveServerReachable();
|
||||
}
|
||||
|
||||
@@ -22,6 +23,6 @@ export function useOfflineBrowseActive(): boolean {
|
||||
useConnectionStatus();
|
||||
|
||||
if (import.meta.env.DEV && devForceOffline) return true;
|
||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return true;
|
||||
if (isNavigatorOfflineHint()) return true;
|
||||
return !isActiveServerReachable();
|
||||
}
|
||||
|
||||
@@ -11,6 +11,10 @@ vi.mock('@/lib/api/subsonicStarRating', () => ({
|
||||
|
||||
import { usePlayerStore } from '@/features/playback/store/playerStore';
|
||||
import type { Track } from '@/lib/media/trackTypes';
|
||||
import {
|
||||
resetActiveServerConnectionSnapshot,
|
||||
setActiveServerReachable,
|
||||
} from '@/lib/network/activeServerReachability';
|
||||
import { queueSongStar, queueSongRating, _resetPendingStarSyncForTest } from '@/features/playback/store/pendingStarSync';
|
||||
import {
|
||||
getCachedTrack,
|
||||
@@ -26,6 +30,8 @@ const track = (id: string): Track => ({
|
||||
describe('pendingStarSync', () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers();
|
||||
resetActiveServerConnectionSnapshot();
|
||||
setActiveServerReachable(true);
|
||||
starMock.mockReset().mockResolvedValue(undefined);
|
||||
unstarMock.mockReset().mockResolvedValue(undefined);
|
||||
setRatingMock.mockReset().mockResolvedValue(undefined);
|
||||
@@ -75,6 +81,19 @@ describe('pendingStarSync', () => {
|
||||
expect(usePlayerStore.getState().starredOverrides.t1).toBe(true); // override survives (no rollback)
|
||||
});
|
||||
|
||||
it('flushes pending stars when the active server becomes reachable', async () => {
|
||||
starMock.mockRejectedValue(new Error('offline'));
|
||||
queueSongStar('t1', true);
|
||||
await vi.advanceTimersByTimeAsync(0);
|
||||
expect(starMock).toHaveBeenCalledTimes(1);
|
||||
|
||||
setActiveServerReachable(false);
|
||||
setActiveServerReachable(true);
|
||||
await vi.advanceTimersByTimeAsync(0);
|
||||
|
||||
expect(starMock.mock.calls.length).toBeGreaterThan(1);
|
||||
});
|
||||
|
||||
it('passes serverId through to star/unstar for cross-server favorites', async () => {
|
||||
queueSongStar('t1', true, 'srv-b');
|
||||
await vi.runAllTimersAsync();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { setRating, star, unstar } from '@/lib/api/subsonicStarRating';
|
||||
import { usePlayerStore } from '@/features/playback/store/playerStore';
|
||||
import { patchCachedTrack } from '@/features/playback/store/queueTrackResolver';
|
||||
import { onActiveServerBecameReachable } from '@/lib/network/activeServerReachability';
|
||||
|
||||
/**
|
||||
* F4 — pending-sync for **song** star + rating (spec §6.5 / R7-18).
|
||||
@@ -11,7 +12,8 @@ import { patchCachedTrack } from '@/features/playback/store/queueTrackResolver';
|
||||
*
|
||||
* 1. Set the override optimistically (instant UI).
|
||||
* 2. Retry the Subsonic API (`star` / `unstar` / `setRating`) with exponential
|
||||
* backoff; flush immediately on `online` / window focus.
|
||||
* backoff; flush immediately when the active server becomes reachable again
|
||||
* (`onActiveServerBecameReachable`) or on window focus.
|
||||
* 3. On **star** success: KEEP the override — list views read it — and patch
|
||||
* the in-memory `Track`. F3 index patch-on-use runs in the API layer.
|
||||
* (Ratings clear on success; see `onRatingSuccess`.)
|
||||
@@ -42,8 +44,8 @@ function armListeners(): void {
|
||||
const flushAll = () => {
|
||||
for (const k of pending.keys()) schedule(k, 0);
|
||||
};
|
||||
window.addEventListener('online', flushAll);
|
||||
window.addEventListener('focus', flushAll);
|
||||
onActiveServerBecameReachable(flushAll);
|
||||
}
|
||||
|
||||
function schedule(k: string, delayMs: number): void {
|
||||
|
||||
Reference in New Issue
Block a user