Compare commits

...

8 commits

Author SHA1 Message Date
Pranav1703
5af4bc3143
Merge a14a1b8798 into da675cd56c 2026-01-10 13:44:25 +05:30
Tim
da675cd56c chore: update caniuse
Some checks failed
Build / build (push) Has been cancelled
2026-01-10 01:12:20 +01:00
Tim
9b3b0d67ba
Merge pull request #1095 from Stremio/feat/player-mute-shortcut-2
Player: Add mute shortcut
2026-01-10 01:02:18 +01:00
Tim
fc2d906a42 Merge branch 'development' of https://github.com/Stremio/stremio-web into feat/player-mute-shortcut-2 2026-01-10 00:56:47 +01:00
Pranav1703
a14a1b8798 remove trailing tab space 2025-12-18 11:28:50 +05:30
Lachezar Lechev
7046622fb6
feat: player - mute shortcut
Signed-off-by: Lachezar Lechev <lachezar@ambire.com>
2025-12-17 14:15:06 +02:00
Pranav1703
d130a0de0a fix: build issues 2025-12-14 18:20:18 +05:30
Pranav1703
ef98490be6 feature: speeds up video when holding MLB 2025-12-11 20:59:22 +05:30
4 changed files with 54 additions and 13 deletions

View file

@ -1808,8 +1808,8 @@ packages:
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
baseline-browser-mapping@2.8.7:
resolution: {integrity: sha512-bxxN2M3a4d1CRoQC//IqsR5XrLh0IJ8TCv2x6Y9N0nckNz/rTjZB3//GGscZziZOxmjP55rzxg/ze7usFI9FqQ==}
baseline-browser-mapping@2.9.14:
resolution: {integrity: sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==}
hasBin: true
batch@0.6.1:
@ -1907,8 +1907,8 @@ packages:
caniuse-api@3.0.0:
resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
caniuse-lite@1.0.30001745:
resolution: {integrity: sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==}
caniuse-lite@1.0.30001763:
resolution: {integrity: sha512-mh/dGtq56uN98LlNX9qdbKnzINhX0QzhiWBFEkFfsFO4QyCvL8YegrJAazCwXIeqkIob8BlZPGM3xdnY+sgmvQ==}
centra@2.7.0:
resolution: {integrity: sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==}
@ -7125,7 +7125,7 @@ snapshots:
autoprefixer@10.4.21(postcss@8.5.6):
dependencies:
browserslist: 4.26.2
caniuse-lite: 1.0.30001745
caniuse-lite: 1.0.30001763
fraction.js: 4.3.7
normalize-range: 0.1.2
picocolors: 1.1.1
@ -7226,7 +7226,7 @@ snapshots:
base64-js@1.5.1: {}
baseline-browser-mapping@2.8.7: {}
baseline-browser-mapping@2.9.14: {}
batch@0.6.1: {}
@ -7277,8 +7277,8 @@ snapshots:
browserslist@4.26.2:
dependencies:
baseline-browser-mapping: 2.8.7
caniuse-lite: 1.0.30001745
baseline-browser-mapping: 2.9.14
caniuse-lite: 1.0.30001763
electron-to-chromium: 1.5.224
node-releases: 2.0.21
update-browserslist-db: 1.1.3(browserslist@4.26.2)
@ -7338,11 +7338,11 @@ snapshots:
caniuse-api@3.0.0:
dependencies:
browserslist: 4.26.2
caniuse-lite: 1.0.30001745
caniuse-lite: 1.0.30001763
lodash.memoize: 4.1.2
lodash.uniq: 4.5.0
caniuse-lite@1.0.30001745: {}
caniuse-lite@1.0.30001763: {}
centra@2.7.0:
dependencies:

View file

@ -59,6 +59,11 @@
"label": "SETTINGS_SHORTCUT_VOLUME_DOWN",
"combos": [["ArrowDown"]]
},
{
"name": "mute",
"label": "SETTINGS_SHORTCUT_MUTE",
"combos": [["M"]]
},
{
"name": "subtitlesSize",
"label": "SETTINGS_SHORTCUT_SUBTITLES_SIZE",

View file

@ -47,6 +47,10 @@ const Player = ({ urlParams, queryParams }) => {
const toast = useToast();
const [seeking, setSeeking] = React.useState(false);
const isMlbHeld = React.useRef(false);
const MlbHoldTimerRef = React.useRef(null);
const currPlaybackSpeed = React.useRef(null);
const [casting, setCasting] = React.useState(() => {
return services.chromecast.active && services.chromecast.transport.getCastState() === cast.framework.CastState.CONNECTED;
@ -312,6 +316,31 @@ const Player = ({ urlParams, queryParams }) => {
closeSideDrawer();
}, []);
const onVideoMouseDown = React.useCallback((event) => {
if (event.button !== 0) return;
MlbHoldTimerRef.current = setTimeout(() => {
currPlaybackSpeed.current = video.state.playbackSpeed;
isMlbHeld.current = true;
video.setProp('playbackSpeed',2.00);
}, 500);
}, [video]);
const onVideoMouseUp = React.useCallback((event) => {
clearTimeout(MlbHoldTimerRef.current);
if (isMlbHeld.current){
video.setProp('playbackSpeed',currPlaybackSpeed.current);
isMlbHeld.current = false;
}
}, [video]);
const onVideoMouseLeave = React.useCallback((event) => {
clearTimeout(MlbHoldTimerRef.current);
if (isMlbHeld.current) {
video.setProp('playbackSpeed',currPlaybackSpeed.current);
isMlbHeld.current = false;
}
}, [video]);
const onContainerMouseMove = React.useCallback((event) => {
setImmersed(false);
if (!event.nativeEvent.immersePrevented) {
@ -568,7 +597,7 @@ const Player = ({ urlParams, queryParams }) => {
const videoId = player.selected ? player.selected?.streamRequest?.path?.id : null;
const video = metaItem ? metaItem.videos.find(({ id }) => id === videoId) : null;
const videoInfo = video && video.season && video.episode ? ` (${video.season}x${video.episode})`: null;
const videoInfo = video && video.season && video.episode ? ` (${video.season}x${video.episode})` : null;
const videoTitle = video ? `${video.title}${videoInfo}` : null;
const metaTitle = metaItem ? metaItem.name : null;
const imageUrl = metaItem ? metaItem.logo : null;
@ -624,6 +653,10 @@ const Player = ({ urlParams, queryParams }) => {
}
}, [menusOpen, nextVideoPopupOpen, video.state.time, onSeekRequested]);
onShortcut('mute', () => {
video.state.muted === true ? onUnmuteRequested() : onMuteRequested();
}, [video.state.muted]);
onShortcut('volumeUp', () => {
if (!menusOpen && !nextVideoPopupOpen && video.state.volume !== null) {
onVolumeChangeRequested(Math.min(video.state.volume + 5, 200));
@ -749,6 +782,9 @@ const Player = ({ urlParams, queryParams }) => {
className={styles['layer']}
onClick={onVideoClick}
onDoubleClick={onVideoDoubleClick}
onMouseDown={onVideoMouseDown}
onMouseUp={onVideoMouseUp}
onMouseLeave={onVideoMouseLeave}
/>
{
!video.state.loaded ?

View file

@ -5,9 +5,9 @@ const PropTypes = require('prop-types');
const classnames = require('classnames');
const styles = require('./styles');
const Video = React.forwardRef(({ className, onClick, onDoubleClick }, ref) => {
const Video = React.forwardRef(({ className, onClick, onDoubleClick, onMouseUp, onMouseDown, onMouseLeave }, ref) => {
return (
<div className={classnames(className, styles['video-container'])} onClick={onClick} onDoubleClick={onDoubleClick}>
<div className={classnames(className, styles['video-container'])} onClick={onClick} onDoubleClick={onDoubleClick} onMouseUp={onMouseUp} onMouseDown={onMouseDown} onMouseLeave={onMouseLeave}>
<div ref={ref} className={styles['video']} />
</div>
);