mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
4.0.0-rc6.4
* Added: Notify users when a new build of FrankerFaceZ is available. * Fixed: The option to disable channel hosting. (Revert to previous channel hosting data scheme from 21 days ago.)
This commit is contained in:
parent
30ec9749da
commit
526c5940f0
7 changed files with 125 additions and 16 deletions
|
@ -27,7 +27,8 @@ module.exports = {
|
|||
"globals": {
|
||||
"import": false,
|
||||
"require": false,
|
||||
"__webpack_hash__": false
|
||||
"__webpack_hash__": false,
|
||||
"__git_commit__": false
|
||||
},
|
||||
"rules": {
|
||||
"accessor-pairs": ["error"],
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
<ul>
|
||||
<li v-for="commit of display" :key="commit.sha" class="tw-mg-b-2">
|
||||
<div class="tw-flex tw-align-items-center tw-border-b tw-mg-b-05">
|
||||
<div v-if="commit.active" class="tw-pill tw-mg-r-05">
|
||||
{{ t('home.changelog.current', 'Current Version') }}
|
||||
</div>
|
||||
<div class="tw-font-size-4">
|
||||
{{ commit.title }}
|
||||
</div>
|
||||
|
@ -50,6 +53,7 @@ import {get} from 'utilities/object';
|
|||
|
||||
const TITLE_MATCH = /^(\d+\.\d+\.\d+(?:\-[^\n]+)?)\n+/;
|
||||
|
||||
|
||||
export default {
|
||||
props: ['item', 'context'],
|
||||
|
||||
|
@ -71,7 +75,10 @@ export default {
|
|||
let message = commit.commit.message,
|
||||
title = old_commit;
|
||||
|
||||
const match = TITLE_MATCH.exec(message);
|
||||
const match = TITLE_MATCH.exec(message),
|
||||
date = new Date(commit.commit.author.date),
|
||||
active = commit.sha === window.FrankerFaceZ.version_info.commit;
|
||||
|
||||
if ( match ) {
|
||||
title = match[1];
|
||||
message = message.slice(match[0].length);
|
||||
|
@ -80,10 +87,11 @@ export default {
|
|||
out.push({
|
||||
title,
|
||||
message,
|
||||
active,
|
||||
hash: commit.sha && commit.sha.slice(0,7),
|
||||
link: commit.html_url,
|
||||
sha: commit.sha,
|
||||
date: new Date(commit.commit.author.date)
|
||||
date
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,17 @@
|
|||
}}
|
||||
</div>
|
||||
</section>
|
||||
<section v-if="context.has_update" class="tw-border-t tw-pd-t-1 tw-pd-b-2">
|
||||
<div class="tw-c-background-accent tw-c-text-overlay tw-pd-1">
|
||||
<h3 class="ffz-i-arrows-cw">
|
||||
{{ t('setting.update', 'There is an update available.') }}
|
||||
</h3>
|
||||
|
||||
{{ t('setting.update.description',
|
||||
'Please refresh your page to receive the latest version of FrankerFaceZ.')
|
||||
}}
|
||||
</div>
|
||||
</section>
|
||||
<section
|
||||
v-if="item.description"
|
||||
class="tw-border-t tw-pd-y-1"
|
||||
|
|
|
@ -18,7 +18,7 @@ function format_term(term) {
|
|||
return term.replace(/<[^>]*>/g, '').toLocaleLowerCase();
|
||||
}
|
||||
|
||||
// TODO: Rewrite literally everything about the menu to use vue-router and further
|
||||
// TODO: Rewrite literally everything about the menu to use a router and further
|
||||
// separate the concept of navigation from visible pages.
|
||||
|
||||
export default class MainMenu extends Module {
|
||||
|
@ -41,7 +41,7 @@ export default class MainMenu extends Module {
|
|||
this._visible = true;
|
||||
this._maximized = false;
|
||||
this.exclusive = false;
|
||||
|
||||
this.has_update = false;
|
||||
|
||||
this.settings.addUI('profiles', {
|
||||
path: 'Data Management @{"sort": 1000, "profile_warning": false} > Profiles @{"profile_warning": false}',
|
||||
|
@ -63,6 +63,20 @@ export default class MainMenu extends Module {
|
|||
component: 'changelog'
|
||||
});
|
||||
|
||||
this.on('socket:command:new_version', version => {
|
||||
if ( version === window.FrankerFaceZ.version_info.commit )
|
||||
return;
|
||||
|
||||
this.log.info('New Version Available', version);
|
||||
this.has_update = true;
|
||||
|
||||
const mb = this.resolve('site.menu_button');
|
||||
if ( mb )
|
||||
mb.has_update = true;
|
||||
|
||||
if ( this._vue )
|
||||
this._vue.$children[0].context.has_update = true;
|
||||
});
|
||||
}
|
||||
|
||||
openPopout() {
|
||||
|
@ -464,6 +478,8 @@ export default class MainMenu extends Module {
|
|||
profile_keys,
|
||||
currentProfile: profile_keys[0],
|
||||
|
||||
has_update: this.has_update,
|
||||
|
||||
createProfile: data => {
|
||||
const profile = settings.createProfile(data);
|
||||
return t.getProfileProxy(profile, context);
|
||||
|
@ -567,7 +583,9 @@ export default class MainMenu extends Module {
|
|||
faded: false,
|
||||
|
||||
nav: settings,
|
||||
currentItem: settings.keys['home'], // settings[0],
|
||||
currentItem: this.has_update ?
|
||||
settings.keys['home.changelog'] :
|
||||
settings.keys['home'], // settings[0],
|
||||
nav_keys: settings.keys,
|
||||
|
||||
maximized: this._maximized,
|
||||
|
|
|
@ -44,7 +44,8 @@ export default class Channel extends Module {
|
|||
|
||||
this.ChannelPage = this.fine.define(
|
||||
'channel-page',
|
||||
n => n.hostModeFromGraphQL,
|
||||
n => n.getHostedChannelLogin && n.handleHostingChange,
|
||||
//n => n.hostModeFromGraphQL,
|
||||
['user']
|
||||
);
|
||||
|
||||
|
@ -73,9 +74,15 @@ export default class Channel extends Module {
|
|||
// We can't do this immediately because the player state
|
||||
// occasionally screws up if we do.
|
||||
setTimeout(() => {
|
||||
if ( inst.state.hostMode ) {
|
||||
/*if ( inst.state.hostMode ) {
|
||||
inst.ffzExpectedHost = inst.state.hostMode;
|
||||
inst.ffzOldSetState({hostMode: null});
|
||||
}*/
|
||||
|
||||
const current_channel = inst.props.data && inst.props.data.variables && inst.props.data.variables.currentChannelLogin;
|
||||
if ( current_channel && current_channel !== inst.state.videoPlayerSource ) {
|
||||
inst.ffzExpectedHost = inst.state.videoPlayerSource;
|
||||
inst.ffzOldHostHandler(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -132,13 +139,21 @@ export default class Channel extends Module {
|
|||
inst.ffzOldSetState = inst.setState;
|
||||
inst.setState = function(state, ...args) {
|
||||
try {
|
||||
if ( has(state, 'hostMode') ) {
|
||||
if ( ! t.settings.get('channel.hosting.enable') ) {
|
||||
if ( has(state, 'isHosting') )
|
||||
state.isHosting = false;
|
||||
|
||||
if ( has(state, 'videoPlayerSource') )
|
||||
state.videoPlayerSource = inst.props.match.params.channelName;
|
||||
}
|
||||
|
||||
/*if ( has(state, 'hostMode') ) {
|
||||
inst.ffzExpectedHost = state.hostMode;
|
||||
if ( state.hostMode && ! t.settings.get('channel.hosting.enable') ) {
|
||||
state.hostMode = null;
|
||||
state.videoPlayerSource = inst.props.match.params.channelName;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
} catch(err) {
|
||||
t.log.capture(err, {extra: {props: inst.props, state}});
|
||||
|
@ -149,12 +164,34 @@ export default class Channel extends Module {
|
|||
|
||||
inst._ffz_hosting_wrapped = true;
|
||||
|
||||
const hosted = inst.ffzExpectedHost = inst.state.hostMode;
|
||||
inst.ffzOldGetHostedLogin = inst.getHostedChannelLogin;
|
||||
inst.getHostedChannelLogin = function() {
|
||||
return t.settings.get('channel.hosting.enable') ?
|
||||
inst.ffzOldGetHostedLogin() : null;
|
||||
}
|
||||
|
||||
inst.ffzOldHostHandler = inst.handleHostingChange;
|
||||
inst.handleHostingChange = function(channel) {
|
||||
inst.ffzExpectedHost = channel;
|
||||
if ( t.settings.get('channel.hosting.enable') )
|
||||
return inst.ffzOldHostHandler(channel);
|
||||
}
|
||||
|
||||
// Store the current state and disable the current host if needed.
|
||||
inst.ffzExpectedHost = inst.state.isHosting ? inst.state.videoPlayerSource : null;
|
||||
if ( ! this.settings.get('channel.hosting.enable') )
|
||||
inst.ffzOldHostHandler(null);
|
||||
|
||||
// Finally, we force an update so that any child components
|
||||
// receive our updated handler.
|
||||
inst.forceUpdate();
|
||||
|
||||
/*const hosted = inst.ffzExpectedHost = inst.state.hostMode;
|
||||
if ( hosted && ! this.settings.get('channel.hosting.enable') )
|
||||
inst.ffzOldSetState({
|
||||
hostMode: null,
|
||||
videoPlayerSource: inst.props.match.params.channelName
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -163,13 +200,15 @@ export default class Channel extends Module {
|
|||
val = this.settings.get('channel.hosting.enable');
|
||||
|
||||
for(const inst of this.ChannelPage.instances) {
|
||||
const host = val ? inst.ffzExpectedHost : null,
|
||||
inst.ffzOldHostHandler(val ? inst.ffzExpectedHost : null);
|
||||
|
||||
/*const host = val ? inst.ffzExpectedHost : null,
|
||||
target = host && host.hostedChannel && host.hostedChannel.login || inst.props.match.params.channelName;
|
||||
|
||||
inst.ffzOldSetState({
|
||||
hostMode: host,
|
||||
videoPlayerSource: target
|
||||
});
|
||||
});*/
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,8 @@ export default class MenuButton extends SiteModule {
|
|||
|
||||
this.should_enable = true;
|
||||
this._pill_content = null;
|
||||
this._has_update = false;
|
||||
this._important_update = false;
|
||||
|
||||
this.NavBar = this.fine.define(
|
||||
'nav-bar',
|
||||
|
@ -24,6 +26,26 @@ export default class MenuButton extends SiteModule {
|
|||
);
|
||||
}
|
||||
|
||||
get important_update() {
|
||||
return this._important_update;
|
||||
}
|
||||
|
||||
set important_update(val) {
|
||||
this._important_update = false;
|
||||
this.update();
|
||||
}
|
||||
|
||||
get has_update() {
|
||||
return this._has_update;
|
||||
}
|
||||
|
||||
set has_update(val) {
|
||||
if ( val && ! this._has_update )
|
||||
this._important_update = true;
|
||||
|
||||
this._has_update = val;
|
||||
this.update();
|
||||
}
|
||||
|
||||
get pill() {
|
||||
return this._pill_content;
|
||||
|
@ -55,6 +77,8 @@ export default class MenuButton extends SiteModule {
|
|||
this.NavBar.on('mount', this.updateButton, this);
|
||||
this.NavBar.on('update', this.updateButton, this);
|
||||
|
||||
this.on(':clicked', () => this.important_update = false);
|
||||
|
||||
this.once(':clicked', this.loadMenu);
|
||||
this.on('i18n:update', this.update);
|
||||
}
|
||||
|
@ -81,7 +105,12 @@ export default class MenuButton extends SiteModule {
|
|||
<span class="tw-button-icon__icon">
|
||||
<figure class="ffz-i-zreknarf" />
|
||||
</span>
|
||||
{DEBUG && (<div class="ffz-menu__dev-pill tw-absolute">
|
||||
{this.has_update && (<div class="ffz-menu__extra-pill tw-absolute">
|
||||
<div class={`tw-pill ${this.important_update ? ' tw-pill--notification' : ''}`}>
|
||||
<figure class="ffz-i-arrows-cw" />
|
||||
</div>
|
||||
</div>)}
|
||||
{!this.has_update && DEBUG && (<div class="ffz-menu__extra-pill tw-absolute">
|
||||
<div class="tw-pill">
|
||||
{this.i18n.t('site.menu_button.dev', 'dev')}
|
||||
</div>
|
||||
|
@ -95,6 +124,9 @@ export default class MenuButton extends SiteModule {
|
|||
</div>)}
|
||||
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-center">
|
||||
{this.i18n.t('site.menu_button', 'FrankerFaceZ Control Center')}
|
||||
{this.has_update && (<div class="tw-mg-t-1">
|
||||
{this.i18n.t('site.menu_button.update-desc', 'There is an update available. Please refresh your page.')}
|
||||
</div>)}
|
||||
{DEBUG && (<div class="tw-mg-t-1">
|
||||
{this.i18n.t('site.menu_button.dev-desc', 'You are running a developer build of FrankerFaceZ.')}
|
||||
</div>)}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.ffz-menu__dev-pill {
|
||||
.ffz-menu__extra-pill {
|
||||
bottom: -1rem;
|
||||
right: -.3rem;
|
||||
font-size: 1.2rem;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue