mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-07-02 00:58:32 +00:00
4.0.0-rc21
* Added: In-Line Chat Actions can now be set to display with specific modifier keys being held. This feature currently requires that Freeze Chat Scrolling is enabled. (Though, why you'd want to use this without that feature is beyond me.) * Fixed: Bug with custom chat width in theater mode. * Fixed: The `Get Bits` button appearing when disabled. * Fixed: Issue with highlighting chat usernames when using Firefox. * Fixed: Misc minor bugs.
This commit is contained in:
parent
63783472b7
commit
bd11a6f2aa
16 changed files with 299 additions and 23 deletions
|
@ -155,6 +155,9 @@ export class TranslationManager extends Module {
|
||||||
|
|
||||||
handleMessage(event) {
|
handleMessage(event) {
|
||||||
const msg = event.data;
|
const msg = event.data;
|
||||||
|
if ( ! msg )
|
||||||
|
return;
|
||||||
|
|
||||||
if ( msg.type === 'seen' )
|
if ( msg.type === 'seen' )
|
||||||
this.see(msg.key, true);
|
this.see(msg.key, true);
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ ${typeof x[1] === 'string' ? x[1] : JSON.stringify(x[1], null, 4)}`
|
||||||
FrankerFaceZ.Logger = Logger;
|
FrankerFaceZ.Logger = Logger;
|
||||||
|
|
||||||
const VER = FrankerFaceZ.version_info = {
|
const VER = FrankerFaceZ.version_info = {
|
||||||
major: 4, minor: 0, revision: 0, extra: '-rc20.5',
|
major: 4, minor: 0, revision: 0, extra: '-rc21',
|
||||||
commit: __git_commit__,
|
commit: __git_commit__,
|
||||||
build: __webpack_hash__,
|
build: __webpack_hash__,
|
||||||
toString: () =>
|
toString: () =>
|
||||||
|
|
|
@ -77,6 +77,7 @@ export default class Actions extends Module {
|
||||||
component: 'chat-actions',
|
component: 'chat-actions',
|
||||||
context: ['user', 'room', 'message'],
|
context: ['user', 'room', 'message'],
|
||||||
inline: true,
|
inline: true,
|
||||||
|
modifiers: true,
|
||||||
|
|
||||||
data: () => {
|
data: () => {
|
||||||
const chat = this.resolve('site.chat');
|
const chat = this.resolve('site.chat');
|
||||||
|
@ -437,7 +438,10 @@ export default class Actions extends Module {
|
||||||
if ( current_level < 3 )
|
if ( current_level < 3 )
|
||||||
mod_icons = false;
|
mod_icons = false;
|
||||||
|
|
||||||
const chat = this.resolve('site.chat');
|
const chat = this.resolve('site.chat'),
|
||||||
|
modified = [];
|
||||||
|
|
||||||
|
let had_action = false;
|
||||||
|
|
||||||
for(const data of this.parent.context.get('chat.actions.inline')) {
|
for(const data of this.parent.context.get('chat.actions.inline')) {
|
||||||
if ( ! data.action || ! data.appearance )
|
if ( ! data.action || ! data.appearance )
|
||||||
|
@ -445,6 +449,7 @@ export default class Actions extends Module {
|
||||||
|
|
||||||
const ap = data.appearance || {},
|
const ap = data.appearance || {},
|
||||||
disp = data.display || {},
|
disp = data.display || {},
|
||||||
|
keys = disp.keys,
|
||||||
|
|
||||||
def = this.renderers[ap.type];
|
def = this.renderers[ap.type];
|
||||||
|
|
||||||
|
@ -459,8 +464,14 @@ export default class Actions extends Module {
|
||||||
color = has_color && (chat && chat.colors ? chat.colors.process(ap.color) : ap.color),
|
color = has_color && (chat && chat.colors ? chat.colors.process(ap.color) : ap.color),
|
||||||
contents = def.render.call(this, ap, createElement, color);
|
contents = def.render.call(this, ap, createElement, color);
|
||||||
|
|
||||||
actions.push(<button
|
let list = actions;
|
||||||
class={`ffz-tooltip ffz-mod-icon mod-icon tw-c-text-alt-2${has_color ? ' colored' : ''}`}
|
|
||||||
|
if ( keys )
|
||||||
|
list = modified;
|
||||||
|
|
||||||
|
had_action = true;
|
||||||
|
list.push(<button
|
||||||
|
class={`ffz-tooltip ffz-mod-icon mod-icon tw-c-text-alt-2${has_color ? ' colored' : ''}${keys ? ` ffz-modifier-${keys}` : ''}`}
|
||||||
data-tooltip-type="action"
|
data-tooltip-type="action"
|
||||||
data-action={data.action}
|
data-action={data.action}
|
||||||
data-options={data.options ? JSON.stringify(data.options) : null}
|
data-options={data.options ? JSON.stringify(data.options) : null}
|
||||||
|
@ -472,7 +483,7 @@ export default class Actions extends Module {
|
||||||
</button>);
|
</button>);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! actions.length )
|
if ( ! had_action )
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
/*const room = current_room && JSON.stringify(current_room),
|
/*const room = current_room && JSON.stringify(current_room),
|
||||||
|
@ -483,12 +494,25 @@ export default class Actions extends Module {
|
||||||
type: msg.user.type
|
type: msg.user.type
|
||||||
});*/
|
});*/
|
||||||
|
|
||||||
return (<div
|
let out = (<div
|
||||||
class="ffz--inline-actions ffz-action-data tw-inline-block tw-mg-r-05"
|
class="ffz--inline-actions ffz-action-data tw-inline-block tw-mg-r-05"
|
||||||
data-source="line"
|
data-source="line"
|
||||||
>
|
>
|
||||||
{actions}
|
{actions}
|
||||||
</div>);
|
</div>);
|
||||||
|
|
||||||
|
if ( modified.length ) {
|
||||||
|
return [out,
|
||||||
|
(<div
|
||||||
|
class="ffz--inline-actions ffz--modifier-actions ffz-action-data"
|
||||||
|
data-source="line"
|
||||||
|
>
|
||||||
|
{modified}
|
||||||
|
</div>)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -291,7 +291,7 @@ export const whisper = {
|
||||||
me = site && site.getUser(),
|
me = site && site.getUser(),
|
||||||
store = site && site.store;
|
store = site && site.store;
|
||||||
|
|
||||||
if ( ! me || ! store || ! data.user.id || me.id == data.user.id )
|
if ( ! me || ! store || ! data.user || ! data.user.id || me.id == data.user.id )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const id_1 = parseInt(me.id, 10),
|
const id_1 = parseInt(me.id, 10),
|
||||||
|
|
|
@ -935,7 +935,7 @@ export default class Chat extends Module {
|
||||||
for(const id in this.room_ids)
|
for(const id in this.room_ids)
|
||||||
if ( has(this.room_ids, id) ) {
|
if ( has(this.room_ids, id) ) {
|
||||||
const room = this.room_ids[id];
|
const room = this.room_ids[id];
|
||||||
if ( room ) {
|
if ( room && ! room.destroyed ) {
|
||||||
visited.add(room);
|
visited.add(room);
|
||||||
yield room;
|
yield room;
|
||||||
}
|
}
|
||||||
|
@ -944,7 +944,7 @@ export default class Chat extends Module {
|
||||||
for(const login in this.rooms)
|
for(const login in this.rooms)
|
||||||
if ( has(this.rooms, login) ) {
|
if ( has(this.rooms, login) ) {
|
||||||
const room = this.rooms[login];
|
const room = this.rooms[login];
|
||||||
if ( room && ! visited.has(room) )
|
if ( room && ! room.destroyed && ! visited.has(room) )
|
||||||
yield room;
|
yield room;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1347,6 +1347,7 @@ export default class Chat extends Module {
|
||||||
|
|
||||||
if ( type === 'text' )
|
if ( type === 'text' )
|
||||||
res = e('span', {
|
res = e('span', {
|
||||||
|
className: 'text-fragment',
|
||||||
'data-a-target': 'chat-message-text'
|
'data-a-target': 'chat-message-text'
|
||||||
}, token.text);
|
}, token.text);
|
||||||
|
|
||||||
|
|
|
@ -364,14 +364,20 @@ export default class Room {
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
|
||||||
ref(referrer) {
|
ref(referrer) {
|
||||||
|
if ( ! this.refs )
|
||||||
|
throw new Error('Attempting to use destroyed Room');
|
||||||
|
|
||||||
clearTimeout(this._destroy_timer);
|
clearTimeout(this._destroy_timer);
|
||||||
this._destroy_timer = null;
|
this._destroy_timer = null;
|
||||||
this.refs.add(referrer);
|
this.refs.add(referrer);
|
||||||
}
|
}
|
||||||
|
|
||||||
unref(referrer) {
|
unref(referrer) {
|
||||||
|
if ( ! this.refs )
|
||||||
|
return;
|
||||||
|
|
||||||
this.refs.delete(referrer);
|
this.refs.delete(referrer);
|
||||||
if ( ! this.users.size && ! this._destroy_timer )
|
if ( ! this.refs.size && ! this._destroy_timer )
|
||||||
this._destroy_timer = setTimeout(() => this.destroy(), 5000);
|
this._destroy_timer = setTimeout(() => this.destroy(), 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ export const Links = {
|
||||||
|
|
||||||
render(token, createElement) {
|
render(token, createElement) {
|
||||||
return (<a
|
return (<a
|
||||||
class="ffz-tooltip"
|
class="ffz-tooltip link-fragment"
|
||||||
data-tooltip-type="link"
|
data-tooltip-type="link"
|
||||||
data-url={token.url}
|
data-url={token.url}
|
||||||
data-is-mail={token.is_mail}
|
data-is-mail={token.is_mail}
|
||||||
|
|
|
@ -119,6 +119,76 @@
|
||||||
<option :value="false">{{ t('setting.false', 'False') }}</option>
|
<option :value="false">{{ t('setting.false', 'False') }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div v-if="has_modifiers" class="tw-flex tw-align-items-start">
|
||||||
|
<label for="vis_modifiers">
|
||||||
|
{{ t('setting.actions.edit-visible.modifier', 'Modifiers') }}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="ffz--inline tw-flex">
|
||||||
|
<div class="tw-pd-r-1 tw-checkbox">
|
||||||
|
<input
|
||||||
|
id="key_ctrl"
|
||||||
|
ref="key_ctrl"
|
||||||
|
:checked="edit_data.display.keys & 1"
|
||||||
|
type="checkbox"
|
||||||
|
class="tw-checkbox__input"
|
||||||
|
@change="onChangeKeys"
|
||||||
|
>
|
||||||
|
<label for="key_ctrl" class="tw-checkbox__label">
|
||||||
|
{{ t('setting.key.ctrl', 'Ctrl') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tw-pd-r-1 tw-checkbox">
|
||||||
|
<input
|
||||||
|
id="key_shift"
|
||||||
|
ref="key_shift"
|
||||||
|
:checked="edit_data.display.keys & 2"
|
||||||
|
type="checkbox"
|
||||||
|
class="tw-checkbox__input"
|
||||||
|
@change="onChangeKeys"
|
||||||
|
>
|
||||||
|
<label for="key_shift" class="tw-checkbox__label">
|
||||||
|
{{ t('setting.key.shift', 'Shift') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tw-pd-r-1 tw-checkbox">
|
||||||
|
<input
|
||||||
|
id="key_alt"
|
||||||
|
ref="key_alt"
|
||||||
|
:checked="edit_data.display.keys & 4"
|
||||||
|
type="checkbox"
|
||||||
|
class="tw-checkbox__input"
|
||||||
|
@change="onChangeKeys"
|
||||||
|
>
|
||||||
|
<label for="key_alt" class="tw-checkbox__label">
|
||||||
|
{{ t('setting.key.alt', 'Alt') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tw-pd-r-1 tw-checkbox">
|
||||||
|
<input
|
||||||
|
id="key_meta"
|
||||||
|
ref="key_meta"
|
||||||
|
:checked="edit_data.display.keys & 8"
|
||||||
|
type="checkbox"
|
||||||
|
class="tw-checkbox__input"
|
||||||
|
@change="onChangeKeys"
|
||||||
|
>
|
||||||
|
<label for="key_meta" class="tw-checkbox__label">
|
||||||
|
{{ t('setting.key.meta', 'Meta') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tw-pd-t-05">
|
||||||
|
Note: This currently requires Chat > Behavior > Freeze Chat Scrolling to be enabled.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="tw-mg-t-1 tw-border-t tw-pd-t-1">
|
<section class="tw-mg-t-1 tw-border-t tw-pd-t-1">
|
||||||
|
@ -215,7 +285,7 @@
|
||||||
import {has, maybe_call, deep_copy} from 'utilities/object';
|
import {has, maybe_call, deep_copy} from 'utilities/object';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['action', 'data', 'inline', 'context'],
|
props: ['action', 'data', 'inline', 'context', 'modifiers'],
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -237,6 +307,10 @@ export default {
|
||||||
return this.context && this.context.includes('message')
|
return this.context && this.context.includes('message')
|
||||||
},
|
},
|
||||||
|
|
||||||
|
has_modifiers() {
|
||||||
|
return this.modifiers
|
||||||
|
},
|
||||||
|
|
||||||
vars() {
|
vars() {
|
||||||
const out = [],
|
const out = [],
|
||||||
ctx = this.context || [];
|
ctx = this.context || [];
|
||||||
|
@ -373,6 +447,24 @@ export default {
|
||||||
else if ( disp.deleted === false )
|
else if ( disp.deleted === false )
|
||||||
out.push(this.t('setting.actions.visible.undeleted', 'if message not deleted'));
|
out.push(this.t('setting.actions.visible.undeleted', 'if message not deleted'));
|
||||||
|
|
||||||
|
if ( disp.keys ) {
|
||||||
|
const key_out = [];
|
||||||
|
if ( disp.keys & 1 )
|
||||||
|
key_out.push(this.t('setting.key.ctrl', 'Ctrl'));
|
||||||
|
if ( disp.keys & 2 )
|
||||||
|
key_out.push(this.t('setting.key.shift', 'Shift'));
|
||||||
|
if ( disp.keys & 4 )
|
||||||
|
key_out.push(this.t('setting.key.alt', 'Alt'));
|
||||||
|
if ( disp.keys & 8 )
|
||||||
|
key_out.push(this.t('setting.key.meta', 'Meta'));
|
||||||
|
|
||||||
|
if ( key_out.length )
|
||||||
|
out.push(this.t('setting.actions.visible.modifier', 'when {key_list} {keys, plural, one {is} other {are}} held', {
|
||||||
|
key_list: key_out.join(' + '),
|
||||||
|
keys: key_out.length
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! out.length )
|
if ( ! out.length )
|
||||||
return this.t('setting.actions.visible.always', 'always');
|
return this.t('setting.actions.visible.always', 'always');
|
||||||
|
|
||||||
|
@ -392,6 +484,23 @@ export default {
|
||||||
this.edit_data.options = val;
|
this.edit_data.options = val;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onChangeKeys() {
|
||||||
|
if ( ! this.editing )
|
||||||
|
return;
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
if ( this.$refs.key_ctrl.checked )
|
||||||
|
i |= 1;
|
||||||
|
if ( this.$refs.key_shift.checked )
|
||||||
|
i |= 2;
|
||||||
|
if ( this.$refs.key_alt.checked )
|
||||||
|
i |= 4;
|
||||||
|
if ( this.$refs.key_meta.checked )
|
||||||
|
i |= 8;
|
||||||
|
|
||||||
|
this.edit_data.display.keys = i;
|
||||||
|
},
|
||||||
|
|
||||||
edit() {
|
edit() {
|
||||||
if ( ! this.canEdit )
|
if ( ! this.canEdit )
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -193,6 +193,7 @@
|
||||||
:data="data"
|
:data="data"
|
||||||
:inline="item.inline"
|
:inline="item.inline"
|
||||||
:context="item.context"
|
:context="item.context"
|
||||||
|
:modifiers="item.modifiers"
|
||||||
@remove="remove(act)"
|
@remove="remove(act)"
|
||||||
@save="save(act, $event)"
|
@save="save(act, $event)"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -38,7 +38,7 @@ export default class BitsButton extends Module {
|
||||||
|
|
||||||
this.BitsButton = this.fine.define(
|
this.BitsButton = this.fine.define(
|
||||||
'bits-button',
|
'bits-button',
|
||||||
n => n.renderButton && n.toggleShowTutorial
|
n => n.toggleBalloon && n.toggleShowTutorial
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -214,6 +214,16 @@ export default class ChatHook extends Module {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.settings.add('chat.use-width', {
|
||||||
|
requires: ['chat.width', 'context.ui.rightColumnExpanded'],
|
||||||
|
process(ctx) {
|
||||||
|
if ( ! ctx.get('context.ui.rightColumnExpanded') )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ctx.get('chat.width') != 340;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.settings.add('chat.bits.show-pinned', {
|
this.settings.add('chat.bits.show-pinned', {
|
||||||
default: true,
|
default: true,
|
||||||
ui: {
|
ui: {
|
||||||
|
@ -349,6 +359,14 @@ export default class ChatHook extends Module {
|
||||||
|
|
||||||
|
|
||||||
updateChatCSS() {
|
updateChatCSS() {
|
||||||
|
if ( ! this._update_chat_css_timer )
|
||||||
|
this._update_chat_css_timer = setTimeout(() => this._updateChatCSS(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateChatCSS() {
|
||||||
|
clearTimeout(this._update_chat_css_timer);
|
||||||
|
this._update_chat_css_timer = null;
|
||||||
|
|
||||||
const width = this.chat.context.get('chat.width'),
|
const width = this.chat.context.get('chat.width'),
|
||||||
size = this.chat.context.get('chat.font-size'),
|
size = this.chat.context.get('chat.font-size'),
|
||||||
emote_alignment = this.chat.context.get('chat.lines.emote-alignment'),
|
emote_alignment = this.chat.context.get('chat.lines.emote-alignment'),
|
||||||
|
@ -364,7 +382,7 @@ export default class ChatHook extends Module {
|
||||||
this.css_tweaks.setVariable('chat-width', `${width/10}rem`);
|
this.css_tweaks.setVariable('chat-width', `${width/10}rem`);
|
||||||
|
|
||||||
this.css_tweaks.toggle('chat-font', size !== 12 || font);
|
this.css_tweaks.toggle('chat-font', size !== 12 || font);
|
||||||
this.css_tweaks.toggle('chat-width', width !== 340);
|
this.css_tweaks.toggle('chat-width', this.chat.context.get('chat.use-width'));
|
||||||
|
|
||||||
this.css_tweaks.toggle('emote-alignment-padded', emote_alignment === 1);
|
this.css_tweaks.toggle('emote-alignment-padded', emote_alignment === 1);
|
||||||
this.css_tweaks.toggle('emote-alignment-baseline', emote_alignment === 2);
|
this.css_tweaks.toggle('emote-alignment-baseline', emote_alignment === 2);
|
||||||
|
@ -421,6 +439,7 @@ export default class ChatHook extends Module {
|
||||||
this.grabTypes();
|
this.grabTypes();
|
||||||
|
|
||||||
this.chat.context.on('changed:chat.width', this.updateChatCSS, this);
|
this.chat.context.on('changed:chat.width', this.updateChatCSS, this);
|
||||||
|
this.chat.context.on('changed:chat.use-width', this.updateChatCSS, this);
|
||||||
this.chat.context.on('changed:chat.font-size', this.updateChatCSS, this);
|
this.chat.context.on('changed:chat.font-size', this.updateChatCSS, this);
|
||||||
this.chat.context.on('changed:chat.font-family', this.updateChatCSS, this);
|
this.chat.context.on('changed:chat.font-family', this.updateChatCSS, this);
|
||||||
this.chat.context.on('changed:chat.lines.emote-alignment', this.updateChatCSS, this);
|
this.chat.context.on('changed:chat.lines.emote-alignment', this.updateChatCSS, this);
|
||||||
|
|
|
@ -156,8 +156,9 @@ export default class ChatLine extends Module {
|
||||||
e('span', {
|
e('span', {
|
||||||
className: 'chat-line__message--badges'
|
className: 'chat-line__message--badges'
|
||||||
}, t.chat.badges.render(msg, e)),
|
}, t.chat.badges.render(msg, e)),
|
||||||
e('button', {
|
e('span', {
|
||||||
className: 'chat-line__username notranslate',
|
className: 'chat-line__username notranslate',
|
||||||
|
role: 'button',
|
||||||
style: { color },
|
style: { color },
|
||||||
onClick: this.ffz_user_click_handler
|
onClick: this.ffz_user_click_handler
|
||||||
}, [
|
}, [
|
||||||
|
@ -414,8 +415,9 @@ other {# messages were deleted by a moderator.}
|
||||||
e('span', {
|
e('span', {
|
||||||
className: 'chat-line__message--badges'
|
className: 'chat-line__message--badges'
|
||||||
}, t.chat.badges.render(msg, e)),
|
}, t.chat.badges.render(msg, e)),
|
||||||
e('button', {
|
e('span', {
|
||||||
className: 'chat-line__username notranslate',
|
className: 'chat-line__username notranslate',
|
||||||
|
role: 'button',
|
||||||
style: { color },
|
style: { color },
|
||||||
onClick: this.ffz_user_click_handler
|
onClick: this.ffz_user_click_handler
|
||||||
}, [
|
}, [
|
||||||
|
@ -774,8 +776,9 @@ other {# messages were deleted by a moderator.}
|
||||||
e('span', {
|
e('span', {
|
||||||
className: 'chat-line__message--badges'
|
className: 'chat-line__message--badges'
|
||||||
}, t.chat.badges.render(msg, e)),
|
}, t.chat.badges.render(msg, e)),
|
||||||
e('button', {
|
e('span', {
|
||||||
className: 'chat-line__username notranslate',
|
className: 'chat-line__username notranslate',
|
||||||
|
role: 'button',
|
||||||
style: { color },
|
style: { color },
|
||||||
onClick: this.onExtensionNameClick
|
onClick: this.onExtensionNameClick
|
||||||
}, e('span', {
|
}, e('span', {
|
||||||
|
|
|
@ -65,6 +65,19 @@ export default class Scroller extends Module {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateUseKeys() {
|
||||||
|
const old_use = this.use_keys;
|
||||||
|
this.use_keys = false;
|
||||||
|
for(const act of this.chat.context.get('chat.actions.inline'))
|
||||||
|
if ( act && act.display && act.display.keys )
|
||||||
|
this.use_keys = true;
|
||||||
|
|
||||||
|
if ( this.use_keys !== old_use ) {
|
||||||
|
for(const inst of this.ChatScroller.instances)
|
||||||
|
inst && inst.ffzUpdateKeys && inst.ffzUpdateKeys();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onEnable() {
|
onEnable() {
|
||||||
this.on('i18n:update', () => {
|
this.on('i18n:update', () => {
|
||||||
for(const inst of this.ChatScroller.instances)
|
for(const inst of this.ChatScroller.instances)
|
||||||
|
@ -82,6 +95,9 @@ export default class Scroller extends Module {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.chat.context.on('changed:chat.actions.inline', this.updateUseKeys, this);
|
||||||
|
this.updateUseKeys();
|
||||||
|
|
||||||
this.smoothScroll = this.chat.context.get('chat.scroller.smooth-scroll');
|
this.smoothScroll = this.chat.context.get('chat.scroller.smooth-scroll');
|
||||||
this.chat.context.on('changed:chat.scroller.smooth-scroll', val => {
|
this.chat.context.on('changed:chat.scroller.smooth-scroll', val => {
|
||||||
this.smoothScroll = val;
|
this.smoothScroll = val;
|
||||||
|
@ -437,6 +453,8 @@ export default class Scroller extends Module {
|
||||||
this.ffz_ctrl = e.ctrlKey;
|
this.ffz_ctrl = e.ctrlKey;
|
||||||
this.ffz_meta = e.metaKey;
|
this.ffz_meta = e.metaKey;
|
||||||
|
|
||||||
|
this.ffzUpdateKeys();
|
||||||
|
|
||||||
if ( this.ffz_outside || t.freeze < 2 )
|
if ( this.ffz_outside || t.freeze < 2 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -451,8 +469,43 @@ export default class Scroller extends Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cls.prototype.ffzUpdateKeys = function() {
|
||||||
|
if ( ! this._ffz_key_update )
|
||||||
|
this._ffz_key_update = requestAnimationFrame(() => this.ffz_updateKeys());
|
||||||
|
}
|
||||||
|
|
||||||
|
cls.prototype.ffz_updateKeys = function() {
|
||||||
|
cancelAnimationFrame(this._ffz_key_update);
|
||||||
|
this._ffz_key_update = null;
|
||||||
|
|
||||||
|
if ( ! t.use_keys && this.ffz_use_keys === t.use_keys )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( ! this.scroll || ! this.scroll.root )
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.ffz_use_keys = t.use_keys;
|
||||||
|
this.scroll.root.classList.toggle('ffz--keys', t.use_keys);
|
||||||
|
|
||||||
|
const ds = this.scroll.root.dataset;
|
||||||
|
|
||||||
|
if ( ! t.use_keys ) {
|
||||||
|
delete ds.alt;
|
||||||
|
delete ds.ctrl;
|
||||||
|
delete ds.shift;
|
||||||
|
delete ds.meta;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ds.alt = ! this.ffz_outside && this.ffz_alt;
|
||||||
|
ds.ctrl = ! this.ffz_outside && this.ffz_ctrl;
|
||||||
|
ds.shift = ! this.ffz_outside && this.ffz_shift;
|
||||||
|
ds.meta = ! this.ffz_outside && this.ffz_meta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cls.prototype.ffzMouseMove = function(e) {
|
cls.prototype.ffzMouseMove = function(e) {
|
||||||
this.ffz_last_move = Date.now();
|
this.ffz_last_move = Date.now();
|
||||||
|
const was_outside = this.ffz_outside;
|
||||||
this.ffz_outside = false;
|
this.ffz_outside = false;
|
||||||
if ( this._ffz_outside ) {
|
if ( this._ffz_outside ) {
|
||||||
clearTimeout(this._ffz_outside);
|
clearTimeout(this._ffz_outside);
|
||||||
|
@ -465,8 +518,13 @@ export default class Scroller extends Module {
|
||||||
e.ctrlKey === this.ffz_ctrl &&
|
e.ctrlKey === this.ffz_ctrl &&
|
||||||
e.metaKey === this.ffz_meta &&
|
e.metaKey === this.ffz_meta &&
|
||||||
e.screenY === this.ffz_sy &&
|
e.screenY === this.ffz_sy &&
|
||||||
e.screenX === this.ffz_sx)
|
e.screenX === this.ffz_sx) {
|
||||||
|
|
||||||
|
if ( was_outside )
|
||||||
|
this.ffzUpdateKeys();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.ffz_alt = e.altKey;
|
this.ffz_alt = e.altKey;
|
||||||
this.ffz_shift = e.shiftKey;
|
this.ffz_shift = e.shiftKey;
|
||||||
|
@ -475,6 +533,8 @@ export default class Scroller extends Module {
|
||||||
this.ffz_sy = e.screenY;
|
this.ffz_sy = e.screenY;
|
||||||
this.ffz_sx = e.screenX;
|
this.ffz_sx = e.screenX;
|
||||||
|
|
||||||
|
this.ffzUpdateKeys();
|
||||||
|
|
||||||
const should_freeze = this.ffzShouldBeFrozen(),
|
const should_freeze = this.ffzShouldBeFrozen(),
|
||||||
changed = should_freeze !== this.ffz_frozen;
|
changed = should_freeze !== this.ffz_frozen;
|
||||||
|
|
||||||
|
@ -492,6 +552,7 @@ export default class Scroller extends Module {
|
||||||
clearTimeout(this._ffz_outside);
|
clearTimeout(this._ffz_outside);
|
||||||
|
|
||||||
this._ffz_outside = setTimeout(() => this.ffzMaybeUnfreeze(), 64);
|
this._ffz_outside = setTimeout(() => this.ffzMaybeUnfreeze(), 64);
|
||||||
|
this.ffzUpdateKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,9 +61,7 @@ export default class Layout extends Module {
|
||||||
const ratio = size.width / size.height;
|
const ratio = size.width / size.height;
|
||||||
return ratio <= ctx.get('layout.portrait-threshold');
|
return ratio <= ctx.get('layout.portrait-threshold');
|
||||||
},
|
},
|
||||||
changed: val => {
|
changed: () => this.updatePortraitMode()
|
||||||
this.updatePortraitMode();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.settings.add('layout.inject-portrait', {
|
this.settings.add('layout.inject-portrait', {
|
||||||
|
|
|
@ -120,7 +120,9 @@ export default class Dialog extends EventEmitter {
|
||||||
container.classList.toggle('ffz-has-dialog', visible);
|
container.classList.toggle('ffz-has-dialog', visible);
|
||||||
|
|
||||||
if ( ! visible ) {
|
if ( ! visible ) {
|
||||||
|
if ( this._element )
|
||||||
this._element.remove();
|
this._element.remove();
|
||||||
|
|
||||||
this.emit('hide');
|
this.emit('hide');
|
||||||
|
|
||||||
if ( this.factory )
|
if ( this.factory )
|
||||||
|
@ -154,7 +156,7 @@ export default class Dialog extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSize(event) {
|
toggleSize(event) {
|
||||||
if ( ! this._visible || event && event.button !== 0 )
|
if ( ! this._visible || event && event.button !== 0 || ! this._element )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._maximized = !this._maximized;
|
this._maximized = !this._maximized;
|
||||||
|
|
|
@ -53,6 +53,55 @@
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chat-line__message {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ffz--modifier-actions {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: .5rem 0;
|
||||||
|
|
||||||
|
background: rgba(255,255,255,0.5);
|
||||||
|
|
||||||
|
.dark-theme &,
|
||||||
|
.tw-root--theme-dark & {
|
||||||
|
background: rgba(0,0,0,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ffz-mod-icon {
|
||||||
|
margin: 0 .5rem;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ffz--keys {
|
||||||
|
&[data-ctrl="true"] .ffz-modifier-1,
|
||||||
|
&[data-shift="true"] .ffz-modifier-2,
|
||||||
|
&[data-shift="true"][data-ctrl="true"] .ffz-modifier-3,
|
||||||
|
&[data-alt="true"] .ffz-modifier-4,
|
||||||
|
&[data-alt="true"][data-ctrl="true"] .ffz-modifier-5,
|
||||||
|
&[data-alt="true"][data-shift="true"] .ffz-modifier-6,
|
||||||
|
&[data-alt="true"][data-ctrl="true"][data-shift="true"] .ffz-modifier-7,
|
||||||
|
&[data-meta="true"] .ffz-modifier-8,
|
||||||
|
|
||||||
|
&[data-meta="true"][data-ctrl="true"] .ffz-modifier-9,
|
||||||
|
&[data-meta="true"][data-shift="true"] .ffz-modifier-10,
|
||||||
|
&[data-meta="true"][data-shift="true"][data-ctrl="true"] .ffz-modifier-11,
|
||||||
|
&[data-meta="true"][data-alt="true"] .ffz-modifier-12,
|
||||||
|
&[data-meta="true"][data-alt="true"][data-ctrl="true"] .ffz-modifier-13,
|
||||||
|
&[data-meta="true"][data-alt="true"][data-shift="true"] .ffz-modifier-14,
|
||||||
|
&[data-meta="true"][data-alt="true"][data-ctrl="true"][data-shift="true"] .ffz-modifier-15 {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ffz--modifier-actions:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.ffz--favorite {
|
.ffz--favorite {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue