mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-12 09:00:54 +00:00
4.14.8
* Added: New icons for Picture-in-Picture and Reset Player, courtesy of Pilk. * Changed: The Reset Player button now has feedback when you interact with it.
This commit is contained in:
parent
a38f5ce9d5
commit
103c68ad10
4 changed files with 82 additions and 8 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "frankerfacez",
|
"name": "frankerfacez",
|
||||||
"author": "Dan Salvato LLC",
|
"author": "Dan Salvato LLC",
|
||||||
"version": "4.14.7",
|
"version": "4.14.8",
|
||||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -11,6 +11,21 @@ export const PLAYER_ROUTES = ['front-page', 'user', 'video', 'user-video', 'user
|
||||||
|
|
||||||
const STYLE_VALIDATOR = createElement('span');
|
const STYLE_VALIDATOR = createElement('span');
|
||||||
|
|
||||||
|
function rotateButton(event) {
|
||||||
|
const target = event.currentTarget,
|
||||||
|
icon = target && target.querySelector('figure');
|
||||||
|
if ( ! icon || icon.classList.contains('ffz-i-t-reset-clicked') )
|
||||||
|
return;
|
||||||
|
|
||||||
|
icon.classList.toggle('ffz-i-t-reset', false);
|
||||||
|
icon.classList.toggle('ffz-i-t-reset-clicked', true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
icon.classList.toggle('ffz-i-t-reset', true);
|
||||||
|
icon.classList.toggle('ffz-i-t-reset-clicked', false);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
export default class Player extends Module {
|
export default class Player extends Module {
|
||||||
constructor(...args) {
|
constructor(...args) {
|
||||||
super(...args);
|
super(...args);
|
||||||
|
@ -395,6 +410,9 @@ export default class Player extends Module {
|
||||||
if ( ! this._ffzErrorReset )
|
if ( ! this._ffzErrorReset )
|
||||||
this._ffzErrorReset = t.addErrorResetButton.bind(t, this);
|
this._ffzErrorReset = t.addErrorResetButton.bind(t, this);
|
||||||
|
|
||||||
|
if ( ! this._ffzReady )
|
||||||
|
this._ffzReady = this.ffzReady.bind(this);
|
||||||
|
|
||||||
const inst = this,
|
const inst = this,
|
||||||
old_active = this.setPlayerActive,
|
old_active = this.setPlayerActive,
|
||||||
old_inactive = this.setPlayerInactive;
|
old_inactive = this.setPlayerInactive;
|
||||||
|
@ -427,6 +445,7 @@ export default class Player extends Module {
|
||||||
on(events, 'PlayerError', this._ffzErrorReset);
|
on(events, 'PlayerError', this._ffzErrorReset);
|
||||||
on(events, 'Ended', this._ffzUpdateState);
|
on(events, 'Ended', this._ffzUpdateState);
|
||||||
on(events, 'Ended', this.ffzOnEnded);
|
on(events, 'Ended', this.ffzOnEnded);
|
||||||
|
on(events, 'Ready', this._ffzReady);
|
||||||
on(events, 'Idle', this._ffzUpdateState);
|
on(events, 'Idle', this._ffzUpdateState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,6 +463,7 @@ export default class Player extends Module {
|
||||||
off(events, 'PlayerError', this._ffzErrorReset);
|
off(events, 'PlayerError', this._ffzErrorReset);
|
||||||
off(events, 'Ended', this._ffzUpdateState);
|
off(events, 'Ended', this._ffzUpdateState);
|
||||||
off(events, 'Ended', this.ffzOnEnded);
|
off(events, 'Ended', this.ffzOnEnded);
|
||||||
|
off(events, 'Ready', this._ffzReady);
|
||||||
off(events, 'Idle', this._ffzUpdateState);
|
off(events, 'Idle', this._ffzUpdateState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,9 +472,26 @@ export default class Player extends Module {
|
||||||
this._ffz_state_raf = null;
|
this._ffz_state_raf = null;
|
||||||
this._ffzUpdateState = null;
|
this._ffzUpdateState = null;
|
||||||
this._ffzErrorReset = null;
|
this._ffzErrorReset = null;
|
||||||
|
this._ffzReady = null;
|
||||||
this.ffzOnEnded = null;
|
this.ffzOnEnded = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cls.prototype.ffzReady = function() {
|
||||||
|
const cont = this.props.containerRef;
|
||||||
|
if ( ! cont )
|
||||||
|
return;
|
||||||
|
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
const icons = cont.querySelectorAll('.ffz--player-reset figure');
|
||||||
|
for(const icon of icons) {
|
||||||
|
if ( icon._ffz_unspin )
|
||||||
|
clearTimeout(icon._ffz_unspin);
|
||||||
|
|
||||||
|
icon.classList.toggle('loading', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
cls.prototype.ffzStopAutoplay = function() {
|
cls.prototype.ffzStopAutoplay = function() {
|
||||||
if ( t.settings.get('player.no-autoplay') || (! t.settings.get('player.home.autoplay') && t.router.current.name === 'front-page') ) {
|
if ( t.settings.get('player.no-autoplay') || (! t.settings.get('player.home.autoplay') && t.router.current.name === 'front-page') ) {
|
||||||
const player = this.props.mediaPlayerInstance,
|
const player = this.props.mediaPlayerInstance,
|
||||||
|
@ -758,7 +795,7 @@ export default class Player extends Module {
|
||||||
>
|
>
|
||||||
<div class="tw-align-items-center tw-flex tw-flex-grow-0">
|
<div class="tw-align-items-center tw-flex tw-flex-grow-0">
|
||||||
<div class="tw-button-icon__icon">
|
<div class="tw-button-icon__icon">
|
||||||
{icon = (<figure />)}
|
{icon = (<figure class="ffz-player-icon" />)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>)}
|
</button>)}
|
||||||
|
@ -777,20 +814,27 @@ export default class Player extends Module {
|
||||||
tip = cont.querySelector('.tw-tooltip');
|
tip = cont.querySelector('.tw-tooltip');
|
||||||
}
|
}
|
||||||
|
|
||||||
const pip_active = !!document.pictureInPictureElement
|
const pip_active = !!document.pictureInPictureElement,
|
||||||
|
label = pip_active ?
|
||||||
|
this.i18n.t('player.pip_button.off', 'Exit Picture-in-Picture') :
|
||||||
|
this.i18n.t('player.pip_button', 'Picture-in-Picture');
|
||||||
|
|
||||||
icon.classList.toggle('ffz-i-t-pip-inactive', ! pip_active);
|
icon.classList.toggle('ffz-i-t-pip-inactive', ! pip_active);
|
||||||
icon.classList.toggle('ffz-i-t-pip-active', pip_active);
|
icon.classList.toggle('ffz-i-t-pip-active', pip_active);
|
||||||
|
|
||||||
btn.setAttribute('aria-label', tip.textContent = this.i18n.t('player.pip_button', 'Picture-in-Picture'));
|
btn.setAttribute('aria-label', label);
|
||||||
|
tip.textContent = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pipPlayer(inst) {
|
pipPlayer(inst, e) {
|
||||||
const video = inst.props.mediaPlayerInstance?.mediaSinkManager?.video;
|
const video = inst.props.mediaPlayerInstance?.mediaSinkManager?.video;
|
||||||
if ( ! video || ! document.pictureInPictureEnabled )
|
if ( ! video || ! document.pictureInPictureEnabled )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if ( e )
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
if ( ! video._ffz_pip_enter ) {
|
if ( ! video._ffz_pip_enter ) {
|
||||||
video.addEventListener('enterpictureinpicture', video._ffz_pip_enter = () => {
|
video.addEventListener('enterpictureinpicture', video._ffz_pip_enter = () => {
|
||||||
this.addPiPButton(inst);
|
this.addPiPButton(inst);
|
||||||
|
@ -836,11 +880,12 @@ export default class Player extends Module {
|
||||||
class="tw-align-items-center tw-align-middle tw-border-bottom-left-radius-medium tw-border-bottom-right-radius-medium tw-border-top-left-radius-medium tw-border-top-right-radius-medium tw-button-icon tw-button-icon--overlay tw-core-button tw-core-button--border tw-core-button--overlay tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden tw-relative"
|
class="tw-align-items-center tw-align-middle tw-border-bottom-left-radius-medium tw-border-bottom-right-radius-medium tw-border-top-left-radius-medium tw-border-top-right-radius-medium tw-button-icon tw-button-icon--overlay tw-core-button tw-core-button--border tw-core-button--overlay tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden tw-relative"
|
||||||
type="button"
|
type="button"
|
||||||
data-a-target="ffz-player-reset-button"
|
data-a-target="ffz-player-reset-button"
|
||||||
|
onClick={rotateButton}
|
||||||
onDblClick={this.resetPlayer.bind(this, inst)} // eslint-disable-line react/jsx-no-bind
|
onDblClick={this.resetPlayer.bind(this, inst)} // eslint-disable-line react/jsx-no-bind
|
||||||
>
|
>
|
||||||
<div class="tw-align-items-center tw-flex tw-flex-grow-0">
|
<div class="tw-align-items-center tw-flex tw-flex-grow-0">
|
||||||
<div class="tw-button-icon__icon">
|
<div class="tw-button-icon__icon">
|
||||||
<figure class="ffz-i-t-reset" />
|
<figure class="ffz-player-icon ffz-i-t-reset" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>)}
|
</button>)}
|
||||||
|
@ -903,11 +948,12 @@ export default class Player extends Module {
|
||||||
class="tw-align-items-center tw-align-middle tw-border-bottom-left-radius-medium tw-border-bottom-right-radius-medium tw-border-top-left-radius-medium tw-border-top-right-radius-medium tw-button-icon tw-button-icon--overlay tw-core-button tw-core-button--border tw-core-button--overlay tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden tw-relative"
|
class="tw-align-items-center tw-align-middle tw-border-bottom-left-radius-medium tw-border-bottom-right-radius-medium tw-border-top-left-radius-medium tw-border-top-right-radius-medium tw-button-icon tw-button-icon--overlay tw-core-button tw-core-button--border tw-core-button--overlay tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden tw-relative"
|
||||||
type="button"
|
type="button"
|
||||||
data-a-target="ffz-player-reset-button"
|
data-a-target="ffz-player-reset-button"
|
||||||
|
onClick={rotateButton}
|
||||||
onDblClick={this.resetPlayer.bind(this, inst)} // eslint-disable-line react/jsx-no-bind
|
onDblClick={this.resetPlayer.bind(this, inst)} // eslint-disable-line react/jsx-no-bind
|
||||||
>
|
>
|
||||||
<div class="tw-align-items-center tw-flex tw-flex-grow-0">
|
<div class="tw-align-items-center tw-flex tw-flex-grow-0">
|
||||||
<div class="tw-button-icon__icon">
|
<div class="tw-button-icon__icon">
|
||||||
<figure class="ffz-i-cancel" />
|
<figure class="ffz-player-icon ffz-i-t-reset" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>)}
|
</button>)}
|
||||||
|
@ -929,9 +975,29 @@ export default class Player extends Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
resetPlayer(inst) {
|
resetPlayer(inst, e) {
|
||||||
const player = inst ? (inst.mediaSinkManager ? inst : inst?.props?.mediaPlayerInstance) : null;
|
const player = inst ? (inst.mediaSinkManager ? inst : inst?.props?.mediaPlayerInstance) : null;
|
||||||
|
|
||||||
|
if ( e ) {
|
||||||
|
e.preventDefault();
|
||||||
|
const target = e.currentTarget,
|
||||||
|
icon = target && target.querySelector('figure');
|
||||||
|
|
||||||
|
if ( icon ) {
|
||||||
|
if ( icon.classList.contains('loading') )
|
||||||
|
return;
|
||||||
|
|
||||||
|
icon.classList.toggle('ffz-i-t-reset', true);
|
||||||
|
icon.classList.toggle('ffz-i-t-reset-clicked', false);
|
||||||
|
|
||||||
|
icon.classList.toggle('loading', true);
|
||||||
|
icon._ffz_unspin = setTimeout(() => {
|
||||||
|
icon._ffz_unspin = null;
|
||||||
|
icon.classList.toggle('loading', false);
|
||||||
|
}, 10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.PlayerSource.check();
|
this.PlayerSource.check();
|
||||||
for(const inst of this.PlayerSource.instances) {
|
for(const inst of this.PlayerSource.instances) {
|
||||||
if ( ! player || player === inst.props?.mediaPlayerInstance )
|
if ( ! player || player === inst.props?.mediaPlayerInstance )
|
||||||
|
|
|
@ -44,6 +44,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ffz-player-icon {
|
||||||
|
font-size: 2rem !important;
|
||||||
|
margin: -.5rem -.4rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.tw-button-icon__icon {
|
.tw-button-icon__icon {
|
||||||
[class^="ffz-i-"], [class*=" ffz-i-"] {
|
[class^="ffz-i-"], [class*=" ffz-i-"] {
|
||||||
font-size: 1.6rem
|
font-size: 1.6rem
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ffz-i-t-reset.loading,
|
||||||
|
.ffz-i-t-reset-clicked.loading,
|
||||||
.ffz-i-zreknarf.loading {
|
.ffz-i-zreknarf.loading {
|
||||||
animation: ffz-rotateplane 1.2s infinite linear;
|
animation: ffz-rotateplane 1.2s infinite linear;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue