mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-07-15 00:43:08 +01:00
fix: network location settings
Fixed android location settings for wifi network connections as didn't exist Added some better wording to assist Signed-off-by: Lance Chant <13349722+lancechant@users.noreply.github.com>
This commit is contained in:
@@ -18,6 +18,7 @@ interface ServerUrlContextValue {
|
||||
effectiveServerUrl: string | null;
|
||||
isUsingLocalUrl: boolean;
|
||||
currentSSID: string | null;
|
||||
connectedToWifi: boolean;
|
||||
refreshUrlState: () => void;
|
||||
}
|
||||
|
||||
@@ -32,7 +33,7 @@ interface Props {
|
||||
export function ServerUrlProvider({ children }: Props): React.ReactElement {
|
||||
const api = useAtomValue(apiAtom);
|
||||
const { switchServerUrl } = useJellyfin();
|
||||
const { ssid, permissionStatus } = useWifiSSID();
|
||||
const { ssid, connectedToWifi, permissionStatus } = useWifiSSID();
|
||||
|
||||
const [isUsingLocalUrl, setIsUsingLocalUrl] = useState(false);
|
||||
const [effectiveServerUrl, setEffectiveServerUrl] = useState<string | null>(
|
||||
@@ -107,6 +108,7 @@ export function ServerUrlProvider({ children }: Props): React.ReactElement {
|
||||
effectiveServerUrl,
|
||||
isUsingLocalUrl,
|
||||
currentSSID: ssid,
|
||||
connectedToWifi,
|
||||
refreshUrlState,
|
||||
}}
|
||||
>
|
||||
|
||||
153
providers/WifiSsidProvider.tsx
Normal file
153
providers/WifiSsidProvider.tsx
Normal file
@@ -0,0 +1,153 @@
|
||||
import type React from "react";
|
||||
import {
|
||||
createContext,
|
||||
type ReactNode,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
} from "react";
|
||||
import { Platform } from "react-native";
|
||||
import { getSSID } from "@/modules/wifi-ssid";
|
||||
|
||||
export type PermissionStatus =
|
||||
| "granted"
|
||||
| "denied"
|
||||
| "undetermined"
|
||||
| "unavailable";
|
||||
|
||||
export interface UseWifiSSIDReturn {
|
||||
ssid: string | null;
|
||||
connectedToWifi: boolean;
|
||||
permissionStatus: PermissionStatus;
|
||||
requestPermission: () => Promise<boolean>;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
const WifiSsidContext = createContext<UseWifiSSIDReturn | null>(null);
|
||||
|
||||
// WiFi SSID is not available on tvOS, and expo-location isn't needed there.
|
||||
const Location = Platform.isTV ? null : require("expo-location");
|
||||
|
||||
const POLL_INTERVAL_MS = 10_000;
|
||||
|
||||
function mapLocationStatus(status: number | undefined): PermissionStatus {
|
||||
if (!Location) return "unavailable";
|
||||
switch (status) {
|
||||
case Location.PermissionStatus?.GRANTED:
|
||||
return "granted";
|
||||
case Location.PermissionStatus?.DENIED:
|
||||
return "denied";
|
||||
default:
|
||||
return "undetermined";
|
||||
}
|
||||
}
|
||||
|
||||
interface Props {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Single source of truth for the current WiFi SSID and the location permission
|
||||
* that gates it. State is shared via context so that granting permission in one
|
||||
* place (e.g. the network settings screen) is reflected everywhere else — most
|
||||
* importantly ServerUrlProvider, which switches between the local and remote
|
||||
* server URLs based on the connected SSID.
|
||||
*
|
||||
* Previously each consumer created its own useWifiSSID instance with independent
|
||||
* state, so the provider never learned that permission had been granted later
|
||||
* in the session and reported "not connected to WiFi" forever.
|
||||
*/
|
||||
export function WifiSsidProvider({ children }: Props): React.ReactElement {
|
||||
const [ssid, setSSID] = useState<string | null>(null);
|
||||
const [connectedToWifi, setConnectedToWifi] = useState(false);
|
||||
const [permissionStatus, setPermissionStatus] = useState<PermissionStatus>(
|
||||
Platform.isTV ? "unavailable" : "undetermined",
|
||||
);
|
||||
const [isLoading, setIsLoading] = useState(!Platform.isTV);
|
||||
|
||||
const fetchSSID = useCallback(async () => {
|
||||
if (Platform.isTV) return;
|
||||
const result = await getSSID();
|
||||
setSSID(result.ssid);
|
||||
setConnectedToWifi(result.connectedToWifi);
|
||||
}, []);
|
||||
|
||||
const requestPermission = useCallback(async (): Promise<boolean> => {
|
||||
if (Platform.isTV || !Location) {
|
||||
setPermissionStatus("unavailable");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const { status } = await Location.requestForegroundPermissionsAsync();
|
||||
const newStatus = mapLocationStatus(status);
|
||||
setPermissionStatus(newStatus);
|
||||
return newStatus === "granted";
|
||||
} catch {
|
||||
setPermissionStatus("unavailable");
|
||||
return false;
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Check the location permission once on mount. The poll effect below takes
|
||||
// over fetching the SSID whenever permission becomes "granted".
|
||||
useEffect(() => {
|
||||
if (Platform.isTV || !Location) {
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
async function initialize() {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const { status } = await Location.getForegroundPermissionsAsync();
|
||||
if (cancelled) return;
|
||||
setPermissionStatus(mapLocationStatus(status));
|
||||
} catch {
|
||||
if (!cancelled) setPermissionStatus("unavailable");
|
||||
}
|
||||
if (!cancelled) setIsLoading(false);
|
||||
}
|
||||
|
||||
initialize();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Fetch the SSID immediately, then poll, whenever permission is granted.
|
||||
// Because permissionStatus is shared, this also covers the case where
|
||||
// permission was granted later (from another consumer) than this provider's
|
||||
// mount time — the original root cause of the "not connected to WiFi" bug.
|
||||
useEffect(() => {
|
||||
if (Platform.isTV || permissionStatus !== "granted") return;
|
||||
|
||||
fetchSSID();
|
||||
const interval = setInterval(fetchSSID, POLL_INTERVAL_MS);
|
||||
return () => clearInterval(interval);
|
||||
}, [permissionStatus, fetchSSID]);
|
||||
|
||||
return (
|
||||
<WifiSsidContext.Provider
|
||||
value={{
|
||||
ssid,
|
||||
connectedToWifi,
|
||||
permissionStatus,
|
||||
requestPermission,
|
||||
isLoading,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</WifiSsidContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useWifiSsid(): UseWifiSSIDReturn {
|
||||
const context = useContext(WifiSsidContext);
|
||||
if (!context) {
|
||||
throw new Error("useWifiSsid must be used within WifiSsidProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
Reference in New Issue
Block a user