chore(fullscreen): drop ts-expect-error, type ctx + NewState properly

useServices is already typed via src/services/ServicesContext/useServices.d.ts,
so the @ts-expect-error suppression on the import was unnecessary and
masked two real type holes that surfaced once it was removed:

- core.transport.getState('ctx') returns Promise<object>; cast to the
  ambient Ctx type so escExitFullscreen is read through a typed path.
- CoreTransport.on/off types listeners as () => void, but the 'NewState'
  event actually emits a string[]. Use a (...args: unknown[]) wrapper +
  Array.isArray narrowing so the call site stays type-safe without
  weakening the ambient transport signature.

No behavior change.

Made-with: Cursor
This commit is contained in:
AK 2026-04-28 00:57:53 -04:00
parent 2e13a60007
commit 90e2cbff15

View file

@ -1,7 +1,6 @@
// Copyright (C) 2017-2023 Smart code 203358507 // Copyright (C) 2017-2023 Smart code 203358507
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
// @ts-expect-error JS module without types
import { useServices } from 'stremio/services'; import { useServices } from 'stremio/services';
import useShell, { type WindowVisibility } from '../useShell'; import useShell, { type WindowVisibility } from '../useShell';
import FullscreenContext, { type FullscreenContextValue } from './FullscreenContext'; import FullscreenContext, { type FullscreenContextValue } from './FullscreenContext';
@ -63,7 +62,7 @@ const FullscreenProvider = ({ children }: Props) => {
let cancelled = false; let cancelled = false;
const refreshSettings = async () => { const refreshSettings = async () => {
try { try {
const ctx = await core.transport.getState('ctx'); const ctx = await core.transport.getState('ctx') as Ctx | null;
if (!cancelled) { if (!cancelled) {
escExitFullscreenRef.current = !!ctx?.profile?.settings?.escExitFullscreen; escExitFullscreenRef.current = !!ctx?.profile?.settings?.escExitFullscreen;
} }
@ -72,7 +71,11 @@ const FullscreenProvider = ({ children }: Props) => {
} }
}; };
const onNewState = (models: string[]) => { // CoreTransport.on types the listener as () => void, but the 'NewState'
// event actually emits a string[] of changed model names. Read it via
// a rest-args wrapper to stay compatible with the ambient signature.
const onNewState = (...args: unknown[]) => {
const models = args[0];
if (Array.isArray(models) && models.indexOf('ctx') !== -1) { if (Array.isArray(models) && models.indexOf('ctx') !== -1) {
refreshSettings(); refreshSettings();
} }