From d177f860189a909321b33bc2f4a27697375da627 Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Wed, 3 Sep 2025 12:07:30 +0300 Subject: [PATCH 01/33] chore: change PullUserFromAPI action and include args Signed-off-by: Lachezar Lechev --- src/App/App.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/App/App.js b/src/App/App.js index 3e816be9f..8bb22c679 100644 --- a/src/App/App.js +++ b/src/App/App.js @@ -159,7 +159,8 @@ const App = () => { services.core.transport.dispatch({ action: 'Ctx', args: { - action: 'PullUserFromAPI' + action: 'PullUserFromAPI', + args: {} } }); services.core.transport.dispatch({ From cfa99f0e386213a2ad9960a15f11bf064f8121df Mon Sep 17 00:00:00 2001 From: Aris Sidiropoulos Date: Wed, 17 Sep 2025 21:13:17 +0300 Subject: [PATCH 02/33] fix(Intro): make all text lowercase to match the rest --- src/routes/Intro/Intro.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes/Intro/Intro.js b/src/routes/Intro/Intro.js index 48acadcd4..e85a65d97 100644 --- a/src/routes/Intro/Intro.js +++ b/src/routes/Intro/Intro.js @@ -387,7 +387,7 @@ const Intro = ({ queryParams }) => { { state.form === SIGNUP_FORM ? : null @@ -395,7 +395,7 @@ const Intro = ({ queryParams }) => { { state.form === LOGIN_FORM ? : null @@ -403,7 +403,7 @@ const Intro = ({ queryParams }) => { { state.form === SIGNUP_FORM ? : null From 010f2e0390377006e9e89009f26c06891aae1ce9 Mon Sep 17 00:00:00 2001 From: Aris Sidiropoulos Date: Fri, 19 Sep 2025 11:43:36 +0300 Subject: [PATCH 03/33] fix(Intro): follow up commit, best practice solution --- src/routes/Intro/Intro.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes/Intro/Intro.js b/src/routes/Intro/Intro.js index e85a65d97..6de7835d5 100644 --- a/src/routes/Intro/Intro.js +++ b/src/routes/Intro/Intro.js @@ -387,7 +387,7 @@ const Intro = ({ queryParams }) => { { state.form === SIGNUP_FORM ? : null @@ -395,7 +395,7 @@ const Intro = ({ queryParams }) => { { state.form === LOGIN_FORM ? : null @@ -403,7 +403,7 @@ const Intro = ({ queryParams }) => { { state.form === SIGNUP_FORM ? : null From 5bea8a83c68a0db968f6adb2fea7b1ef82d17271 Mon Sep 17 00:00:00 2001 From: Aris Sidiropoulos Date: Fri, 19 Sep 2025 16:45:25 +0300 Subject: [PATCH 04/33] fix(Intro): clean up unused css class --- src/routes/Intro/styles.less | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/routes/Intro/styles.less b/src/routes/Intro/styles.less index 32fc73d79..7aedeae48 100644 --- a/src/routes/Intro/styles.less +++ b/src/routes/Intro/styles.less @@ -102,9 +102,6 @@ text-align: center; } - .uppercase { - text-transform: uppercase; - } } .submit-button, .guest-login-button, .signup-form-button, .login-form-button { From 10a98fcecf8ab807e4e1ac1c36887ab94435071e Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Tue, 23 Sep 2025 23:45:57 +0300 Subject: [PATCH 05/33] chore: code styles --- src/routes/Intro/styles.less | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routes/Intro/styles.less b/src/routes/Intro/styles.less index 7aedeae48..31a09d54c 100644 --- a/src/routes/Intro/styles.less +++ b/src/routes/Intro/styles.less @@ -101,7 +101,6 @@ color: var(--primary-foreground-color); text-align: center; } - } .submit-button, .guest-login-button, .signup-form-button, .login-form-button { From 67f5446030c0317dfb3941df84911edcfcd79253 Mon Sep 17 00:00:00 2001 From: actuallylost Date: Sat, 27 Sep 2025 16:23:06 +0300 Subject: [PATCH 06/33] chore: fix all typos and misspellings --- .github/workflows/build.yml | 4 ++-- CODE_OF_CONDUCT.md | 4 ++-- src/App/styles.less | 4 ++-- src/common/FileDrop/FileDrop.tsx | 2 +- src/common/useNotifications.d.ts | 4 ++-- src/components/BottomSheet/BottomSheet.less | 2 +- src/components/ColorInput/ColorPicker/ColorPicker.js | 2 +- src/components/ColorInput/ColorPicker/styles.less | 2 +- src/components/ContinueWatchingItem/index.js | 4 ++-- src/routes/Player/SubtitlesMenu/SubtitlesMenu.js | 2 +- .../Settings/Streaming/URLsManager/AddItem/AddItem.tsx | 6 +++--- src/types/models/Player.d.ts | 2 +- webpack.config.js | 4 ++-- 13 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b41ff7317..95c70f581 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,7 @@ on: branches: - development tags-ignore: - - '**' + - "**" pull_request: branches: - development @@ -33,7 +33,7 @@ jobs: run: npm test - name: Lint run: npm run lint - # Create recursivelly the destiantion dir with + # Create recursively the destination dir with # "--parrents where no error if existing, make parent directories as needed." - run: mkdir -p ./build/${{ github.head_ref || github.ref_name }} - name: Deploy to GitHub Pages diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 921fba0a7..0933226b2 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -29,10 +29,10 @@ Project maintainers are responsible for enforcing this code of conduct. They can ## Suggestions for newbies - Contributors are welcomed to use AI models as "help" in solving issues, but you must always double check the code that you're submitting. -- Refrain from excesive comments generated by AI. +- Refrain from excessive comments generated by AI. - Refrain from docs generated entirely by AI. - Always check what files you are committing and submitting to the PR when you are using any agent for help or an AI model. -- If you don't how to tackle a problem and AI can't help you, please just ask or look in Stack Overlflow, Google, Medium etc. +- If you don't how to tackle a problem and AI can't help you, please just ask or look in Stack Overflow, Google, Medium etc. - Learning how to code is fun and easier when using AI, but sometimes it might be just too much ... what are you going to learn, if AI does everything for you and you don't know what the code you are submitting actually does?! ## Scope diff --git a/src/App/styles.less b/src/App/styles.less index 373b46900..adce0ae5c 100644 --- a/src/App/styles.less +++ b/src/App/styles.less @@ -35,7 +35,7 @@ @top-overlay-size: 5.25rem; @bottom-overlay-size: 0rem; @overlap-size: 3rem; -@transparency-grandient-pad: 6rem; +@transparency-gradient-pad: 6rem; :root { --landscape-shape-ratio: 0.5625; @@ -69,7 +69,7 @@ --top-overlay-size: @top-overlay-size; --bottom-overlay-size: @bottom-overlay-size; --overlap-size: @overlap-size; - --transparency-grandient-pad: @transparency-grandient-pad; + --transparency-gradient-pad: @transparency-gradient-pad; --safe-area-inset-top: @safe-area-inset-top; --safe-area-inset-right: @safe-area-inset-right; --safe-area-inset-bottom: @safe-area-inset-bottom; diff --git a/src/common/FileDrop/FileDrop.tsx b/src/common/FileDrop/FileDrop.tsx index aae4e146b..2993991e7 100644 --- a/src/common/FileDrop/FileDrop.tsx +++ b/src/common/FileDrop/FileDrop.tsx @@ -42,7 +42,7 @@ const FileDropProvider = ({ className, children }: Props) => { .then((buffer) => { listeners .filter(([type]) => file.type ? type === file.type : isFileType(buffer, type)) - .forEach(([, listerner]) => listerner(file.name, buffer)); + .forEach(([, listener]) => listener(file.name, buffer)); }); } diff --git a/src/common/useNotifications.d.ts b/src/common/useNotifications.d.ts index e3cae5b81..bfe63d67b 100644 --- a/src/common/useNotifications.d.ts +++ b/src/common/useNotifications.d.ts @@ -1,2 +1,2 @@ -declare const useNotifcations: () => Notifications; -export = useNotifcations; +declare const useNotifications: () => Notifications; +export = useNotifications; diff --git a/src/components/BottomSheet/BottomSheet.less b/src/components/BottomSheet/BottomSheet.less index f7e3315e1..7fcc6e508 100644 --- a/src/components/BottomSheet/BottomSheet.less +++ b/src/components/BottomSheet/BottomSheet.less @@ -86,7 +86,7 @@ } } -@media only screen and (min-width: @small) and (orientation: portait) { +@media only screen and (min-width: @small) and (orientation: portrait) { .bottom-sheet { display: none; } diff --git a/src/components/ColorInput/ColorPicker/ColorPicker.js b/src/components/ColorInput/ColorPicker/ColorPicker.js index 823ea55c8..3b66fcdf4 100644 --- a/src/components/ColorInput/ColorPicker/ColorPicker.js +++ b/src/components/ColorInput/ColorPicker/ColorPicker.js @@ -21,7 +21,7 @@ const ColorPicker = ({ className, value, onInput }) => { showRGB: false, showAlpha: true }); - const pickerClipboard = pickerElementRef.current.querySelector('.a-color-picker-clipbaord'); + const pickerClipboard = pickerElementRef.current.querySelector('.a-color-picker-clipboard'); if (pickerClipboard instanceof HTMLElement) { pickerClipboard.tabIndex = -1; } diff --git a/src/components/ColorInput/ColorPicker/styles.less b/src/components/ColorInput/ColorPicker/styles.less index 7156d440d..536228ed1 100644 --- a/src/components/ColorInput/ColorPicker/styles.less +++ b/src/components/ColorInput/ColorPicker/styles.less @@ -16,7 +16,7 @@ box-shadow: 0 0 .2rem var(--color-surfacedark); } - :global(.a-color-picker-clipbaord) { + :global(.a-color-picker-clipboard) { pointer-events: none; } } \ No newline at end of file diff --git a/src/components/ContinueWatchingItem/index.js b/src/components/ContinueWatchingItem/index.js index 5d3b2dd76..2c50f3c22 100644 --- a/src/components/ContinueWatchingItem/index.js +++ b/src/components/ContinueWatchingItem/index.js @@ -1,5 +1,5 @@ // Copyright (C) 2017-2023 Smart code 203358507 -const ContineWatchingItem = require('./ContinueWatchingItem'); +const ContinueWatchingItem = require('./ContinueWatchingItem'); -module.exports = ContineWatchingItem; +module.exports = ContinueWatchingItem; diff --git a/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js b/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js index d94c5f70b..fe690d0c4 100644 --- a/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js +++ b/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js @@ -228,7 +228,7 @@ const SubtitlesMenu = React.memo((props) => { /> { setInputValue(target.value); }, []); - const onSumbit = useCallback(() => { + const onSubmit = useCallback(() => { handleAddUrl(inputValue); }, [inputValue]); @@ -27,11 +27,11 @@ const AddItem = ({ onCancel, handleAddUrl }: Props) => { className={styles['input']} value={inputValue} onChange={handleValueChange} - onSubmit={onSumbit} + onSubmit={onSubmit} placeholder={'Enter URL'} />
- +
+ +
+ { + grouped.map(({ name, label, shortcuts }) => ( + + )) + } +
+ + + ), document.body); +}; + +export default ShortcutsModal; diff --git a/src/App/ShortcutsModal/index.ts b/src/App/ShortcutsModal/index.ts new file mode 100644 index 000000000..5a7549fac --- /dev/null +++ b/src/App/ShortcutsModal/index.ts @@ -0,0 +1,2 @@ +import ShortcutsModal from './ShortcutsModal'; +export default ShortcutsModal; diff --git a/src/App/ShortcutsModal/styles.less b/src/App/ShortcutsModal/styles.less new file mode 100644 index 000000000..ebbc19c62 --- /dev/null +++ b/src/App/ShortcutsModal/styles.less @@ -0,0 +1,91 @@ +@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less'; + +.shortcuts-modal { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; + align-items: center; + justify-content: center; + + .backdrop { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: @color-background-dark5-40; + cursor: pointer; + } + + .container { + position: relative; + display: flex; + flex-direction: column; + gap: 1rem; + max-height: 80%; + max-width: 80%; + border-radius: var(--border-radius); + background-color: var(--modal-background-color); + box-shadow: var(--outer-glow); + overflow-y: auto; + + .header { + flex: none; + display: flex; + justify-content: space-between; + align-items: center; + height: 5rem; + padding-left: 2.5rem; + padding-right: 1rem; + + .title { + position: relative; + font-size: 1.5rem; + font-weight: 500; + color: var(--primary-foreground-color); + } + + .close-button { + position: relative; + width: 3rem; + height: 3rem; + padding: 0.5rem; + border-radius: var(--border-radius); + z-index: 2; + + .icon { + display: block; + width: 100%; + height: 100%; + color: var(--primary-foreground-color); + opacity: 0.4; + } + + &:hover, &:focus { + .icon { + opacity: 1; + color: var(--primary-foreground-color); + } + } + + &:focus { + outline-color: var(--primary-foreground-color); + } + } + } + + .content { + position: relative; + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 3rem; + padding: 0 2.5rem; + padding-bottom: 2rem; + overflow-y: auto; + } + } +} \ No newline at end of file diff --git a/src/common/Shortcuts/Shortcuts.tsx b/src/common/Shortcuts/Shortcuts.tsx new file mode 100644 index 000000000..f41e08271 --- /dev/null +++ b/src/common/Shortcuts/Shortcuts.tsx @@ -0,0 +1,54 @@ +import React, { createContext, useCallback, useContext, useEffect } from 'react'; +import shortcuts from './shortcuts'; + +const SHORTCUTS = shortcuts.map(({ shortcuts }) => shortcuts).flat(); + +export type ShortcutName = string; +export type ShortcutListener = () => void; + +interface ShortcutsContext { + grouped: ShortcutGroup[], +} + +const ShortcutsContext = createContext({} as ShortcutsContext); + +type Props = { + children: JSX.Element, + onShortcut: (name: ShortcutName) => void, +}; + +const ShortcutsProvider = ({ children, onShortcut }: Props) => { + const onKeyDown = useCallback(({ ctrlKey, shiftKey, key }: KeyboardEvent) => { + SHORTCUTS.forEach(({ name, combos }) => combos.forEach((keys) => { + const modifers = (keys.includes('Ctrl') ? ctrlKey : true) + && (keys.includes('Shift') ? shiftKey : true); + + if (modifers && keys.includes(key.toUpperCase())) { + onShortcut(name as ShortcutName); + } + })); + }, [onShortcut]); + + useEffect(() => { + document.addEventListener('keydown', onKeyDown); + + return () => { + document.removeEventListener('keydown', onKeyDown); + }; + }, [onKeyDown]); + + return ( + + {children} + + ); +}; + +const useShortcuts = () => { + return useContext(ShortcutsContext); +}; + +export { + ShortcutsProvider, + useShortcuts +}; diff --git a/src/common/Shortcuts/index.ts b/src/common/Shortcuts/index.ts new file mode 100644 index 000000000..f7fa38a18 --- /dev/null +++ b/src/common/Shortcuts/index.ts @@ -0,0 +1,5 @@ +import { ShortcutsProvider, useShortcuts } from './Shortcuts'; +export { + ShortcutsProvider, + useShortcuts, +}; diff --git a/src/common/Shortcuts/shortcuts.ts b/src/common/Shortcuts/shortcuts.ts new file mode 100644 index 000000000..d918733af --- /dev/null +++ b/src/common/Shortcuts/shortcuts.ts @@ -0,0 +1,91 @@ +const shortcuts: ShortcutGroup[] = [ + { + name: 'general', + label: 'SETTINGS_NAV_GENERAL', + shortcuts: [ + { + name: 'navigateTabs', + label: 'SETTINGS_SHORTCUT_NAVIGATE_MENUS', + combos: [['1', '2', '3', '4', '5', '6']], + }, + { + name: 'navigateSearch', + label: 'SETTINGS_SHORTCUT_GO_TO_SEARCH', + combos: [['0']], + }, + { + name: 'fullscreen', + label: 'SETTINGS_SHORTCUT_FULLSCREEN', + combos: [['F']], + }, + { + name: 'exit', + label: 'SETTINGS_SHORTCUT_EXIT_BACK', + combos: [['Escape']], + }, + { + name: 'shortcuts', + label: 'SETTINGS_SHORTCUT_SHORTCUTS', + combos: [['Ctrl', '?']], + }, + ] + }, + { + name: 'player', + label: 'SETTINGS_NAV_PLAYER', + shortcuts: [ + { + name: 'playPause', + label: 'SETTINGS_SHORTCUT_PLAY_PAUSE', + combos: [['Space']], + }, + { + name: 'seekForward', + label: 'SETTINGS_SHORTCUT_SEEK_FORWARD', + combos: [['ArrowRight'], ['Shift', 'ArrowRight']], + }, + { + name: 'seekBackward', + label: 'SETTINGS_SHORTCUT_SEEK_BACKWARD', + combos: [['ArrowLeft'], ['Shift', 'ArrowLeft']], + }, + { + name: 'volumeUp', + label: 'SETTINGS_SHORTCUT_VOLUME_UP', + combos: [['ArrowUp']], + }, + { + name: 'volumeDown', + label: 'SETTINGS_SHORTCUT_VOLUME_DOWN', + combos: [['ArrowDown']], + }, + { + name: 'subtitlesSize', + label: 'SETTINGS_SHORTCUT_SUBTITLES_SIZE', + combos: [['-'], ['=']], + }, + { + name: 'subtitlesDelay', + label: 'SETTINGS_SHORTCUT_SUBTITLES_DELAY', + combos: [['G'], ['H']], + }, + { + name: 'subtitlesMenu', + label: 'SETTINGS_SHORTCUT_MENU_SUBTITLES', + combos: [['S']], + }, + { + name: 'audioMenu', + label: 'SETTINGS_SHORTCUT_MENU_AUDIO', + combos: [['A']], + }, + { + name: 'infoMenu', + label: 'SETTINGS_SHORTCUT_MENU_INFO', + combos: [['I']], + }, + ] + }, +]; + +export default shortcuts; diff --git a/src/common/Shortcuts/types.d.ts b/src/common/Shortcuts/types.d.ts new file mode 100644 index 000000000..e4180616d --- /dev/null +++ b/src/common/Shortcuts/types.d.ts @@ -0,0 +1,11 @@ +type Shortcut = { + name: string, + label: string, + combos: string[][], +}; + +type ShortcutGroup = { + name: string, + label: string, + shortcuts: Shortcut[], +}; diff --git a/src/common/index.js b/src/common/index.js index 25df5c158..0b9cb252f 100644 --- a/src/common/index.js +++ b/src/common/index.js @@ -4,6 +4,7 @@ const { FileDropProvider, onFileDrop } = require('./FileDrop'); const { PlatformProvider, usePlatform } = require('./Platform'); const { ToastProvider, useToast } = require('./Toast'); const { TooltipProvider, Tooltip } = require('./Tooltips'); +const { ShortcutsProvider, useShortcuts } = require('./Shortcuts'); const comparatorWithPriorities = require('./comparatorWithPriorities'); const CONSTANTS = require('./CONSTANTS'); const { withCoreSuspender, useCoreSuspender } = require('./CoreSuspender'); @@ -35,6 +36,8 @@ module.exports = { onFileDrop, PlatformProvider, usePlatform, + ShortcutsProvider, + useShortcuts, ToastProvider, useToast, TooltipProvider, diff --git a/src/components/ShortcutsGroup/Combos/Combos.less b/src/components/ShortcutsGroup/Combos/Combos.less new file mode 100644 index 000000000..a862d54ca --- /dev/null +++ b/src/components/ShortcutsGroup/Combos/Combos.less @@ -0,0 +1,22 @@ +.combos { + position: relative; + display: flex; + overflow: visible; + + .combo { + position: relative; + display: flex; + overflow: visible; + + .separator { + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 3.5rem; + font-size: 1rem; + color: var(--primary-foreground-color); + opacity: 0.6; + } + } +} \ No newline at end of file diff --git a/src/components/ShortcutsGroup/Combos/Combos.tsx b/src/components/ShortcutsGroup/Combos/Combos.tsx new file mode 100644 index 000000000..0168441bc --- /dev/null +++ b/src/components/ShortcutsGroup/Combos/Combos.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import Keys from './Keys'; +import styles from './Combos.less'; + +type Props = { + combos: string[][], +}; + +const Combos = ({ combos }: Props) => { + const { t } = useTranslation(); + + return ( +
+ { + combos.map((keys, index) => ( +
+ + { + index < (combos.length - 1) && ( +
+ { t('SETTINGS_SHORTCUT_OR') } +
+ ) + } +
+ )) + } +
+ ); +}; + +export default Combos; diff --git a/src/components/ShortcutsGroup/Combos/Keys/Keys.less b/src/components/ShortcutsGroup/Combos/Keys/Keys.less new file mode 100644 index 000000000..7bb8c76e7 --- /dev/null +++ b/src/components/ShortcutsGroup/Combos/Keys/Keys.less @@ -0,0 +1,26 @@ +kbd { + flex: none; + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; + height: 2.5rem; + min-width: 2.5rem; + padding: 0 1rem; + font-size: 1rem; + font-weight: 500; + color: var(--primary-foreground-color); + border-radius: 0.25em; + box-shadow: 0 4px 0 1px rgba(255, 255, 255, 0.1); + background-color: var(--overlay-color); +} + +.separator { + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 2.5rem; + font-size: 1rem; + color: var(--primary-foreground-color); +} \ No newline at end of file diff --git a/src/components/ShortcutsGroup/Combos/Keys/Keys.tsx b/src/components/ShortcutsGroup/Combos/Keys/Keys.tsx new file mode 100644 index 000000000..71ec610da --- /dev/null +++ b/src/components/ShortcutsGroup/Combos/Keys/Keys.tsx @@ -0,0 +1,51 @@ +import React, { Fragment, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; +import styles from './Keys.less'; + +type Props = { + keys: string[], +}; + +const Keys = ({ keys }: Props) => { + const { t } = useTranslation(); + + const keyLabelMap: Record = useMemo(() => ({ + 'Shift': `⇧ ${t('SETTINGS_SHORTCUT_SHIFT')}`, + 'Space': t('SETTINGS_SHORTCUT_SPACE'), + 'Ctrl': t('SETTINGS_SHORTCUT_CTRL'), + 'Escape': t('SETTINGS_SHORTCUT_ESC'), + 'ArrowUp': '↑', + 'ArrowDown': '↓', + 'ArrowLeft': '←', + 'ArrowRight': '→', + }), [t]); + + const isRange = useMemo(() => { + return keys.length > 1 && keys.every((key) => !Number.isNaN(parseInt(key))); + }, [keys]); + + const filteredKeys = useMemo(() => { + return isRange ? [keys[0], keys[keys.length - 1]] : keys; + }, [keys, isRange]); + + return ( + filteredKeys.map((key, index) => ( + + + {keyLabelMap[key] ?? key.toUpperCase()} + + { + index < (filteredKeys.length - 1) && ( +
+ { + isRange ? t('SETTINGS_SHORTCUT_TO') : '+' + } +
+ ) + } +
+ )) + ); +}; + +export default Keys; diff --git a/src/components/ShortcutsGroup/Combos/Keys/index.ts b/src/components/ShortcutsGroup/Combos/Keys/index.ts new file mode 100644 index 000000000..ba8d58731 --- /dev/null +++ b/src/components/ShortcutsGroup/Combos/Keys/index.ts @@ -0,0 +1,2 @@ +import Keys from './Keys'; +export default Keys; diff --git a/src/components/ShortcutsGroup/Combos/index.ts b/src/components/ShortcutsGroup/Combos/index.ts new file mode 100644 index 000000000..c66667f91 --- /dev/null +++ b/src/components/ShortcutsGroup/Combos/index.ts @@ -0,0 +1,2 @@ +import Combos from './Combos'; +export default Combos; diff --git a/src/components/ShortcutsGroup/ShortcutsGroup.less b/src/components/ShortcutsGroup/ShortcutsGroup.less new file mode 100644 index 000000000..f0fdd975c --- /dev/null +++ b/src/components/ShortcutsGroup/ShortcutsGroup.less @@ -0,0 +1,44 @@ +.shortcuts-group { + flex: 1 1 0; + position: relative; + min-width: 30rem; + display: flex; + flex-direction: column; + gap: 2rem; + overflow: visible; + + .title { + flex: none; + display: flex; + font-size: 1rem; + font-weight: 400; + color: var(--primary-foreground-color); + opacity: 0.6; + } + + .shortcuts { + position: relative; + display: flex; + flex-direction: column; + gap: 2rem; + overflow: visible; + + .shortcut { + position: relative; + display: flex; + align-items: center; + justify-content: space-between; + gap: 2rem; + overflow: visible; + + .label { + position: relative; + font-size: 1rem; + color: var(--primary-foreground-color); + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + } + } + } +} diff --git a/src/components/ShortcutsGroup/ShortcutsGroup.tsx b/src/components/ShortcutsGroup/ShortcutsGroup.tsx new file mode 100644 index 000000000..069d5d1e8 --- /dev/null +++ b/src/components/ShortcutsGroup/ShortcutsGroup.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import classNames from 'classnames'; +import { useTranslation } from 'react-i18next'; +import Combos from './Combos'; +import styles from './ShortcutsGroup.less'; + +type Props = { + className?: string, + label: string, + shortcuts: Shortcut[], +}; + +const ShortcutsGroup = ({ className, label, shortcuts }: Props) => { + const { t } = useTranslation(); + + return ( +
+
+ {t(label)} +
+ +
+ { + shortcuts.map(({ name, label, combos }) => ( +
+
+ {t(label)} +
+ +
+ )) + } +
+
+ ); +}; + +export default ShortcutsGroup; diff --git a/src/components/ShortcutsGroup/index.ts b/src/components/ShortcutsGroup/index.ts new file mode 100644 index 000000000..11f8d0678 --- /dev/null +++ b/src/components/ShortcutsGroup/index.ts @@ -0,0 +1,2 @@ +import ShortcutsGroup from './ShortcutsGroup'; +export default ShortcutsGroup; diff --git a/src/components/index.ts b/src/components/index.ts index a5638007e..a47c2c709 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -25,6 +25,7 @@ import RadioButton from './RadioButton'; import SearchBar from './SearchBar'; import SharePrompt from './SharePrompt'; import Slider from './Slider'; +import ShortcutsGroup from './ShortcutsGroup'; import TextInput from './TextInput'; import Toggle from './Toggle'; import Transition from './Transition'; @@ -59,6 +60,7 @@ export { SearchBar, SharePrompt, Slider, + ShortcutsGroup, TextInput, Toggle, Transition, diff --git a/src/routes/Settings/Shortcuts/Shortcuts.less b/src/routes/Settings/Shortcuts/Shortcuts.less index 40d97987d..186cfa837 100644 --- a/src/routes/Settings/Shortcuts/Shortcuts.less +++ b/src/routes/Settings/Shortcuts/Shortcuts.less @@ -1,27 +1,4 @@ -.shortcut-container { - display: flex; - align-items: center; - justify-content: center; - padding: 0; - overflow: visible; - - kbd { - flex: 0 1 auto; - height: 2.5rem; - min-width: 2.5rem; - line-height: 2.5rem; - padding: 0 1rem; - font-weight: 500; - color: var(--primary-foreground-color); - border-radius: 0.25em; - box-shadow: 0 4px 0 1px var(--modal-background-color); - background-color: var(--overlay-color); - } - - .label { - flex: none; - margin: 0 1rem; - white-space: nowrap; - color: var(--primary-foreground-color); - } +.shortcuts-group { + width: 100%; + margin-bottom: 3rem; } \ No newline at end of file diff --git a/src/routes/Settings/Shortcuts/Shortcuts.tsx b/src/routes/Settings/Shortcuts/Shortcuts.tsx index d852280a6..a0599a503 100644 --- a/src/routes/Settings/Shortcuts/Shortcuts.tsx +++ b/src/routes/Settings/Shortcuts/Shortcuts.tsx @@ -1,97 +1,24 @@ import React, { forwardRef } from 'react'; -import { Section, Option } from '../components'; +import { Section } from '../components'; +import { ShortcutsGroup } from 'stremio/components'; +import { useShortcuts } from 'stremio/common'; import styles from './Shortcuts.less'; -import { useTranslation } from 'react-i18next'; const Shortcuts = forwardRef((_, ref) => { - const { t } = useTranslation(); + const { grouped } = useShortcuts(); return (
- - - - - - - - - - - - - - + { + grouped.map(({ name, label, shortcuts }) => ( + + )) + }
); }); diff --git a/tsconfig.json b/tsconfig.json index d55ac9356..c4b0a8626 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "lib": [ "ES2016", "DOM", "DOM.Iterable"], + "lib": ["ESNext", "DOM", "DOM.Iterable"], "jsx": "react", "baseUrl": "./src", "outDir": "./dist", From 539a7ebc10c8840c34d69f4c667b63da0da9ae8b Mon Sep 17 00:00:00 2001 From: Victor Sales <36749678+v1ctorsales@users.noreply.github.com> Date: Sun, 12 Oct 2025 13:41:42 +0300 Subject: [PATCH 15/33] fix(calendar): align day and more indicator inline in narrow desktop viewports --- src/routes/Calendar/Table/Cell/Cell.less | 69 +++++++++++++++--------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/src/routes/Calendar/Table/Cell/Cell.less b/src/routes/Calendar/Table/Cell/Cell.less index e989b4cf7..d66084392 100644 --- a/src/routes/Calendar/Table/Cell/Cell.less +++ b/src/routes/Calendar/Table/Cell/Cell.less @@ -28,7 +28,7 @@ .heading { position: relative; - width: 60%; + width: 100%; display: flex; align-items: start; padding: 0; @@ -52,7 +52,7 @@ position: relative; display: flex; flex-direction: row; - gap: 1rem; + gap: 0.1em; padding: 0.1rem; width: 90%; @@ -80,13 +80,10 @@ } .poster { - flex: auto; - z-index: 0; - position: relative; - height: 100%; - width: 100%; + height: auto; + max-height: 100%; + aspect-ratio: 2 / 3; object-fit: cover; - opacity: 1; } .icon, .poster { @@ -134,27 +131,19 @@ } } -@media only screen and (orientation: portrait) { +@media @phone-portrait { .cell { flex-direction: column; display: grid; - .heading { - justify-content: center; - } .items { - padding: 1px; - gap: 0.15rem; - justify-content: space-evenly; + padding: 1px; + gap: 0.15rem; + justify-content: space-evenly; - .item{ - width: 80%; - } - } - - .more { - display: flex; - display: none; + .item { + width: 80%; + } } } } @@ -180,4 +169,36 @@ } } } -} \ No newline at end of file +} + +@media only screen and (max-width: @minimum) and (orientation: portrait) and (pointer: fine) { + .cell { + position: relative; + flex-direction: row; + align-items: center; + display: flex; + + .items { + display: none; + } + + .heading { + display: flex; + align-items: center; + gap: 0.25rem; + width: auto; + } + + .day { + margin-right: 0.25rem; + } + + .more { + display: inline-flex; + position: relative; + height: auto; + padding: 0; + width: 30%; + } + } +} From fb9497a85631f28bc4eca0a39a45e52f608d496a Mon Sep 17 00:00:00 2001 From: Victor Sales <36749678+v1ctorsales@users.noreply.github.com> Date: Sun, 12 Oct 2025 18:23:34 +0300 Subject: [PATCH 16/33] feat(calendar): redesign calendar cell layout for responsiveness and banner support --- src/routes/Calendar/Table/Cell/Cell.less | 56 +++++++++++------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/src/routes/Calendar/Table/Cell/Cell.less b/src/routes/Calendar/Table/Cell/Cell.less index d66084392..0fdf615d2 100644 --- a/src/routes/Calendar/Table/Cell/Cell.less +++ b/src/routes/Calendar/Table/Cell/Cell.less @@ -28,10 +28,9 @@ .heading { position: relative; - width: 100%; + flex: 1 1 40%; display: flex; - align-items: start; - padding: 0; + align-items: flex-start; .day { flex: none; @@ -54,7 +53,10 @@ flex-direction: row; gap: 0.1em; padding: 0.1rem; - width: 90%; + flex: 1 1 60%; + overflow-x: auto; + overflow-y: hidden; + min-width: 0; .item { flex: none; @@ -63,8 +65,9 @@ justify-content: center; height: 100%; aspect-ratio: 2 / 3; - border-radius: var(--border-radius); - max-height: clamp(8rem, 25vh, 14rem); + border-radius: calc(var(--border-radius) /2); + max-height: 100%; + width: 100%; .icon { flex: none; @@ -84,6 +87,7 @@ max-height: 100%; aspect-ratio: 2 / 3; object-fit: cover; + border-radius: inherit } .icon, .poster { @@ -115,7 +119,10 @@ &.today { .heading { .day { + width: auto; background-color: var(--primary-accent-color); + height: auto; + padding: 0.3rem; } } } @@ -142,12 +149,21 @@ justify-content: space-evenly; .item { - width: 80%; + width: 100%; } } } } +@media only screen and (max-height: @xxsmall) and (max-width: @xxsmall) and (orientation: landscape) { + .cell{ + .items{ + width: 100%; + } + } +} + + @media only screen and (max-height: @medium) and (max-width: @medium) and (orientation: landscape) { .cell { gap: 0; @@ -161,12 +177,6 @@ .items { width: 100%; - - .item { - pointer-events: none; - border-radius: calc(var(--border-radius) / 2); - width: 80%; - } } } } @@ -175,30 +185,16 @@ .cell { position: relative; flex-direction: row; - align-items: center; display: flex; - .items { - display: none; - } - .heading { display: flex; - align-items: center; gap: 0.25rem; width: auto; - } + .day{ + font-size: 0.6rem; + } - .day { - margin-right: 0.25rem; - } - - .more { - display: inline-flex; - position: relative; - height: auto; - padding: 0; - width: 30%; } } } From 4860a028c2410bed51e6155b8147de8ceacc1e39 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 13 Oct 2025 11:29:16 +0200 Subject: [PATCH 17/33] chore: update translations --- package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index c824ad411..61e713041 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "react-i18next": "^15.1.3", "react-is": "18.3.1", "spatial-navigation-polyfill": "github:Stremio/spatial-navigation#64871b1422466f5f45d24ebc8bbd315b2ebab6a6", - "stremio-translations": "github:Stremio/stremio-translations#abe7684165a031755e9aee39da26daa806ba7824", + "stremio-translations": "github:Stremio/stremio-translations#5e5e3776ff1a1684648eaa3fa6c3a6caeb67cc37", "url": "0.11.4", "use-long-press": "^3.2.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 121d0dbea..110fd7d71 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -90,8 +90,8 @@ importers: specifier: github:Stremio/spatial-navigation#64871b1422466f5f45d24ebc8bbd315b2ebab6a6 version: https://codeload.github.com/Stremio/spatial-navigation/tar.gz/64871b1422466f5f45d24ebc8bbd315b2ebab6a6 stremio-translations: - specifier: github:Stremio/stremio-translations#abe7684165a031755e9aee39da26daa806ba7824 - version: https://codeload.github.com/Stremio/stremio-translations/tar.gz/abe7684165a031755e9aee39da26daa806ba7824 + specifier: github:Stremio/stremio-translations#5e5e3776ff1a1684648eaa3fa6c3a6caeb67cc37 + version: https://codeload.github.com/Stremio/stremio-translations/tar.gz/5e5e3776ff1a1684648eaa3fa6c3a6caeb67cc37 url: specifier: 0.11.4 version: 0.11.4 @@ -4527,9 +4527,9 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} - stremio-translations@https://codeload.github.com/Stremio/stremio-translations/tar.gz/abe7684165a031755e9aee39da26daa806ba7824: - resolution: {tarball: https://codeload.github.com/Stremio/stremio-translations/tar.gz/abe7684165a031755e9aee39da26daa806ba7824} - version: 1.44.12 + stremio-translations@https://codeload.github.com/Stremio/stremio-translations/tar.gz/5e5e3776ff1a1684648eaa3fa6c3a6caeb67cc37: + resolution: {tarball: https://codeload.github.com/Stremio/stremio-translations/tar.gz/5e5e3776ff1a1684648eaa3fa6c3a6caeb67cc37} + version: 1.44.13 string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} @@ -10283,7 +10283,7 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 - stremio-translations@https://codeload.github.com/Stremio/stremio-translations/tar.gz/abe7684165a031755e9aee39da26daa806ba7824: {} + stremio-translations@https://codeload.github.com/Stremio/stremio-translations/tar.gz/5e5e3776ff1a1684648eaa3fa6c3a6caeb67cc37: {} string-length@4.0.2: dependencies: From 2e1ad64d02b23b7a508a708acab62616d4e79acd Mon Sep 17 00:00:00 2001 From: Victor Sales <36749678+v1ctorsales@users.noreply.github.com> Date: Mon, 13 Oct 2025 13:06:52 +0300 Subject: [PATCH 18/33] refactor(calendar): replace fixed width with max-width for better banner scaling --- src/routes/Calendar/Table/Cell/Cell.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/Calendar/Table/Cell/Cell.less b/src/routes/Calendar/Table/Cell/Cell.less index 0fdf615d2..95116de20 100644 --- a/src/routes/Calendar/Table/Cell/Cell.less +++ b/src/routes/Calendar/Table/Cell/Cell.less @@ -51,7 +51,7 @@ position: relative; display: flex; flex-direction: row; - gap: 0.1em; + gap: 0.2rem; padding: 0.1rem; flex: 1 1 60%; overflow-x: auto; @@ -67,7 +67,7 @@ aspect-ratio: 2 / 3; border-radius: calc(var(--border-radius) /2); max-height: 100%; - width: 100%; + max-width: 100%; .icon { flex: none; From e74072ebd5c2e548589630022d2dae156d3cebaf Mon Sep 17 00:00:00 2001 From: Victor Sales <36749678+v1ctorsales@users.noreply.github.com> Date: Mon, 13 Oct 2025 13:40:13 +0300 Subject: [PATCH 19/33] fix(calendar): disable banner click in phone-portrait mode --- src/routes/Calendar/Table/Cell/Cell.less | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/routes/Calendar/Table/Cell/Cell.less b/src/routes/Calendar/Table/Cell/Cell.less index 95116de20..3a103c913 100644 --- a/src/routes/Calendar/Table/Cell/Cell.less +++ b/src/routes/Calendar/Table/Cell/Cell.less @@ -138,6 +138,17 @@ } } +@media only screen and (max-width: @minimum) and (orientation: portrait) { + .cell{ + .items{ + .item{ + pointer-events: none; + } + + } + } +} + @media @phone-portrait { .cell { flex-direction: column; @@ -150,6 +161,7 @@ .item { width: 100%; + pointer-events: none; } } } @@ -187,6 +199,12 @@ flex-direction: row; display: flex; + .items{ + .item{ + pointer-events: none; + } + } + .heading { display: flex; gap: 0.25rem; From a97dd01869f0342f0449b4d40278ea2b7a4a70e4 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 13 Oct 2025 12:55:12 +0200 Subject: [PATCH 20/33] refactor(shortcuts): use Ctrl + / for shortcuts modal --- src/common/Shortcuts/shortcuts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/Shortcuts/shortcuts.ts b/src/common/Shortcuts/shortcuts.ts index d918733af..614495f0a 100644 --- a/src/common/Shortcuts/shortcuts.ts +++ b/src/common/Shortcuts/shortcuts.ts @@ -26,7 +26,7 @@ const shortcuts: ShortcutGroup[] = [ { name: 'shortcuts', label: 'SETTINGS_SHORTCUT_SHORTCUTS', - combos: [['Ctrl', '?']], + combos: [['Ctrl', '/']], }, ] }, From d2d28be6ded2956837e6167854d99fd78f5cff8d Mon Sep 17 00:00:00 2001 From: Victor Sales <36749678+v1ctorsales@users.noreply.github.com> Date: Mon, 13 Oct 2025 16:27:15 +0300 Subject: [PATCH 21/33] style(responsive): add @phone-landscape media query --- src/routes/Calendar/Table/Cell/Cell.less | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/routes/Calendar/Table/Cell/Cell.less b/src/routes/Calendar/Table/Cell/Cell.less index 3a103c913..754715f32 100644 --- a/src/routes/Calendar/Table/Cell/Cell.less +++ b/src/routes/Calendar/Table/Cell/Cell.less @@ -167,12 +167,19 @@ } } -@media only screen and (max-height: @xxsmall) and (max-width: @xxsmall) and (orientation: landscape) { - .cell{ - .items{ - width: 100%; +@media @phone-landscape { + .cell { + flex-direction: row; + + .items { + padding: 1px; + gap: 0.15rem; + + .item { + pointer-events: none; + } + } } - } } From 56b60beedbb0c04cad82d3d6ad32264340a7f0e9 Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Tue, 14 Oct 2025 11:39:28 +0300 Subject: [PATCH 22/33] fix: useFullscreen - catch exception on Firefox when using keyboard F shortcut in web Signed-off-by: Lachezar Lechev --- src/common/useFullscreen.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common/useFullscreen.ts b/src/common/useFullscreen.ts index 69cdcd494..0e5c13f42 100644 --- a/src/common/useFullscreen.ts +++ b/src/common/useFullscreen.ts @@ -14,7 +14,9 @@ const useFullscreen = () => { if (shell.active) { shell.send('win-set-visibility', { fullscreen: true }); } else { - document.documentElement.requestFullscreen(); + document.documentElement.requestFullscreen().catch((err) => { + console.error(`Error enabling fullscreen: ${err.message}`); + }); } }, []); From 91fbfc1178dacb9783f881e00dc1e3d5907b9e47 Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Tue, 14 Oct 2025 12:00:43 +0300 Subject: [PATCH 23/33] fix: useFullscreen - catch exception on Firefox when using keyboard F shortcut in web Signed-off-by: Lachezar Lechev --- src/common/useFullscreen.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/common/useFullscreen.ts b/src/common/useFullscreen.ts index 0e5c13f42..8a1692254 100644 --- a/src/common/useFullscreen.ts +++ b/src/common/useFullscreen.ts @@ -10,13 +10,15 @@ const useFullscreen = () => { const [fullscreen, setFullscreen] = useState(false); - const requestFullscreen = useCallback(() => { + const requestFullscreen = useCallback(async () => { if (shell.active) { shell.send('win-set-visibility', { fullscreen: true }); } else { - document.documentElement.requestFullscreen().catch((err) => { - console.error(`Error enabling fullscreen: ${err.message}`); - }); + try { + await document.documentElement.requestFullscreen(); + } catch (err) { + console.error('Error enabling fullscreen', err); + } } }, []); From 5c3b2b0b224132265fa192bb1448800a76045e0d Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 14 Oct 2025 17:22:08 +0200 Subject: [PATCH 24/33] refactor(Shortcuts): use json to declare shortcuts --- src/common/Shortcuts/Shortcuts.tsx | 2 +- src/common/Shortcuts/shortcuts.json | 89 ++++++++++++++++++++++++++++ src/common/Shortcuts/shortcuts.ts | 91 ----------------------------- 3 files changed, 90 insertions(+), 92 deletions(-) create mode 100644 src/common/Shortcuts/shortcuts.json delete mode 100644 src/common/Shortcuts/shortcuts.ts diff --git a/src/common/Shortcuts/Shortcuts.tsx b/src/common/Shortcuts/Shortcuts.tsx index f41e08271..532e9a409 100644 --- a/src/common/Shortcuts/Shortcuts.tsx +++ b/src/common/Shortcuts/Shortcuts.tsx @@ -1,5 +1,5 @@ import React, { createContext, useCallback, useContext, useEffect } from 'react'; -import shortcuts from './shortcuts'; +import shortcuts from './shortcuts.json'; const SHORTCUTS = shortcuts.map(({ shortcuts }) => shortcuts).flat(); diff --git a/src/common/Shortcuts/shortcuts.json b/src/common/Shortcuts/shortcuts.json new file mode 100644 index 000000000..766288fb0 --- /dev/null +++ b/src/common/Shortcuts/shortcuts.json @@ -0,0 +1,89 @@ +[ + { + "name": "general", + "label": "SETTINGS_NAV_GENERAL", + "shortcuts": [ + { + "name": "navigateTabs", + "label": "SETTINGS_SHORTCUT_NAVIGATE_MENUS", + "combos": [["1", "2", "3", "4", "5", "6"]] + }, + { + "name": "navigateSearch", + "label": "SETTINGS_SHORTCUT_GO_TO_SEARCH", + "combos": [["0"]] + }, + { + "name": "fullscreen", + "label": "SETTINGS_SHORTCUT_FULLSCREEN", + "combos": [["F"]] + }, + { + "name": "exit", + "label": "SETTINGS_SHORTCUT_EXIT_BACK", + "combos": [["Escape"]] + }, + { + "name": "shortcuts", + "label": "SETTINGS_SHORTCUT_SHORTCUTS", + "combos": [["Ctrl", "/"]] + } + ] + }, + { + "name": "player", + "label": "SETTINGS_NAV_PLAYER", + "shortcuts": [ + { + "name": "playPause", + "label": "SETTINGS_SHORTCUT_PLAY_PAUSE", + "combos": [["Space"]] + }, + { + "name": "seekForward", + "label": "SETTINGS_SHORTCUT_SEEK_FORWARD", + "combos": [["ArrowRight"], ["Shift", "ArrowRight"]] + }, + { + "name": "seekBackward", + "label": "SETTINGS_SHORTCUT_SEEK_BACKWARD", + "combos": [["ArrowLeft"], ["Shift", "ArrowLeft"]] + }, + { + "name": "volumeUp", + "label": "SETTINGS_SHORTCUT_VOLUME_UP", + "combos": [["ArrowUp"]] + }, + { + "name": "volumeDown", + "label": "SETTINGS_SHORTCUT_VOLUME_DOWN", + "combos": [["ArrowDown"]] + }, + { + "name": "subtitlesSize", + "label": "SETTINGS_SHORTCUT_SUBTITLES_SIZE", + "combos": [["-"], ["="]] + }, + { + "name": "subtitlesDelay", + "label": "SETTINGS_SHORTCUT_SUBTITLES_DELAY", + "combos": [["G"], ["H"]] + }, + { + "name": "subtitlesMenu", + "label": "SETTINGS_SHORTCUT_MENU_SUBTITLES", + "combos": [["S"]] + }, + { + "name": "audioMenu", + "label": "SETTINGS_SHORTCUT_MENU_AUDIO", + "combos": [["A"]] + }, + { + "name": "infoMenu", + "label": "SETTINGS_SHORTCUT_MENU_INFO", + "combos": [["I"]] + } + ] + } +] \ No newline at end of file diff --git a/src/common/Shortcuts/shortcuts.ts b/src/common/Shortcuts/shortcuts.ts deleted file mode 100644 index 614495f0a..000000000 --- a/src/common/Shortcuts/shortcuts.ts +++ /dev/null @@ -1,91 +0,0 @@ -const shortcuts: ShortcutGroup[] = [ - { - name: 'general', - label: 'SETTINGS_NAV_GENERAL', - shortcuts: [ - { - name: 'navigateTabs', - label: 'SETTINGS_SHORTCUT_NAVIGATE_MENUS', - combos: [['1', '2', '3', '4', '5', '6']], - }, - { - name: 'navigateSearch', - label: 'SETTINGS_SHORTCUT_GO_TO_SEARCH', - combos: [['0']], - }, - { - name: 'fullscreen', - label: 'SETTINGS_SHORTCUT_FULLSCREEN', - combos: [['F']], - }, - { - name: 'exit', - label: 'SETTINGS_SHORTCUT_EXIT_BACK', - combos: [['Escape']], - }, - { - name: 'shortcuts', - label: 'SETTINGS_SHORTCUT_SHORTCUTS', - combos: [['Ctrl', '/']], - }, - ] - }, - { - name: 'player', - label: 'SETTINGS_NAV_PLAYER', - shortcuts: [ - { - name: 'playPause', - label: 'SETTINGS_SHORTCUT_PLAY_PAUSE', - combos: [['Space']], - }, - { - name: 'seekForward', - label: 'SETTINGS_SHORTCUT_SEEK_FORWARD', - combos: [['ArrowRight'], ['Shift', 'ArrowRight']], - }, - { - name: 'seekBackward', - label: 'SETTINGS_SHORTCUT_SEEK_BACKWARD', - combos: [['ArrowLeft'], ['Shift', 'ArrowLeft']], - }, - { - name: 'volumeUp', - label: 'SETTINGS_SHORTCUT_VOLUME_UP', - combos: [['ArrowUp']], - }, - { - name: 'volumeDown', - label: 'SETTINGS_SHORTCUT_VOLUME_DOWN', - combos: [['ArrowDown']], - }, - { - name: 'subtitlesSize', - label: 'SETTINGS_SHORTCUT_SUBTITLES_SIZE', - combos: [['-'], ['=']], - }, - { - name: 'subtitlesDelay', - label: 'SETTINGS_SHORTCUT_SUBTITLES_DELAY', - combos: [['G'], ['H']], - }, - { - name: 'subtitlesMenu', - label: 'SETTINGS_SHORTCUT_MENU_SUBTITLES', - combos: [['S']], - }, - { - name: 'audioMenu', - label: 'SETTINGS_SHORTCUT_MENU_AUDIO', - combos: [['A']], - }, - { - name: 'infoMenu', - label: 'SETTINGS_SHORTCUT_MENU_INFO', - combos: [['I']], - }, - ] - }, -]; - -export default shortcuts; From 83752eb647b1c9b5a15c70fcbe326e02be82b14a Mon Sep 17 00:00:00 2001 From: Victor Sales <36749678+v1ctorsales@users.noreply.github.com> Date: Tue, 14 Oct 2025 18:34:43 +0300 Subject: [PATCH 25/33] fix(calendar): adaptive display and style fixes --- src/routes/Calendar/Table/Cell/Cell.less | 59 +++++++++--------------- 1 file changed, 21 insertions(+), 38 deletions(-) diff --git a/src/routes/Calendar/Table/Cell/Cell.less b/src/routes/Calendar/Table/Cell/Cell.less index 754715f32..d5202c53d 100644 --- a/src/routes/Calendar/Table/Cell/Cell.less +++ b/src/routes/Calendar/Table/Cell/Cell.less @@ -5,7 +5,7 @@ .cell { position: relative; display: flex; - flex-direction: row; + flex-direction: column; justify-content: space-between; gap: 0.5rem; background-color: var(--overlay-color); @@ -28,9 +28,8 @@ .heading { position: relative; - flex: 1 1 40%; display: flex; - align-items: flex-start; + align-items: center; .day { flex: none; @@ -65,7 +64,7 @@ justify-content: center; height: 100%; aspect-ratio: 2 / 3; - border-radius: calc(var(--border-radius) /2); + border-radius: calc(var(--border-radius) / 2); max-height: 100%; max-width: 100%; @@ -118,11 +117,11 @@ &.today { .heading { + padding: 0.3rem; .day { - width: auto; background-color: var(--primary-accent-color); - height: auto; - padding: 0.3rem; + height: 1.5rem; + width: 1.5rem; } } } @@ -138,15 +137,14 @@ } } -@media only screen and (max-width: @minimum) and (orientation: portrait) { - .cell{ - .items{ - .item{ - pointer-events: none; +@media only screen and (max-width: @minimum) { + .cell { + .items { + .item { + pointer-events: none; + } } - } - } } @media @phone-portrait { @@ -157,10 +155,8 @@ .items { padding: 1px; gap: 0.15rem; - justify-content: space-evenly; .item { - width: 100%; pointer-events: none; } } @@ -169,7 +165,7 @@ @media @phone-landscape { .cell { - flex-direction: row; + flex-direction: column; .items { padding: 1px; @@ -186,10 +182,11 @@ @media only screen and (max-height: @medium) and (max-width: @medium) and (orientation: landscape) { .cell { gap: 0; - flex-direction: row; + flex-direction: column; .heading { .day { + padding: 0; font-size: 0.875rem; } } @@ -201,25 +198,11 @@ } @media only screen and (max-width: @minimum) and (orientation: portrait) and (pointer: fine) { - .cell { - position: relative; - flex-direction: row; - display: flex; + .cell { + display: flex; - .items{ - .item{ - pointer-events: none; - } - } - - .heading { - display: flex; - gap: 0.25rem; - width: auto; - .day{ - font-size: 0.6rem; - } - - } - } + .heading { + flex: 1 1 33%; + } + } } From 4361792cae363ac8ec2b4b4f1a4c8158abde96b8 Mon Sep 17 00:00:00 2001 From: Victor Sales <36749678+v1ctorsales@users.noreply.github.com> Date: Wed, 15 Oct 2025 20:36:13 +0300 Subject: [PATCH 26/33] fix: adapt items display for mobile landscape --- src/routes/Calendar/Table/Cell/Cell.less | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/routes/Calendar/Table/Cell/Cell.less b/src/routes/Calendar/Table/Cell/Cell.less index d5202c53d..f6ef744f1 100644 --- a/src/routes/Calendar/Table/Cell/Cell.less +++ b/src/routes/Calendar/Table/Cell/Cell.less @@ -29,7 +29,7 @@ .heading { position: relative; display: flex; - align-items: center; + align-items: flex-start; .day { flex: none; @@ -165,7 +165,7 @@ @media @phone-landscape { .cell { - flex-direction: column; + flex-direction: row; .items { padding: 1px; @@ -182,7 +182,6 @@ @media only screen and (max-height: @medium) and (max-width: @medium) and (orientation: landscape) { .cell { gap: 0; - flex-direction: column; .heading { .day { From 3e0308dff1a6aa8a89f150399ee11317b8213dc1 Mon Sep 17 00:00:00 2001 From: Victor Sales <36749678+v1ctorsales@users.noreply.github.com> Date: Wed, 15 Oct 2025 20:45:46 +0300 Subject: [PATCH 27/33] fix: align banners with day for small desktops --- src/routes/Calendar/Table/Cell/Cell.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes/Calendar/Table/Cell/Cell.less b/src/routes/Calendar/Table/Cell/Cell.less index f6ef744f1..06304fb24 100644 --- a/src/routes/Calendar/Table/Cell/Cell.less +++ b/src/routes/Calendar/Table/Cell/Cell.less @@ -192,6 +192,7 @@ .items { width: 100%; + padding-left: 0.5rem; } } } From 0433da66c11c5bf83956425c8ae533f3bc46c06c Mon Sep 17 00:00:00 2001 From: Victor Sales <36749678+v1ctorsales@users.noreply.github.com> Date: Thu, 16 Oct 2025 19:59:00 +0300 Subject: [PATCH 28/33] fix: point event none for tablets on portrait mode --- src/routes/Calendar/Table/Cell/Cell.less | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/routes/Calendar/Table/Cell/Cell.less b/src/routes/Calendar/Table/Cell/Cell.less index 06304fb24..c1f25fe46 100644 --- a/src/routes/Calendar/Table/Cell/Cell.less +++ b/src/routes/Calendar/Table/Cell/Cell.less @@ -206,3 +206,13 @@ } } } + +@media screen and (min-width: @small-phone-portrait-size) and (max-width: @small) and (orientation: portrait) { + .cell { + .items { + .item { + pointer-events: none; + } + } + } +} From 18617b32c99c33c1b0c442b608af98f2cc871cfb Mon Sep 17 00:00:00 2001 From: Victor Sales <36749678+v1ctorsales@users.noreply.github.com> Date: Fri, 17 Oct 2025 17:45:53 +0300 Subject: [PATCH 29/33] refactor: reduce duplicated CSS using less variables --- src/routes/Calendar/Table/Cell/Cell.less | 64 +++++++++++------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/src/routes/Calendar/Table/Cell/Cell.less b/src/routes/Calendar/Table/Cell/Cell.less index c1f25fe46..2ea7c6a74 100644 --- a/src/routes/Calendar/Table/Cell/Cell.less +++ b/src/routes/Calendar/Table/Cell/Cell.less @@ -2,6 +2,25 @@ @import (reference) '~stremio/common/screen-sizes.less'; +.disable-cell-items() { + .cell { + .items { + .item { + pointer-events: none; + } + } + } +} + +.compact-items() { + .cell { + .items { + padding: 1px; + gap: 0.15rem; + } + } +} + .cell { position: relative; display: flex; @@ -138,47 +157,26 @@ } @media only screen and (max-width: @minimum) { - .cell { - .items { - .item { - pointer-events: none; - } - } - } + .disable-cell-items(); } @media @phone-portrait { .cell { flex-direction: column; display: grid; - - .items { - padding: 1px; - gap: 0.15rem; - - .item { - pointer-events: none; - } - } } + .compact-items(); + .disable-cell-items(); } @media @phone-landscape { .cell { flex-direction: row; - - .items { - padding: 1px; - gap: 0.15rem; - - .item { - pointer-events: none; - } - } } + .compact-items(); + .disable-cell-items(); } - @media only screen and (max-height: @medium) and (max-width: @medium) and (orientation: landscape) { .cell { gap: 0; @@ -207,12 +205,10 @@ } } -@media screen and (min-width: @small-phone-portrait-size) and (max-width: @small) and (orientation: portrait) { - .cell { - .items { - .item { - pointer-events: none; - } - } - } +@media screen and (max-width: @small) and (orientation: portrait) { + .disable-cell-items(); +} + +@media screen and (min-width: @small-phone-portrait-size) and (max-width: @small) and (orientation: portrait) { + .disable-cell-items(); } From eb61ad69434840c3fcd1d090f3c977454fbd04fb Mon Sep 17 00:00:00 2001 From: Victor Sales <36749678+v1ctorsales@users.noreply.github.com> Date: Fri, 17 Oct 2025 18:20:31 +0300 Subject: [PATCH 30/33] fix: remove unused mediaquery --- src/routes/Calendar/Table/Cell/Cell.less | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/routes/Calendar/Table/Cell/Cell.less b/src/routes/Calendar/Table/Cell/Cell.less index 2ea7c6a74..afd2a3889 100644 --- a/src/routes/Calendar/Table/Cell/Cell.less +++ b/src/routes/Calendar/Table/Cell/Cell.less @@ -208,7 +208,3 @@ @media screen and (max-width: @small) and (orientation: portrait) { .disable-cell-items(); } - -@media screen and (min-width: @small-phone-portrait-size) and (max-width: @small) and (orientation: portrait) { - .disable-cell-items(); -} From e7b0a1d1be672b279a8b51cf04e7bfac9cf25728 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Oct 2025 21:13:21 +0000 Subject: [PATCH 31/33] chore(deps): bump actions/setup-node from 5 to 6 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 5 to 6. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d728715a2..6782e9d8e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: version: 10 run_install: false - name: Setup node - uses: actions/setup-node@v5 + uses: actions/setup-node@v6 with: node-version-file: .nvmrc cache: "pnpm" From 8c8d3376db8c0a27a07957124eb5d87b116cf19c Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 22 Oct 2025 13:41:51 +0200 Subject: [PATCH 32/33] chore: update core --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index c824ad411..0e229cb03 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "@babel/runtime": "7.26.0", "@sentry/browser": "8.42.0", "@stremio/stremio-colors": "5.2.0", - "@stremio/stremio-core-web": "0.49.4", + "@stremio/stremio-core-web": "0.50.0", "@stremio/stremio-icons": "5.7.1", "@stremio/stremio-video": "0.0.62", "a-color-picker": "1.2.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 121d0dbea..2bf50734f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ importers: specifier: 5.2.0 version: 5.2.0 '@stremio/stremio-core-web': - specifier: 0.49.4 - version: 0.49.4 + specifier: 0.50.0 + version: 0.50.0 '@stremio/stremio-icons': specifier: 5.7.1 version: 5.7.1 @@ -1302,8 +1302,8 @@ packages: '@stremio/stremio-colors@5.2.0': resolution: {integrity: sha512-dYlPgu9W/H7c9s1zmW5tiDnRenaUa4Hg1QCyOg1lhOcgSfM/bVTi5nnqX+IfvGTTUNA0zgzh8hI3o3miwnZxTg==} - '@stremio/stremio-core-web@0.49.4': - resolution: {integrity: sha512-K9LJGKXs8juV3pZOHH6thWTwOShAhjFt9bLL6K1VlORAe6AiieZ2uRp9wdOwFmPX+UgzWLIOd0r2aFXJ4OsJCw==} + '@stremio/stremio-core-web@0.50.0': + resolution: {integrity: sha512-SRE9nStgYNbhjJAw7mXfmM0wdnSLS4GMSJsSMTXvoGxnUgd+yisJUkN/9Sughe4t2IU7Uct8QWpdx9zFdlil+g==} '@stremio/stremio-icons@5.7.1': resolution: {integrity: sha512-Z96p36LLX3G+ewMnFKmNZVsO/AtcHA33WQ3wGOYFubxiYADPRAkcLVU5rHIfiGSC9IUaUVhxQWTPVB9ScY4Q5Q==} @@ -6561,7 +6561,7 @@ snapshots: '@stremio/stremio-colors@5.2.0': {} - '@stremio/stremio-core-web@0.49.4': + '@stremio/stremio-core-web@0.50.0': dependencies: '@babel/runtime': 7.24.1 From cf93c2dcbe5600fdce5d0b0050843dd27f7679df Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 23 Oct 2025 15:55:39 +0200 Subject: [PATCH 33/33] chore: update translations --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 61e713041..f36160585 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "react-i18next": "^15.1.3", "react-is": "18.3.1", "spatial-navigation-polyfill": "github:Stremio/spatial-navigation#64871b1422466f5f45d24ebc8bbd315b2ebab6a6", - "stremio-translations": "github:Stremio/stremio-translations#5e5e3776ff1a1684648eaa3fa6c3a6caeb67cc37", + "stremio-translations": "github:Stremio/stremio-translations#01aaa201e419782b26b9f2cbe4430795021426e5", "url": "0.11.4", "use-long-press": "^3.2.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 110fd7d71..0bce8e52f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -90,8 +90,8 @@ importers: specifier: github:Stremio/spatial-navigation#64871b1422466f5f45d24ebc8bbd315b2ebab6a6 version: https://codeload.github.com/Stremio/spatial-navigation/tar.gz/64871b1422466f5f45d24ebc8bbd315b2ebab6a6 stremio-translations: - specifier: github:Stremio/stremio-translations#5e5e3776ff1a1684648eaa3fa6c3a6caeb67cc37 - version: https://codeload.github.com/Stremio/stremio-translations/tar.gz/5e5e3776ff1a1684648eaa3fa6c3a6caeb67cc37 + specifier: github:Stremio/stremio-translations#01aaa201e419782b26b9f2cbe4430795021426e5 + version: https://codeload.github.com/Stremio/stremio-translations/tar.gz/01aaa201e419782b26b9f2cbe4430795021426e5 url: specifier: 0.11.4 version: 0.11.4 @@ -4527,8 +4527,8 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} - stremio-translations@https://codeload.github.com/Stremio/stremio-translations/tar.gz/5e5e3776ff1a1684648eaa3fa6c3a6caeb67cc37: - resolution: {tarball: https://codeload.github.com/Stremio/stremio-translations/tar.gz/5e5e3776ff1a1684648eaa3fa6c3a6caeb67cc37} + stremio-translations@https://codeload.github.com/Stremio/stremio-translations/tar.gz/01aaa201e419782b26b9f2cbe4430795021426e5: + resolution: {tarball: https://codeload.github.com/Stremio/stremio-translations/tar.gz/01aaa201e419782b26b9f2cbe4430795021426e5} version: 1.44.13 string-length@4.0.2: @@ -10283,7 +10283,7 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 - stremio-translations@https://codeload.github.com/Stremio/stremio-translations/tar.gz/5e5e3776ff1a1684648eaa3fa6c3a6caeb67cc37: {} + stremio-translations@https://codeload.github.com/Stremio/stremio-translations/tar.gz/01aaa201e419782b26b9f2cbe4430795021426e5: {} string-length@4.0.2: dependencies: