mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-11 21:27:05 +00:00
Merge branch 'development' of https://github.com/Stremio/stremio-web into feat/player-local-subtitles
This commit is contained in:
commit
02d3c421bc
42 changed files with 486 additions and 237 deletions
12
package-lock.json
generated
12
package-lock.json
generated
|
|
@ -1,18 +1,18 @@
|
|||
{
|
||||
"name": "stremio",
|
||||
"version": "5.0.0-beta.16",
|
||||
"version": "5.0.0-beta.17",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "stremio",
|
||||
"version": "5.0.0-beta.16",
|
||||
"version": "5.0.0-beta.17",
|
||||
"license": "gpl-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "7.26.0",
|
||||
"@sentry/browser": "8.42.0",
|
||||
"@stremio/stremio-colors": "5.2.0",
|
||||
"@stremio/stremio-core-web": "0.48.4",
|
||||
"@stremio/stremio-core-web": "0.48.5",
|
||||
"@stremio/stremio-icons": "5.4.1",
|
||||
"@stremio/stremio-video": "0.0.53",
|
||||
"a-color-picker": "1.2.1",
|
||||
|
|
@ -3371,9 +3371,9 @@
|
|||
"integrity": "sha512-dYlPgu9W/H7c9s1zmW5tiDnRenaUa4Hg1QCyOg1lhOcgSfM/bVTi5nnqX+IfvGTTUNA0zgzh8hI3o3miwnZxTg=="
|
||||
},
|
||||
"node_modules/@stremio/stremio-core-web": {
|
||||
"version": "0.48.4",
|
||||
"resolved": "https://registry.npmjs.org/@stremio/stremio-core-web/-/stremio-core-web-0.48.4.tgz",
|
||||
"integrity": "sha512-848OLm0dtP75aAlYhUB0KoOqwosJIj+ubB8/abuaAzH/N3dtxs40vu2AezmMpGjwR4V60rlOUkUZeWFvrUOjrw==",
|
||||
"version": "0.48.5",
|
||||
"resolved": "https://registry.npmjs.org/@stremio/stremio-core-web/-/stremio-core-web-0.48.5.tgz",
|
||||
"integrity": "sha512-oDTNBrv8zZi1VGbeV+1Bm6CliI2rF23ERdJpz+gv8EnbFjRIo78WIsoS0yO0EOg8HHXYsFytPq5+c0+YlxmBlA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "7.24.1"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "stremio",
|
||||
"displayName": "Stremio",
|
||||
"version": "5.0.0-beta.16",
|
||||
"version": "5.0.0-beta.17",
|
||||
"author": "Smart Code OOD",
|
||||
"private": true,
|
||||
"license": "gpl-2.0",
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
"@babel/runtime": "7.26.0",
|
||||
"@sentry/browser": "8.42.0",
|
||||
"@stremio/stremio-colors": "5.2.0",
|
||||
"@stremio/stremio-core-web": "0.48.4",
|
||||
"@stremio/stremio-core-web": "0.48.5",
|
||||
"@stremio/stremio-icons": "5.4.1",
|
||||
"@stremio/stremio-video": "0.0.53",
|
||||
"a-color-picker": "1.2.1",
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ const { FileDropProvider, PlatformProvider, ToastProvider, TooltipProvider, CONS
|
|||
const ServicesToaster = require('./ServicesToaster');
|
||||
const DeepLinkHandler = require('./DeepLinkHandler');
|
||||
const SearchParamsHandler = require('./SearchParamsHandler');
|
||||
const { default: UpdaterBanner } = require('./UpdaterBanner');
|
||||
const ErrorDialog = require('./ErrorDialog');
|
||||
const withProtectedRoutes = require('./withProtectedRoutes');
|
||||
const routerViewsConfig = require('./routerViewsConfig');
|
||||
|
|
@ -169,6 +170,7 @@ const App = () => {
|
|||
<ServicesToaster />
|
||||
<DeepLinkHandler />
|
||||
<SearchParamsHandler />
|
||||
<UpdaterBanner className={styles['updater-banner-container']} />
|
||||
<RouterWithProtectedRoutes
|
||||
className={styles['router']}
|
||||
viewsConfig={routerViewsConfig}
|
||||
|
|
|
|||
46
src/App/UpdaterBanner/UpdaterBanner.less
Normal file
46
src/App/UpdaterBanner/UpdaterBanner.less
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
.updater-banner {
|
||||
height: 4rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
padding: 0 1rem;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
color: var(--primary-foreground-color);
|
||||
background-color: var(--primary-accent-color);
|
||||
|
||||
.button {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 2.5rem;
|
||||
padding: 0 1rem;
|
||||
border-radius: var(--border-radius);
|
||||
color: var(--primary-background-color);
|
||||
background-color: var(--primary-foreground-color);
|
||||
transition: all 0.1s ease-out;
|
||||
|
||||
&:hover {
|
||||
color: var(--primary-foreground-color);
|
||||
background-color: transparent;
|
||||
box-shadow: inset 0 0 0 0.15rem var(--primary-foreground-color);
|
||||
}
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
height: 4rem;
|
||||
width: 4rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.icon {
|
||||
height: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
50
src/App/UpdaterBanner/UpdaterBanner.tsx
Normal file
50
src/App/UpdaterBanner/UpdaterBanner.tsx
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import Icon from '@stremio/stremio-icons/react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useServices } from 'stremio/services';
|
||||
import { useBinaryState, useShell } from 'stremio/common';
|
||||
import { Button, Transition } from 'stremio/components';
|
||||
import styles from './UpdaterBanner.less';
|
||||
|
||||
type Props = {
|
||||
className: string,
|
||||
};
|
||||
|
||||
const UpdaterBanner = ({ className }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const { shell } = useServices();
|
||||
const shellTransport = useShell();
|
||||
const [visible, show, hide] = useBinaryState(false);
|
||||
|
||||
const onInstallClick = () => {
|
||||
shellTransport.send('autoupdater-notif-clicked');
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
shell.transport && shell.transport.on('autoupdater-show-notif', show);
|
||||
|
||||
return () => {
|
||||
shell.transport && shell.transport.off('autoupdater-show-notif', show);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<Transition when={visible} name={'slide-up'}>
|
||||
<div className={styles['updater-banner']}>
|
||||
<div className={styles['label']}>
|
||||
{ t('UPDATER_TITLE') }
|
||||
</div>
|
||||
<Button className={styles['button']} onClick={onInstallClick}>
|
||||
{ t('UPDATER_INSTALL_BUTTON') }
|
||||
</Button>
|
||||
<Button className={styles['close']} onClick={hide}>
|
||||
<Icon className={styles['icon']} name={'close'} />
|
||||
</Button>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default UpdaterBanner;
|
||||
2
src/App/UpdaterBanner/index.ts
Normal file
2
src/App/UpdaterBanner/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import UpdaterBanner from './UpdaterBanner';
|
||||
export default UpdaterBanner;
|
||||
|
|
@ -23,8 +23,8 @@
|
|||
// HTML sizes
|
||||
@html-width: ~"calc(max(var(--small-viewport-width), var(--dynamic-viewport-width)))";
|
||||
@html-height: ~"calc(max(var(--small-viewport-height), var(--dynamic-viewport-height)))";
|
||||
@html-standalone-width: ~"calc(max(100%, var(--large-viewport-width)))";
|
||||
@html-standalone-height: ~"calc(max(100%, var(--large-viewport-height)))";
|
||||
@html-standalone-width: ~"calc(max(100%, var(--small-viewport-width)))";
|
||||
@html-standalone-height: ~"calc(max(100%, var(--small-viewport-height)))";
|
||||
|
||||
// Safe area insets
|
||||
@safe-area-inset-top: env(safe-area-inset-top, 0rem);
|
||||
|
|
@ -64,7 +64,6 @@
|
|||
--modal-background-color: rgba(15, 13, 32, 1);
|
||||
--outer-glow: 0px 0px 15px rgba(123, 91, 245, 0.37);
|
||||
--border-radius: 0.75rem;
|
||||
--calculated-bottom-safe-inset: @calculated-bottom-safe-inset;
|
||||
--top-overlay-size: @top-overlay-size;
|
||||
--bottom-overlay-size: @bottom-overlay-size;
|
||||
--overlap-size: @overlap-size;
|
||||
|
|
@ -99,6 +98,10 @@
|
|||
@supports (height: 100lvh) and (height: 100svh) {
|
||||
--viewport-height-diff: calc(100lvh - 100svh);
|
||||
}
|
||||
|
||||
@media (display-mode: standalone) {
|
||||
--safe-area-inset-bottom: @calculated-bottom-safe-inset;
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
|
|
@ -174,7 +177,7 @@ html {
|
|||
position: absolute;
|
||||
top: calc(1.2 * var(--horizontal-nav-bar-size) + var(--safe-area-inset-top));
|
||||
right: var(--safe-area-inset-right);
|
||||
bottom: calc(1.2 * var(--horizontal-nav-bar-size) + var(--calculated-bottom-safe-inset, 0rem));
|
||||
bottom: calc(1.2 * var(--horizontal-nav-bar-size) + var(--safe-area-inset-bottom, 0rem));
|
||||
left: auto;
|
||||
z-index: 1;
|
||||
padding: 0 calc(0.5 * var(--horizontal-nav-bar-size));
|
||||
|
|
@ -217,6 +220,14 @@ html {
|
|||
}
|
||||
}
|
||||
|
||||
.updater-banner-container {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.router {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { createContext, useContext } from 'react';
|
||||
import { WHITELISTED_HOSTS } from 'stremio/common/CONSTANTS';
|
||||
import useShell from './useShell';
|
||||
import useShell from 'stremio/common/useShell';
|
||||
import { name, isMobile } from './device';
|
||||
|
||||
interface PlatformContext {
|
||||
|
|
|
|||
|
|
@ -69,6 +69,19 @@
|
|||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
.slide-up-enter {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
.slide-up-active {
|
||||
transform: translateY(0%);
|
||||
transition: transform 0.3s cubic-bezier(0.32, 0, 0.67, 0);
|
||||
}
|
||||
|
||||
.slide-up-exit {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
@keyframes fade-in-no-motion {
|
||||
0% {
|
||||
opacity: 0;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ const useModelState = require('./useModelState');
|
|||
const useNotifications = require('./useNotifications');
|
||||
const useOnScrollToBottom = require('./useOnScrollToBottom');
|
||||
const useProfile = require('./useProfile');
|
||||
const { default: useShell } = require('./useShell');
|
||||
const useStreamingServer = require('./useStreamingServer');
|
||||
const useTorrent = require('./useTorrent');
|
||||
const useTranslate = require('./useTranslate');
|
||||
|
|
@ -50,6 +51,7 @@ module.exports = {
|
|||
useNotifications,
|
||||
useOnScrollToBottom,
|
||||
useProfile,
|
||||
useShell,
|
||||
useStreamingServer,
|
||||
useTorrent,
|
||||
useTranslate,
|
||||
|
|
|
|||
|
|
@ -21,5 +21,5 @@
|
|||
@small-phone-portrait: ~"screen and (max-width: @{small-phone-landscape-size}) and (max-height: @{small-phone-portrait-size}) and (orientation: portrait)";
|
||||
|
||||
@phone-landscape: ~"screen and (max-width: @{phone-portrait-size}) and (max-height: @{phone-landscape-size}) and (orientation: landscape)";
|
||||
@phone-portrait: ~"screen and (max-width: @{phone-portrait-size}) and (max-height: @{phone-portrait-size}) and (orientation: portrait)";
|
||||
@phone-portrait: ~"screen and (max-width: @{phone-landscape-size}) and (max-height: @{phone-portrait-size}) and (orientation: portrait)";
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@
|
|||
@media only screen and (orientation: landscape) {
|
||||
.bottom-sheet {
|
||||
.container {
|
||||
max-width: 90%;
|
||||
max-width: calc(90% - var(--safe-area-inset-left) - var(--safe-area-inset-right));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,8 @@ const PropTypes = require('prop-types');
|
|||
const classnames = require('classnames');
|
||||
const AColorPicker = require('a-color-picker');
|
||||
const { useTranslation } = require('react-i18next');
|
||||
const { Button, ModalDialog } = require('stremio/components');
|
||||
const { Button } = require('stremio/components');
|
||||
const ModalDialog = require('stremio/components/ModalDialog');
|
||||
const useBinaryState = require('stremio/common/useBinaryState');
|
||||
const ColorPicker = require('./ColorPicker');
|
||||
const styles = require('./styles');
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
position: relative;
|
||||
z-index: 0;
|
||||
overflow: clip;
|
||||
margin-left: env(safe-area-inset-left, 0px);
|
||||
margin-right: env(safe-area-inset-right, 0px);
|
||||
width: calc(100% - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px));
|
||||
margin-left: var(--safe-area-inset-left);
|
||||
margin-right: var(--safe-area-inset-right);
|
||||
width: calc(100% - var(--safe-area-inset-left) - var(--safe-area-inset-right));
|
||||
height: 100%;
|
||||
|
||||
.horizontal-nav-bar {
|
||||
|
|
@ -22,14 +22,14 @@
|
|||
.vertical-nav-bar {
|
||||
position: absolute;
|
||||
top: var(--horizontal-nav-bar-size);
|
||||
bottom: var(--calculated-bottom-safe-inset);
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.nav-content-container {
|
||||
position: absolute;
|
||||
padding-top: calc(var(--horizontal-nav-bar-size) + env(safe-area-inset-top, 0px));
|
||||
padding-top: calc(var(--horizontal-nav-bar-size) + var(--safe-area-inset-top));
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
}
|
||||
|
||||
.addons-container {
|
||||
height: 100%;
|
||||
height: calc(100% - var(--safe-area-inset-bottom));
|
||||
background-color: transparent;
|
||||
|
||||
.addons-content {
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ const React = require('react');
|
|||
const classnames = require('classnames');
|
||||
const debounce = require('lodash.debounce');
|
||||
const { useTranslation } = require('react-i18next');
|
||||
const { useStreamingServer, useNotifications, withCoreSuspender, getVisibleChildrenRange } = require('stremio/common');
|
||||
const { useStreamingServer, useNotifications, withCoreSuspender, getVisibleChildrenRange, useProfile } = require('stremio/common');
|
||||
const { ContinueWatchingItem, EventModal, MainNavBars, MetaItem, MetaRow } = require('stremio/components');
|
||||
const StreamingServerWarning = require('./StreamingServerWarning');
|
||||
const useBoard = require('./useBoard');
|
||||
const useContinueWatchingPreview = require('./useContinueWatchingPreview');
|
||||
const styles = require('./styles');
|
||||
const { default: StreamingServerWarning } = require('./StreamingServerWarning');
|
||||
|
||||
const THRESHOLD = 5;
|
||||
|
||||
|
|
@ -19,8 +19,15 @@ const Board = () => {
|
|||
const continueWatchingPreview = useContinueWatchingPreview();
|
||||
const [board, loadBoardRows] = useBoard();
|
||||
const notifications = useNotifications();
|
||||
const profile = useProfile();
|
||||
const boardCatalogsOffset = continueWatchingPreview.items.length > 0 ? 1 : 0;
|
||||
const scrollContainerRef = React.useRef();
|
||||
const streamingServerWarningDismissed = React.useMemo(() => {
|
||||
return streamingServer.settings !== null && streamingServer.settings.type === 'Ready' || (
|
||||
!isNaN(profile.settings.streamingServerWarningDismissed.getTime()) &&
|
||||
profile.settings.streamingServerWarningDismissed.getTime() > Date.now()
|
||||
);
|
||||
}, [profile.settings, streamingServer.settings]);
|
||||
const onVisibleRangeChange = React.useCallback(() => {
|
||||
const range = getVisibleChildrenRange(scrollContainerRef.current);
|
||||
if (range === null) {
|
||||
|
|
@ -95,7 +102,7 @@ const Board = () => {
|
|||
</div>
|
||||
</MainNavBars>
|
||||
{
|
||||
streamingServer.settings !== null && streamingServer.settings.type === 'Err' ?
|
||||
!streamingServerWarningDismissed ?
|
||||
<StreamingServerWarning className={styles['board-warning-container']} />
|
||||
:
|
||||
null
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
// Copyright (C) 2017-2023 Smart code 203358507
|
||||
|
||||
const React = require('react');
|
||||
const { useServices } = require('stremio/services');
|
||||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const { useTranslation } = require('react-i18next');
|
||||
const { Button } = require('stremio/components');
|
||||
const useProfile = require('stremio/common/useProfile');
|
||||
const { withCoreSuspender } = require('stremio/common/CoreSuspender');
|
||||
const styles = require('./styles');
|
||||
|
||||
const StreamingServerWarning = ({ className }) => {
|
||||
const { t } = useTranslation();
|
||||
const { core } = useServices();
|
||||
const profile = useProfile();
|
||||
const onLaterClick = React.useCallback(() => {
|
||||
const streamingServerWarningDismissed = new Date();
|
||||
streamingServerWarningDismissed.setMonth(streamingServerWarningDismissed.getMonth() + 1);
|
||||
core.transport.dispatch({
|
||||
action: 'Ctx',
|
||||
args: {
|
||||
action: 'UpdateSettings',
|
||||
args: {
|
||||
...profile.settings,
|
||||
streamingServerWarningDismissed
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [profile.settings]);
|
||||
const onDismissClick = React.useCallback(() => {
|
||||
const streamingServerWarningDismissed = new Date();
|
||||
streamingServerWarningDismissed.setFullYear(streamingServerWarningDismissed.getFullYear() + 50);
|
||||
core.transport.dispatch({
|
||||
action: 'Ctx',
|
||||
args: {
|
||||
action: 'UpdateSettings',
|
||||
args: {
|
||||
...profile.settings,
|
||||
streamingServerWarningDismissed
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [profile.settings]);
|
||||
|
||||
if (!isNaN(profile.settings.streamingServerWarningDismissed.getTime()) &&
|
||||
profile.settings.streamingServerWarningDismissed.getTime() > Date.now()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classnames(className, styles['warning-container'])}>
|
||||
<div className={styles['warning-statement']}>{ t('SETTINGS_SERVER_UNAVAILABLE') }</div>
|
||||
<a href="https://www.stremio.com/download-service" target="_blank" rel="noreferrer">
|
||||
<Button className={styles['warning-button']} title={t('SERVICE_INSTALL')} tabIndex={-1}>
|
||||
<div className={styles['warning-label']}>{ t('SERVICE_INSTALL') }</div>
|
||||
</Button>
|
||||
</a>
|
||||
<Button className={styles['warning-button']} title={t('WARNING_STREAMING_SERVER_LATER')} onClick={onLaterClick} tabIndex={-1}>
|
||||
<div className={styles['warning-label']}>{ t('WARNING_STREAMING_SERVER_LATER') }</div>
|
||||
</Button>
|
||||
<Button className={styles['warning-button']} title={t('DONT_SHOW_AGAIN')} onClick={onDismissClick} tabIndex={-1}>
|
||||
<div className={styles['warning-label']}>{ t('DONT_SHOW_AGAIN') }</div>
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
StreamingServerWarning.propTypes = {
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
module.exports = withCoreSuspender(StreamingServerWarning);
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (C) 2017-2024 Smart code 203358507
|
||||
|
||||
@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less';
|
||||
@import (reference) '~stremio/common/screen-sizes.less';
|
||||
|
||||
.warning-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
background-color: @color-accent5-dark3;
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0rem 0.25rem 1rem rgba(0, 0, 0, 0.48), 0rem 0.5rem 3rem rgba(0, 0, 0, 0.64);
|
||||
|
||||
.warning-statement {
|
||||
flex: 1;
|
||||
font-size: 1.2rem;
|
||||
max-height: 2.4em;
|
||||
color: @color-surface-light5-90;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
|
||||
.action {
|
||||
flex: none;
|
||||
padding: 0.5rem 1rem;
|
||||
color: @color-surface-light5-90;
|
||||
background-color: rgba(0, 0, 0, 0.24);
|
||||
border-radius: var(--border-radius);
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 1.2rem;
|
||||
color: @color-surface-light5-90;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.label {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: @minimum) {
|
||||
.warning-container {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
padding: 1rem 0.5rem;
|
||||
|
||||
.actions {
|
||||
justify-content: space-around;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
// Copyright (C) 2017-2024 Smart code 203358507
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import classnames from 'classnames';
|
||||
import { useServices } from 'stremio/services';
|
||||
import { Button } from 'stremio/components';
|
||||
import useProfile from 'stremio/common/useProfile';
|
||||
import { withCoreSuspender } from 'stremio/common/CoreSuspender';
|
||||
import styles from './StreamingServerWarning.less';
|
||||
|
||||
type Props = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const StreamingServerWarning = ({ className }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const { core } = useServices();
|
||||
const profile = useProfile();
|
||||
|
||||
const createDismissalDate = (months: number, years = 0): Date => {
|
||||
const dismissalDate = new Date();
|
||||
|
||||
if (months) {
|
||||
dismissalDate.setMonth(dismissalDate.getMonth() + months);
|
||||
}
|
||||
if (years) {
|
||||
dismissalDate.setFullYear(dismissalDate.getFullYear() + years);
|
||||
}
|
||||
|
||||
return dismissalDate;
|
||||
};
|
||||
|
||||
const updateSettings = useCallback((streamingServerWarningDismissed: Date) => {
|
||||
core.transport.dispatch({
|
||||
action: 'Ctx',
|
||||
args: {
|
||||
action: 'UpdateSettings',
|
||||
args: {
|
||||
...profile.settings,
|
||||
streamingServerWarningDismissed
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [profile.settings]);
|
||||
|
||||
const onLater = useCallback(() => {
|
||||
updateSettings(createDismissalDate(1));
|
||||
}, [updateSettings]);
|
||||
|
||||
const onDismiss = useCallback(() => {
|
||||
updateSettings(createDismissalDate(0, 50));
|
||||
}, [updateSettings]);
|
||||
|
||||
return (
|
||||
<div className={classnames(className, styles['warning-container'])}>
|
||||
<div className={styles['warning-statement']}>
|
||||
{t('SETTINGS_SERVER_UNAVAILABLE')}
|
||||
</div>
|
||||
<div className={styles['actions']}>
|
||||
<a
|
||||
href='https://www.stremio.com/download-service'
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
>
|
||||
<Button
|
||||
className={styles['action']}
|
||||
title={t('SERVICE_INSTALL')}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<div className={styles['label']}>
|
||||
{t('SERVICE_INSTALL')}
|
||||
</div>
|
||||
</Button>
|
||||
</a>
|
||||
<Button
|
||||
className={styles['action']}
|
||||
title={t('WARNING_STREAMING_SERVER_LATER')}
|
||||
onClick={onLater}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<div className={styles['label']}>
|
||||
{t('WARNING_STREAMING_SERVER_LATER')}
|
||||
</div>
|
||||
</Button>
|
||||
<Button
|
||||
className={styles['action']}
|
||||
title={t('DONT_SHOW_AGAIN')}
|
||||
onClick={onDismiss}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<div className={styles['label']}>
|
||||
{t('DONT_SHOW_AGAIN')}
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default withCoreSuspender(StreamingServerWarning);
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
// Copyright (C) 2017-2023 Smart code 203358507
|
||||
|
||||
const StreamingServerWarning = require('./StreamingServerWarning');
|
||||
|
||||
module.exports = StreamingServerWarning;
|
||||
5
src/routes/Board/StreamingServerWarning/index.ts
Normal file
5
src/routes/Board/StreamingServerWarning/index.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// Copyright (C) 2017-2024 Smart code 203358507
|
||||
|
||||
import StreamingServerWarning from './StreamingServerWarning';
|
||||
|
||||
export default StreamingServerWarning;
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright (C) 2017-2023 Smart code 203358507
|
||||
|
||||
@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less';
|
||||
|
||||
.warning-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
background-color: @color-accent5-dark3;
|
||||
|
||||
.warning-statement {
|
||||
flex: 1;
|
||||
margin-right: 1rem;
|
||||
font-size: 1.2rem;
|
||||
max-height: 2.4em;
|
||||
color: @color-surface-light5-90;
|
||||
}
|
||||
|
||||
.warning-button {
|
||||
flex: none;
|
||||
margin-left: 1rem;
|
||||
color: @color-surface-light5-90;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.warning-label {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.warning-label {
|
||||
font-size: 1.2rem;
|
||||
max-height: 1.2em;
|
||||
color: @color-surface-light5-90;
|
||||
}
|
||||
}
|
||||
|
||||
.warning-button:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 500px) {
|
||||
.warning-container {
|
||||
display: block;
|
||||
height: auto !important;
|
||||
text-align: center;
|
||||
.warning-statement {
|
||||
margin-bottom: 0.5rem;
|
||||
margin-right: 0;
|
||||
}
|
||||
.warning-button {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
.board-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
height: calc(100% - var(--safe-area-inset-bottom));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
|
|
@ -36,9 +36,10 @@
|
|||
}
|
||||
|
||||
.board-warning-container {
|
||||
flex: none;
|
||||
align-self: stretch;
|
||||
margin-bottom: var(--calculated-bottom-safe-inset, 0rem);
|
||||
position: absolute;
|
||||
bottom: calc(var(--safe-area-inset-bottom) + 0.5rem);
|
||||
left: calc(var(--safe-area-inset-left) + 0.5rem);
|
||||
right: calc(var(--safe-area-inset-right) + 0.5rem);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -216,12 +217,16 @@
|
|||
}
|
||||
|
||||
.board-warning-container {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: calc(var(--vertical-nav-bar-size) + var(--calculated-bottom-safe-inset, 0rem));
|
||||
height: 4rem;
|
||||
margin-bottom: 0rem;
|
||||
bottom: calc(var(--vertical-nav-bar-size) + 0.5rem);
|
||||
height: 7rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media @phone-landscape {
|
||||
.board-container {
|
||||
.board-warning-container {
|
||||
left: calc(var(--safe-area-inset-left) + var(--vertical-nav-bar-size) + 0.5rem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,8 +3,7 @@
|
|||
@import (reference) '~stremio/common/screen-sizes.less';
|
||||
|
||||
.calendar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
height: calc(100% - var(--safe-area-inset-bottom));
|
||||
background-color: transparent;
|
||||
|
||||
.content {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
}
|
||||
|
||||
.discover-container {
|
||||
height: 100%;
|
||||
height: calc(100% - var(--safe-area-inset-bottom));
|
||||
background-color: transparent;
|
||||
|
||||
.discover-content {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
}
|
||||
|
||||
.library-container {
|
||||
height: 100%;
|
||||
height: calc(100% - var(--safe-area-inset-bottom));
|
||||
background-color: transparent;
|
||||
|
||||
.library-content {
|
||||
|
|
|
|||
|
|
@ -181,12 +181,17 @@ const Stream = ({ className, videoId, videoReleased, addonName, name, descriptio
|
|||
const renderMenu = React.useMemo(() => function renderMenu() {
|
||||
return (
|
||||
<div className={styles['context-menu-content']} onPointerDown={popupMenuOnPointerDown} onContextMenu={popupMenuOnContextMenu} onClick={popupMenuOnClick} onKeyDown={popupMenuOnKeyDown}>
|
||||
<div className={styles['context-menu-title']}>
|
||||
{description}
|
||||
</div>
|
||||
<Button className={styles['context-menu-option-container']} title={t('CTX_PLAY')}>
|
||||
<Icon className={styles['menu-icon']} name={'play'} />
|
||||
<div className={styles['context-menu-option-label']}>{t('CTX_PLAY')}</div>
|
||||
</Button>
|
||||
{
|
||||
streamLink &&
|
||||
<Button className={styles['context-menu-option-container']} title={t('CTX_COPY_STREAM_LINK')} onClick={copyStreamLink}>
|
||||
<Icon className={styles['menu-icon']} name={'link'} />
|
||||
<div className={styles['context-menu-option-label']}>{t('CTX_COPY_STREAM_LINK')}</div>
|
||||
</Button>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,12 +111,29 @@
|
|||
background-color: var(--secondary-accent-color);
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
flex: none;
|
||||
width: 1.7rem;
|
||||
height: 1.7rem;
|
||||
margin-right: 1rem;
|
||||
color: var(--color-placeholder);
|
||||
}
|
||||
|
||||
.context-menu-container {
|
||||
max-width: calc(90% - 1.5rem);
|
||||
z-index: 2;
|
||||
|
||||
.context-menu-content {
|
||||
--spatial-navigation-contain: contain;
|
||||
|
||||
.context-menu-title {
|
||||
font-size: 0.9rem;
|
||||
padding: 1rem 1.5rem;
|
||||
font-weight: 100;
|
||||
border-bottom: 1px solid var(--color-placeholder);
|
||||
color: var(--primary-foreground-color);
|
||||
white-space: break-spaces;
|
||||
}
|
||||
|
||||
.context-menu-option-container {
|
||||
display: flex;
|
||||
|
|
@ -131,8 +148,9 @@
|
|||
|
||||
.context-menu-option-label {
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
color:var(--primary-foreground-color);
|
||||
font-weight: 300;
|
||||
color: var(--primary-foreground-color);
|
||||
text-transform: capitalize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const { Button, Image, Multiselect } = require('stremio/components');
|
|||
const { useServices } = require('stremio/services');
|
||||
const Stream = require('./Stream');
|
||||
const styles = require('./styles');
|
||||
const { usePlatform } = require('stremio/common');
|
||||
const { usePlatform, useProfile } = require('stremio/common');
|
||||
|
||||
const ALL_ADDONS_KEY = 'ALL';
|
||||
|
||||
|
|
@ -17,17 +17,21 @@ const StreamsList = ({ className, video, ...props }) => {
|
|||
const { t } = useTranslation();
|
||||
const { core } = useServices();
|
||||
const platform = usePlatform();
|
||||
const profile = useProfile();
|
||||
const streamsContainerRef = React.useRef(null);
|
||||
const [selectedAddon, setSelectedAddon] = React.useState(ALL_ADDONS_KEY);
|
||||
const onAddonSelected = React.useCallback((event) => {
|
||||
streamsContainerRef.current.scrollTo({ top: 0, left: 0, behavior: platform.name === 'ios' ? 'smooth' : 'instant' });
|
||||
setSelectedAddon(event.value);
|
||||
}, [platform]);
|
||||
const showInstallAddonsButton = React.useMemo(() => {
|
||||
return !profile || profile.auth === null || profile.auth?.user?.isNewUser === true;
|
||||
}, [profile]);
|
||||
const backButtonOnClick = React.useCallback(() => {
|
||||
if (video.deepLinks && typeof video.deepLinks.metaDetailsVideos === 'string') {
|
||||
window.location.replace(video.deepLinks.metaDetailsVideos + (
|
||||
typeof video.season === 'number' ?
|
||||
`?${new URLSearchParams({'season': video.season})}`
|
||||
`?${new URLSearchParams({ 'season': video.season })}`
|
||||
:
|
||||
null
|
||||
));
|
||||
|
|
@ -126,6 +130,15 @@ const StreamsList = ({ className, video, ...props }) => {
|
|||
<div className={styles['message-container']}>
|
||||
<Image className={styles['image']} src={require('/images/empty.png')} alt={' '} />
|
||||
<div className={styles['label']}>{t('NO_STREAM')}</div>
|
||||
{
|
||||
showInstallAddonsButton ?
|
||||
<Button className={styles['install-button-container']} title={t('ADDON_CATALOGUE_MORE')} href={'#/addons'}>
|
||||
<Icon className={styles['icon']} name={'addons'} />
|
||||
<div className={styles['label']}>{t('ADDON_CATALOGUE_MORE')}</div>
|
||||
</Button>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
:
|
||||
filteredStreams.length === 0 ?
|
||||
|
|
@ -161,13 +174,18 @@ const StreamsList = ({ className, video, ...props }) => {
|
|||
onClick={stream.onClick}
|
||||
/>
|
||||
))}
|
||||
{
|
||||
showInstallAddonsButton ?
|
||||
<Button className={styles['install-button-container']} title={t('ADDON_CATALOGUE_MORE')} href={'#/addons'}>
|
||||
<Icon className={styles['icon']} name={'addons'} />
|
||||
<div className={styles['label']}>{t('ADDON_CATALOGUE_MORE')}</div>
|
||||
</Button>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
}
|
||||
<Button className={styles['install-button-container']} title={t('ADDON_CATALOGUE_MORE')} href={'#/addons'}>
|
||||
<Icon className={styles['icon']} name={'addons'} />
|
||||
<div className={styles['label']}>{ t('ADDON_CATALOGUE_MORE') }</div>
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 1rem 1rem 0;
|
||||
padding: 1rem;
|
||||
overflow-y: auto;
|
||||
|
||||
.image {
|
||||
|
|
@ -144,11 +144,12 @@
|
|||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 1rem;
|
||||
padding: 1.5rem 1rem;
|
||||
border-radius: var(--border-radius);
|
||||
background-color: var(--secondary-accent-color);
|
||||
border-radius: 3rem;
|
||||
height: 4rem;
|
||||
padding: 0 2rem;
|
||||
margin: 1rem auto;
|
||||
max-width: 50%;
|
||||
border-radius: 2rem;
|
||||
|
||||
&:hover {
|
||||
outline: var(--focus-outline-size) solid var(--secondary-accent-color);
|
||||
|
|
@ -165,7 +166,7 @@
|
|||
|
||||
.label {
|
||||
flex: 0 1 auto;
|
||||
font-size: 1.5rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
max-height: 3.6em;
|
||||
text-align: center;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
flex-direction: row;
|
||||
margin-top: calc(var(--top-overlay-size) * -1);
|
||||
padding-top: var(--top-overlay-size);
|
||||
padding-bottom: var(--calculated-bottom-safe-inset, 0rem);
|
||||
padding-bottom: var(--safe-area-inset-bottom, 0rem);
|
||||
.vertical-nav-bar {
|
||||
flex: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ const ControlBar = ({
|
|||
<VolumeSlider
|
||||
className={styles['volume-slider']}
|
||||
volume={volume}
|
||||
muted={muted}
|
||||
onVolumeChangeRequested={onVolumeChangeRequested}
|
||||
/>
|
||||
<div className={styles['spacing']} />
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const { useRouteFocused } = require('stremio-router');
|
|||
const { Slider } = require('stremio/components');
|
||||
const styles = require('./styles');
|
||||
|
||||
const VolumeSlider = ({ className, volume, onVolumeChangeRequested }) => {
|
||||
const VolumeSlider = ({ className, volume, onVolumeChangeRequested, muted }) => {
|
||||
const disabled = volume === null || isNaN(volume);
|
||||
const routeFocused = useRouteFocused();
|
||||
const [slidingVolume, setSlidingVolume] = React.useState(null);
|
||||
|
|
@ -45,7 +45,9 @@ const VolumeSlider = ({ className, volume, onVolumeChangeRequested }) => {
|
|||
className={classnames(className, styles['volume-slider'], { 'active': slidingVolume !== null })}
|
||||
value={
|
||||
!disabled ?
|
||||
slidingVolume !== null ? slidingVolume : volume
|
||||
!muted ?
|
||||
slidingVolume !== null ? slidingVolume : volume
|
||||
: 0
|
||||
:
|
||||
100
|
||||
}
|
||||
|
|
@ -61,7 +63,8 @@ const VolumeSlider = ({ className, volume, onVolumeChangeRequested }) => {
|
|||
VolumeSlider.propTypes = {
|
||||
className: PropTypes.string,
|
||||
volume: PropTypes.number,
|
||||
onVolumeChangeRequested: PropTypes.func
|
||||
onVolumeChangeRequested: PropTypes.func,
|
||||
muted: PropTypes.bool,
|
||||
};
|
||||
|
||||
module.exports = VolumeSlider;
|
||||
|
|
|
|||
|
|
@ -76,14 +76,6 @@ const NextVideoPopup = ({ className, metaItem, nextVideo, onDismiss, onNextVideo
|
|||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
nextVideo !== null && typeof nextVideo.overview === 'string' ?
|
||||
<div className={styles['description']}>
|
||||
{ nextVideo.overview }
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
<div className={styles['buttons-container']}>
|
||||
<Button className={classnames(styles['button-container'], styles['dismiss'])} onClick={onDismissButtonClick}>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
// Copyright (C) 2017-2023 Smart code 203358507
|
||||
|
||||
@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less';
|
||||
@import (reference) '~stremio/common/screen-sizes.less';
|
||||
|
||||
.next-video-popup-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 50rem;
|
||||
width: 38rem;
|
||||
min-height: 13rem;
|
||||
animation: slide-fade-in 0.5s ease-in;
|
||||
|
||||
@keyframes slide-fade-in {
|
||||
|
|
@ -21,7 +23,7 @@
|
|||
}
|
||||
|
||||
.poster-container {
|
||||
flex: 1 1 45%;
|
||||
flex: 1 1 25%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
|
@ -50,14 +52,16 @@
|
|||
|
||||
.details-container {
|
||||
flex: auto;
|
||||
padding: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
padding: 1.5rem 2rem;
|
||||
|
||||
.name {
|
||||
flex: none;
|
||||
align-self: stretch;
|
||||
max-height: 2.4em;
|
||||
font-weight: 700;
|
||||
margin-bottom: 1.5rem;
|
||||
color: var(--primary-accent-color);
|
||||
|
||||
.label {
|
||||
|
|
@ -70,36 +74,30 @@
|
|||
align-self: stretch;
|
||||
max-height: 2.4em;
|
||||
font-weight: 500;
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--primary-foreground-color);
|
||||
}
|
||||
|
||||
.description {
|
||||
color: var(--primary-foreground-color);
|
||||
opacity: 0.5;
|
||||
max-width: 80%;
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
.buttons-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 0 1rem 2rem;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
padding: 0 1rem 1.5rem;
|
||||
|
||||
.spacing {
|
||||
flex: 0 0 50%;
|
||||
}
|
||||
|
||||
.button-container {
|
||||
flex: 0 0 45%;
|
||||
flex: 0 1 50%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
height: 3.5rem;
|
||||
padding: 0 0.5rem;
|
||||
margin-left: 1rem;
|
||||
padding: 0 1rem;
|
||||
border-radius: 1.75rem;
|
||||
|
||||
&.play-button {
|
||||
|
|
@ -123,7 +121,6 @@
|
|||
flex: none;
|
||||
width: 1.4rem;
|
||||
height: 1.4rem;
|
||||
margin-right: 1rem;
|
||||
color: var(--primary-foreground-color);
|
||||
}
|
||||
|
||||
|
|
@ -145,4 +142,26 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media @phone-portrait {
|
||||
.next-video-popup-container {
|
||||
.info-container {
|
||||
.buttons-container {
|
||||
gap: 0.5rem;
|
||||
|
||||
.button-container {
|
||||
margin-left: 0rem;
|
||||
|
||||
.icon {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@media (orientation: portrait) and (max-width: @xsmall) {
|
||||
@media @phone-portrait {
|
||||
.side-drawer {
|
||||
max-width: 100dvw;
|
||||
|
||||
|
|
@ -94,12 +94,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
@media (orientation: landscape) and (max-width: @xsmall) {
|
||||
@media @phone-landscape {
|
||||
.side-drawer {
|
||||
max-width: 50dvw;
|
||||
|
||||
.info {
|
||||
max-height: 30dvh;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ html:not(.active-slider-within) {
|
|||
}
|
||||
|
||||
&.side-drawer-button-layer {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
right: -4rem;
|
||||
left: initial;
|
||||
|
|
|
|||
|
|
@ -187,6 +187,12 @@ const Settings = () => {
|
|||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
typeof shell?.transport?.props?.shellVersion === 'string' ?
|
||||
<div className={styles['version-info-label']} title={shell.transport.props.shellVersion}>Shell Version: {shell.transport.props.shellVersion}</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
<div ref={sectionsContainerRef} className={styles['sections-container']} onScroll={sectionsContainerOnScroll}>
|
||||
<div ref={generalSectionRef} className={styles['section-container']}>
|
||||
|
|
@ -717,6 +723,23 @@ const Settings = () => {
|
|||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
typeof shell?.transport?.props?.shellVersion === 'string' ?
|
||||
<div className={styles['option-container']}>
|
||||
<div className={styles['option-name-container']}>
|
||||
<div className={styles['label']}>
|
||||
Shell Version
|
||||
</div>
|
||||
</div>
|
||||
<div className={classnames(styles['option-input-container'], styles['info-container'])}>
|
||||
<div className={styles['label']}>
|
||||
{ shell.transport.props.shellVersion }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
}
|
||||
|
||||
.settings-container {
|
||||
height: 100%;
|
||||
height: calc(100% - var(--safe-area-inset-bottom));
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
|
||||
|
|
|
|||
1
src/types/models/Ctx.d.ts
vendored
1
src/types/models/Ctx.d.ts
vendored
|
|
@ -9,6 +9,7 @@ type Auth = {
|
|||
created_at: number,
|
||||
expires_in: number,
|
||||
},
|
||||
isNewUser: boolean,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ module.exports = (env, argv) => ({
|
|||
exclude: /node_modules/,
|
||||
type: 'asset/resource',
|
||||
generator: {
|
||||
filename: `${COMMIT_HASH}/images/[name][ext][query]`
|
||||
filename: 'images/[name][ext][query]'
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -231,9 +231,9 @@ module.exports = (env, argv) => ({
|
|||
}),
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
{ from: 'favicons', to: `${COMMIT_HASH}/favicons` },
|
||||
{ from: 'images', to: `${COMMIT_HASH}/images` },
|
||||
{ from: 'screenshots/*.webp', to: `${COMMIT_HASH}` },
|
||||
{ from: 'favicons', to: 'favicons' },
|
||||
{ from: 'images', to: 'images' },
|
||||
{ from: 'screenshots/*.webp', to: './' },
|
||||
]
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
|
|
@ -243,8 +243,8 @@ module.exports = (env, argv) => ({
|
|||
template: './src/index.html',
|
||||
inject: false,
|
||||
scriptLoading: 'blocking',
|
||||
faviconsPath: `${COMMIT_HASH}/favicons`,
|
||||
imagesPath: `${COMMIT_HASH}/images`,
|
||||
faviconsPath: 'favicons',
|
||||
imagesPath: 'images',
|
||||
}),
|
||||
new WebpackPwaManifest({
|
||||
name: 'Stremio Web',
|
||||
|
|
@ -261,33 +261,33 @@ module.exports = (env, argv) => ({
|
|||
icons: [
|
||||
{
|
||||
src: 'images/icon.png',
|
||||
destination: `${COMMIT_HASH}/images`,
|
||||
destination: 'icons',
|
||||
sizes: [196, 512],
|
||||
purpose: 'any',
|
||||
ios: true,
|
||||
purpose: 'any'
|
||||
},
|
||||
{
|
||||
src: 'images/maskable_icon.png',
|
||||
destination: `${COMMIT_HASH}/images`,
|
||||
destination: 'maskable_icons',
|
||||
sizes: [196, 512],
|
||||
purpose: 'maskable',
|
||||
ios: true
|
||||
},
|
||||
{
|
||||
src: 'favicons/favicon.ico',
|
||||
destination: `${COMMIT_HASH}/favicons`,
|
||||
destination: 'favicons',
|
||||
sizes: [256],
|
||||
}
|
||||
],
|
||||
screenshots : [
|
||||
{
|
||||
src: `${COMMIT_HASH}/screenshots/board_wide.webp`,
|
||||
src: 'screenshots/board_wide.webp',
|
||||
sizes: '1440x900',
|
||||
type: 'image/webp',
|
||||
form_factor: 'wide',
|
||||
label: 'Homescreen of Stremio'
|
||||
},
|
||||
{
|
||||
src: `${COMMIT_HASH}/screenshots/board_narrow.webp`,
|
||||
src: 'screenshots/board_narrow.webp',
|
||||
sizes: '414x896',
|
||||
type: 'image/webp',
|
||||
form_factor: 'narrow',
|
||||
|
|
|
|||
Loading…
Reference in a new issue