Merge pull request #694 from Stremio/refactor/unite-platform-logic

refactor: logic unite
This commit is contained in:
Tim 2024-09-27 11:27:07 +02:00 committed by GitHub
commit 02b9b5b435
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 53 additions and 54 deletions

View file

@ -1,15 +1,18 @@
import React, { createContext, useContext } from 'react';
import useShell from './useShell';
import { WHITELISTED_HOSTS } from 'stremio/common/CONSTANTS';
import useShell from './useShell';
import { name, isMobile } from './device';
interface PlatformContext {
openExternal: (url: string) => void,
};
name: string;
isMobile: boolean;
openExternal: (url: string) => void;
}
const PlatformContext = createContext<PlatformContext | null>(null);
type Props = {
children: JSX.Element,
children: JSX.Element;
};
const PlatformProvider = ({ children }: Props) => {
@ -19,8 +22,8 @@ const PlatformProvider = ({ children }: Props) => {
try {
const { hostname } = new URL(url);
const isWhitelisted = WHITELISTED_HOSTS.some((host: string) => hostname.endsWith(host));
const finalUrl = !isWhitelisted ? 'https://www.stremio.com/warning#' + encodeURIComponent(url) : url;
const finalUrl = !isWhitelisted ? `https://www.stremio.com/warning#${encodeURIComponent(url)}` : url;
if (shell.active) {
shell.send('open-external', finalUrl);
} else {
@ -28,11 +31,11 @@ const PlatformProvider = ({ children }: Props) => {
}
} catch (e) {
console.error('Failed to parse external url:', e);
}
}
};
return (
<PlatformContext.Provider value={{ openExternal }}>
<PlatformContext.Provider value={{ openExternal, name, isMobile }}>
{children}
</PlatformContext.Provider>
);
@ -42,7 +45,7 @@ const usePlatform = () => {
return useContext(PlatformContext);
};
export {
export {
PlatformProvider,
usePlatform,
usePlatform
};

View file

@ -0,0 +1,31 @@
import Bowser from 'bowser';
const APPLE_MOBILE_DEVICES = [
'iPad Simulator',
'iPhone Simulator',
'iPod Simulator',
'iPad',
'iPhone',
'iPod',
];
const { userAgent, platform, maxTouchPoints } = globalThis.navigator;
// this detects ipad properly in safari
// while bowser does not
const isIOS = APPLE_MOBILE_DEVICES.includes(platform) || (userAgent.includes('Mac') && 'ontouchend' in document);
// Edge case: iPad is included in this function
// Keep in mind maxTouchPoints for Vision Pro might change in the future
const isVisionOS = userAgent.includes('Macintosh') || maxTouchPoints === 5;
const bowser = Bowser.getParser(userAgent);
const os = bowser.getOSName().toLowerCase();
const name = isVisionOS ? 'visionos' : isIOS ? 'ios' : os || 'unknown';
const isMobile = ['ios', 'android'].includes(name);
export {
name,
isMobile,
};

View file

@ -46,7 +46,6 @@ const useProfile = require('./useProfile');
const useStreamingServer = require('./useStreamingServer');
const useTorrent = require('./useTorrent');
const useTranslate = require('./useTranslate');
const platform = require('./platform');
const EventModal = require('./EventModal');
module.exports = {
@ -101,6 +100,5 @@ module.exports = {
useStreamingServer,
useTorrent,
useTranslate,
platform,
EventModal,
};

View file

@ -1,36 +0,0 @@
// Copyright (C) 2017-2024 Smart code 203358507
// this detects ipad properly in safari
// while bowser does not
const iOS = () => {
return [
'iPad Simulator',
'iPhone Simulator',
'iPod Simulator',
'iPad',
'iPhone',
'iPod'
].includes(navigator.platform)
|| (navigator.userAgent.includes('Mac') && 'ontouchend' in document);
};
const Bowser = require('bowser');
const browser = Bowser.parse(window.navigator?.userAgent || '');
// Edge case: iPad is included in this function
// Keep in mind maxTouchPoints for Vision Pro might change in the future
const isVisionProUser = () => {
const isMacintosh = navigator.userAgent.includes('Macintosh');
const hasFiveTouchPoints = navigator.maxTouchPoints === 5;
return isMacintosh && hasFiveTouchPoints;
};
const name = isVisionProUser() ? 'visionos' : (iOS() ? 'ios' : (browser?.os?.name || 'unknown').toLowerCase());
module.exports = {
name,
isMobile: () => {
return name === 'ios' || name === 'android';
}
};

View file

@ -5,7 +5,7 @@ const PropTypes = require('prop-types');
const classnames = require('classnames');
const { default: Icon } = require('@stremio/stremio-icons/react');
const { t } = require('i18next');
const { Button, Image, useProfile, platform, useToast, Popup, useBinaryState } = require('stremio/common');
const { Button, Image, useProfile, usePlatform, useToast, Popup, useBinaryState } = require('stremio/common');
const { useServices } = require('stremio/services');
const { useRouteFocused } = require('stremio-router');
const StreamPlaceholder = require('./StreamPlaceholder');
@ -14,6 +14,7 @@ const styles = require('./styles');
const Stream = ({ className, videoId, videoReleased, addonName, name, description, thumbnail, progress, deepLinks, ...props }) => {
const profile = useProfile();
const toast = useToast();
const platform = usePlatform();
const { core } = useServices();
const routeFocused = useRouteFocused();

View file

@ -11,7 +11,6 @@ const { Button, Checkbox, MainNavBars, Multiselect, ColorInput, TextInput, Modal
const useProfileSettingsInputs = require('./useProfileSettingsInputs');
const useStreamingServerSettingsInputs = require('./useStreamingServerSettingsInputs');
const useDataExport = require('./useDataExport');
const { name: platformName } = require('stremio/common/platform');
const styles = require('./styles');
const GENERAL_SECTION = 'general';
@ -104,16 +103,18 @@ const Settings = () => {
}
}, [isTraktAuthenticated, profile.auth]);
const subscribeCalendarOnClick = React.useCallback(() => {
const protocol = platformName === 'ios' ? 'webcal' : 'https';
if (!profile.auth) return;
const protocol = platform.name === 'ios' ? 'webcal' : 'https';
const url = `${protocol}://www.strem.io/calendar/${profile.auth.user._id}.ics`;
platform.openExternal(url);
toast.show({
type: 'success',
title: platformName === 'ios' ? t('SETTINGS_SUBSCRIBE_CALENDAR_IOS_TOAST') : t('SETTINGS_SUBSCRIBE_CALENDAR_TOAST'),
title: platform.name === 'ios' ? t('SETTINGS_SUBSCRIBE_CALENDAR_IOS_TOAST') : t('SETTINGS_SUBSCRIBE_CALENDAR_TOAST'),
timeout: 25000
});
// Stremio 4 emits not documented event subscribeCalendar
}, [profile.auth.user._id]);
}, [profile.auth]);
const exportDataOnClick = React.useCallback(() => {
loadDataExport();
}, []);

View file

@ -3,11 +3,12 @@
const React = require('react');
const { useTranslation } = require('react-i18next');
const { useServices } = require('stremio/services');
const { CONSTANTS, interfaceLanguages, languageNames, platform } = require('stremio/common');
const { CONSTANTS, usePlatform, interfaceLanguages, languageNames } = require('stremio/common');
const useProfileSettingsInputs = (profile) => {
const { t } = useTranslation();
const { core } = useServices();
const platform = usePlatform();
// TODO combine those useMemo in one
const interfaceLanguageSelect = React.useMemo(() => ({
options: interfaceLanguages.map(({ name, codes }) => ({