1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-07-28 13:38:30 +00:00
* Added: Chat Action for editing a user's displayed name and color. Only applies to chat.
* Changed: Re-enable the setting for hiding offline channels from the side-bar.
* Changed: Updated dependencies.
* Fixed: Issue with multiple copies of FFZ emotes appearing in tab-completion.
* Fixed: Issue with tab-completion crashing sometimes in mod view. (Closes #839)
* Fixed: Support for swapping sidebars with the latest Twitch changes.
* Fixed: Hiding Recommended Channels from the sidebar. (Closes #840)
* Removed: Setting for hiding Recommended Friends from the sidebar, since that section no longer exists.
This commit is contained in:
SirStendec 2020-07-10 20:08:29 -04:00
parent 50378bb3dc
commit 7638a885f2
16 changed files with 2862 additions and 2420 deletions

4798
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
{ {
"name": "frankerfacez", "name": "frankerfacez",
"author": "Dan Salvato LLC", "author": "Dan Salvato LLC",
"version": "4.20.4", "version": "4.20.5",
"description": "FrankerFaceZ is a Twitch enhancement suite.", "description": "FrankerFaceZ is a Twitch enhancement suite.",
"license": "Apache-2.0", "license": "Apache-2.0",
"scripts": { "scripts": {
@ -24,38 +24,38 @@
"font:update": "node bin/update_fonts" "font:update": "node bin/update_fonts"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.7.7", "@babel/core": "^7.10.4",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.7.4", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4",
"@babel/plugin-proposal-object-rest-spread": "^7.7.7", "@babel/plugin-proposal-object-rest-spread": "^7.10.4",
"@babel/plugin-proposal-optional-chaining": "^7.7.5", "@babel/plugin-proposal-optional-chaining": "^7.10.4",
"@babel/plugin-syntax-dynamic-import": "^7.7.4", "@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-react-jsx": "^7.7.7", "@babel/plugin-transform-react-jsx": "^7.10.4",
"@ffz/fontello-cli": "^1.0.3", "@ffz/fontello-cli": "^1.0.3",
"babel-eslint": "^10.0.3", "babel-eslint": "^10.1.0",
"babel-loader": "^8.0.6", "babel-loader": "^8.1.0",
"clean-webpack-plugin": "^3.0.0", "clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^5.1.1", "copy-webpack-plugin": "^5.1.1",
"cross-env": "^6.0.3", "cross-env": "^7.0.2",
"css-loader": "^3.1.0", "css-loader": "^3.1.0",
"eslint": "^6.8.0", "eslint": "^7.3.1",
"eslint-plugin-react": "^7.17.0", "eslint-plugin-react": "^7.20.3",
"eslint-plugin-vue": "^6.1.2", "eslint-plugin-vue": "^6.2.2",
"extract-loader": "^2.0.1", "extract-loader": "^2.0.1",
"file-loader": "^4.1.0", "file-loader": "^4.1.0",
"json-loader": "^0.5.7", "json-loader": "^0.5.7",
"node-sass": "^4.12.0", "node-sass": "^4.14.1",
"raw-loader": "^3.1.0", "raw-loader": "^3.1.0",
"rimraf": "^3.0.0", "rimraf": "^3.0.2",
"sass-loader": "^7.1.0", "sass-loader": "^7.1.0",
"semver": "^7.1.1", "semver": "^7.3.2",
"terser-webpack-plugin": "^2.3.1", "terser-webpack-plugin": "^3.0.6",
"vue": "^2.6.11", "vue": "^2.6.11",
"vue-loader": "^15.8.3", "vue-loader": "^15.8.3",
"vue-observe-visibility": "^0.4.6", "vue-observe-visibility": "^0.4.6",
"vue-template-compiler": "^2.6.11", "vue-template-compiler": "^2.6.11",
"webpack": "^4.41.5", "webpack": "^4.43.0",
"webpack-cli": "^3.3.10", "webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.10.1", "webpack-dev-server": "^3.11.0",
"webpack-manifest-plugin": "^2.2.0", "webpack-manifest-plugin": "^2.2.0",
"webpack-merge": "^4.2.2" "webpack-merge": "^4.2.2"
}, },
@ -65,26 +65,26 @@
}, },
"dependencies": { "dependencies": {
"@ffz/icu-msgparser": "^1.0.2", "@ffz/icu-msgparser": "^1.0.2",
"crypto-js": "^3.1.9-1", "crypto-js": "^4.0.0",
"dayjs": "^1.8.18", "dayjs": "^1.8.29",
"displacejs": "^1.4.0", "displacejs": "^1.4.1",
"emoji-regex": "^8.0.0", "emoji-regex": "^8.0.0",
"file-saver": "^2.0.1", "file-saver": "^2.0.1",
"graphql": "^14.5.8", "graphql": "^15.2.0",
"graphql-tag": "^2.9.1", "graphql-tag": "^2.10.3",
"js-cookie": "^2.2.1", "js-cookie": "^2.2.1",
"markdown-it": "^9.0.1", "markdown-it": "^11.0.0",
"markdown-it-link-attributes": "^2.1.0", "markdown-it-link-attributes": "^3.0.0",
"path-to-regexp": "^3.0.0", "path-to-regexp": "^3.0.0",
"popper.js": "^1.14.3", "popper.js": "^1.14.3",
"raven-js": "^3.24.2", "raven-js": "^3.24.2",
"react": "^16.4.1", "react": "^16.13.1",
"safe-regex": "^2.0.2", "safe-regex": "^2.1.1",
"sortablejs": "^1.10.0-rc3", "sortablejs": "^1.10.2",
"sourcemapped-stacktrace": "^1.1.11", "sourcemapped-stacktrace": "^1.1.11",
"text-diff": "^1.0.1", "text-diff": "^1.0.1",
"vue-clickaway": "^2.2.2", "vue-clickaway": "^2.2.2",
"vue-color": "^2.4.6", "vue-color": "^2.7.1",
"vuedraggable": "^2.23.0" "vuedraggable": "^2.23.2"
} }
} }

View file

@ -328,7 +328,10 @@ export default class Actions extends Module {
fp.destroy(); fp.destroy();
} }
target._ffz_destroy = target._ffz_outside = null; if ( target._ffz_on_destroy )
target._ffz_on_destroy();
target._ffz_destroy = target._ffz_outside = target._ffz_on_destroy = null;
} }
const parent = document.body.querySelector('#root>div') || document.body, const parent = document.body.querySelector('#root>div') || document.body,
@ -496,8 +499,8 @@ export default class Actions extends Module {
let line = null; let line = null;
const handle_click = event => { const handle_click = event => {
tip.hide();
this.handleClick(event); this.handleClick(event);
tip.hide();
}; };
for(const data of actions) { for(const data of actions) {

View file

@ -1,6 +1,32 @@
'use strict'; 'use strict';
import {createElement} from 'utilities/dom'; // ============================================================================
// Edit Overrides
// ============================================================================
export const edit_overrides = {
presets: [{
appearance: {
type: 'icon',
icon: 'ffz-i-pencil'
}
}],
required_context: ['user'],
title: 'Change Name & Color',
description: 'Allows you to set local overrides for a user\'s name and color in chat.',
tooltip() {
return this.i18n.t('chat.actions.edit_overrides', 'Change Name & Color')
},
click(event, data) {
//const ref = makeReference(event.clientX, event.clientY);
this.resolve('chat.overrides').renderUserEditor(data.user, event.target);
}
}
// ============================================================================ // ============================================================================
// Open URL // Open URL

View file

@ -0,0 +1,129 @@
<template>
<div class="ffz-override-editor tw-c-background-base tw-c-text-base tw-pd-05 tw-pd-l-1">
<div class="tw-flex tw-align-items-center tw-pd-b-05 tw-border-b tw-mg-b-05">
<div class="tw-flex-grow-1">
{{ t('chat.overrides.editing', 'Editing {user.login}...', {user}) }}
</div>
<button
class="tw-mg-l-05 tw-button tw-button--text"
@click="close"
>
<span class="tw-button__text ffz-i-window-close" />
</button>
</div>
<div class="tw-flex tw-align-items-center">
<label for="user-name" class="tw-mg-r-1">
{{ t('chat.overrides.name', 'Name') }}
</label>
<input
id="user-name"
ref="name"
class="tw-border-radius-medium tw-font-size-6 tw-pd-x-1 tw-pd-y-05 tw-input tw-flex-grow-1"
:value="name"
@change="updateName"
>
<button
class="tw-mg-l-05 tw-button tw-button--text tw-tooltip-wrapper"
:class="{'tw-button--disabled': name == null}"
@click="clearName"
>
<span class="tw-button__text ffz-i-cancel" />
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.reset', 'Reset to Default') }}
</div>
</button>
</div>
<div class="tw-flex tw-align-items-center">
<label for="user-color" class="tw-mg-r-1">
{{ t('chat.overrides.color', 'Color') }}
</label>
<color-picker
id="user-color"
ref="color"
:alpha="false"
:nullable="true"
:value="editColor"
@input="updateColor"
/>
<button
class="tw-mg-l-05 tw-button tw-button--text tw-tooltip-wrapper"
:class="{'tw-button--disabled': color == null}"
@click="clearColor"
>
<span class="tw-button__text ffz-i-cancel" />
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.reset', 'Reset to Default') }}
</div>
</button>
</div>
</div>
</template>
<script>
import { debounce } from 'utilities/object';
export default {
data() {
return this.$vnode.data
},
computed: {
editColor() {
if ( ! this.color )
return '';
return this.color;
}
},
created() {
this.updateName = debounce(this.updateName, 250);
this.updateColor = debounce(this.updateColor, 250);
},
updated() {
this.updateTip();
},
methods: {
clearName() {
this.name = null;
this.deleteName();
},
updateName() {
const value = this.$refs.name.value;
if ( value == null || ! value.length ) {
this.clearName();
return;
}
this.name = value;
this.setName(value);
},
clearColor() {
this.color = null;
this.deleteColor();
},
updateColor(value) {
if ( value == null || ! value.length ) {
this.clearColor();
return;
}
this.color = value;
this.setColor(value);
}
}
}
</script>

View file

@ -5,6 +5,8 @@
// ============================================================================ // ============================================================================
import Module from 'utilities/module'; import Module from 'utilities/module';
import { createElement, ClickOutside } from 'utilities/dom';
import Tooltip from 'utilities/tooltip';
export default class Overrides extends Module { export default class Overrides extends Module {
@ -12,14 +14,126 @@ export default class Overrides extends Module {
super(...args); super(...args);
this.inject('settings'); this.inject('settings');
this.color_cache = null; this.color_cache = null;
this.name_cache = null; this.name_cache = null;
/*this.settings.addUI('chat.overrides', {
path: 'Chat > Overrides @{"profile_warning": false}',
component: 'chat-overrides',
on: (...args) => this.on(...args),
off: (...args) => this.off(...args),
setColor: (...args) => this.setColor(...args),
setName: (...args) => this.setName(...args),
deleteColor: id => this.deleteColor(id),
deleteName: id => this.deleteName(id),
getColors: () => this.colors,
getNames: () => this.names
});*/
} }
onEnable() { onEnable() {
this.settings.provider.on('changed', this.onProviderChange, this); this.settings.provider.on('changed', this.onProviderChange, this);
} }
renderUserEditor(user, target) {
let outside, popup, ve;
const destroy = () => {
const o = outside, p = popup, v = ve;
outside = popup = ve = null;
if ( o )
o.destroy();
if ( p )
p.destroy();
if ( v )
v.$destroy();
}
const parent = document.body.querySelector('#root>div') || document.body;
popup = new Tooltip(parent, [], {
logger: this.log,
manual: true,
live: false,
html: true,
hover_events: true,
no_update: true,
no_auto_remove: true,
tooltipClass: 'ffz-action-balloon tw-balloon tw-block tw-border tw-elevation-1 tw-border-radius-small tw-c-background-base',
arrowClass: '', //tw-balloon__tail tw-overflow-hidden tw-absolute',
arrowInner: '', //tw-balloon__tail-symbol tw-border-t tw-border-r tw-border-b tw-border-l tw-border-radius-small tw-c-background-base tw-absolute',
innerClass: '',
popper: {
placement: 'bottom',
modifiers: {
preventOverflow: {
boundariesElement: parent
},
flip: {
behavior: ['bottom', 'top', 'left', 'right']
}
}
},
content: async (t, tip) => {
const vue = this.resolve('vue'),
_editor = import(/* webpackChunkName: "overrides" */ './override-editor.vue');
const [, editor] = await Promise.all([vue.enable(), _editor]);
vue.component('override-editor', editor.default);
ve = new vue.Vue({
el: createElement('div'),
render: h => h('override-editor', {
user,
name: this.getName(user.id),
color: this.getColor(user.id),
updateTip: () => tip.update(),
setColor: val => this.setColor(user.id, val),
deleteColor: () => this.deleteColor(user.id),
setName: val => this.setName(user.id, val),
deleteName: () => this.deleteName(user.id),
close: () => tip.hide()
})
});
return ve.$el;
},
onShow: async (t, tip) => {
await tip.waitForDom();
requestAnimationFrame(() => {
outside = new ClickOutside(tip.outer, destroy)
});
},
onMove: (target, tip, event) => {
this.emit('tooltips:mousemove', target, tip, event)
},
onLeave: (target, tip, event) => {
this.emit('tooltips:leave', target, tip, event);
},
onHide: destroy
});
popup._enter(target);
}
onProviderChange(key) { onProviderChange(key) {
if ( key === 'overrides.colors' ) if ( key === 'overrides.colors' )
this.loadColors(); this.loadColors();

View file

@ -613,6 +613,8 @@ export default class MainMenu extends Module {
deleteProfile: profile => settings.deleteProfile(profile), deleteProfile: profile => settings.deleteProfile(profile),
getFFZ: () => t.resolve('core'),
context: { context: {
_users: 0, _users: 0,

View file

@ -37,11 +37,11 @@ export default class Channel extends Module {
} }
}); });
/*this.SideNav = this.elemental.define( this.SideNav = this.elemental.define(
'side-nav', '.side-bar-contents .side-nav-section:first-child', 'side-nav', '.side-bar-contents .side-nav-section:first-child',
null, null,
{childNodes: true, subtree: true}, 1 {childNodes: true, subtree: true}, 1
);*/ );
this.ChannelRoot = this.elemental.define( this.ChannelRoot = this.elemental.define(
'channel-root', '.channel-root', 'channel-root', '.channel-root',
@ -59,8 +59,9 @@ export default class Channel extends Module {
onEnable() { onEnable() {
this.updateChannelColor(); this.updateChannelColor();
//this.SideNav.on('mount', this.updateHidden, this); this.SideNav.on('mount', this.updateHidden, this);
//this.SideNav.on('mutate', this.updateHidden, this); this.SideNav.on('mutate', this.updateHidden, this);
this.SideNav.each(el => this.updateHidden(el));
this.ChannelRoot.on('mount', this.updateRoot, this); this.ChannelRoot.on('mount', this.updateRoot, this);
this.ChannelRoot.on('mutate', this.updateRoot, this); this.ChannelRoot.on('mutate', this.updateRoot, this);
@ -87,18 +88,21 @@ export default class Channel extends Module {
} }
} }
/*updateHidden(el) { // eslint-disable-line class-methods-use-this updateHidden(el) { // eslint-disable-line class-methods-use-this
if ( ! el._ffz_raf ) if ( ! el._ffz_raf )
el._ffz_raf = requestAnimationFrame(() => { el._ffz_raf = requestAnimationFrame(() => {
el._ffz_raf = null; el._ffz_raf = null;
const nodes = el.querySelectorAll('.side-nav-card__avatar--offline'); const nodes = el.querySelectorAll('.side-nav-card');
for(const node of nodes) { for(const node of nodes) {
const par = node.closest('.tw-transition'); const react = this.fine.getReactInstance(node),
if ( par && el.contains(par) ) props = react?.return?.return?.return?.memoizedProps;
par.classList.add('tw-hide');
const offline = props?.offline ?? node.querySelector('.side-nav-card__avatar--offline') != null;
node.classList.toggle('ffz--offline-side-nav', offline);
} }
}); });
}*/ }
updateSubscription(login) { updateSubscription(login) {
if ( this._subbed_login === login ) if ( this._subbed_login === login )

View file

@ -405,16 +405,23 @@ export default class Input extends Module {
} }
inst.doesEmoteMatchTerm = function(emote, term) { inst.doesEmoteMatchTerm = function(emote, term) {
const emote_name = emote.name || emote.token, const emote_name = emote.name || emote.token;
emote_lower = emote_name.toLowerCase(), if ( ! emote_name )
term_lower = term.toLowerCase(); return false;
let emote_lower = emote.tokenLower;
if ( ! emote_lower )
emote_lower = emote_name.toLowerCase();
const term_lower = term.toLowerCase();
if (emote_lower.startsWith(term_lower)) if (emote_lower.startsWith(term_lower))
return true; return true;
const idx = emote_name.indexOf(term.charAt(0).toUpperCase()); const idx = emote_name.indexOf(term.charAt(0).toUpperCase());
if (idx !== -1) if (idx !== -1)
return emote_lower.slice(idx + 1).startsWith(term_lower.slice(1)); return emote_lower.slice(idx + 1).startsWith(term_lower.slice(1));
return false;
} }
inst.getMatchedEmotes = function(input) { inst.getMatchedEmotes = function(input) {
@ -532,8 +539,12 @@ export default class Input extends Module {
continue; continue;
const id = emote.id, const id = emote.id,
replacement = REPLACEMENTS[id]; token = KNOWN_CODES[emote.token] || emote.token;
if ( ! token )
continue;
const replacement = REPLACEMENTS[id];
let src, srcSet; let src, srcSet;
if ( replacement && this.chat.context.get('chat.fix-bad-emotes') ) { if ( replacement && this.chat.context.get('chat.fix-bad-emotes') ) {
@ -548,7 +559,8 @@ export default class Input extends Module {
out.push({ out.push({
id, id,
setID: set.id, setID: set.id,
token: KNOWN_CODES[emote.token] || emote.token, token,
tokenLower: token.toLowerCase(),
srcSet, srcSet,
favorite: favorites.includes(id) favorite: favorites.includes(id)
}); });
@ -653,7 +665,8 @@ export default class Input extends Module {
const out = [], const out = [],
hidden_sets = this.settings.provider.get('emote-menu.hidden-sets'), hidden_sets = this.settings.provider.get('emote-menu.hidden-sets'),
has_hidden = Array.isArray(hidden_sets) && hidden_sets.length > 0; has_hidden = Array.isArray(hidden_sets) && hidden_sets.length > 0,
added_emotes = new Set;
for(const set of sets) { for(const set of sets) {
if ( ! set || ! set.emotes ) if ( ! set || ! set.emotes )
@ -669,12 +682,18 @@ export default class Input extends Module {
favorites = this.emotes.getFavorites(source); favorites = this.emotes.getFavorites(source);
for(const emote of Object.values(set.emotes)) { for(const emote of Object.values(set.emotes)) {
if ( ! emote || ! emote.id || hidden_emotes.includes(emote.id) ) if ( ! emote || ! emote.id || emote.hidden || hidden_emotes.includes(emote.id) || added_emotes.has(emote.name) )
continue; continue;
if ( ! emote.name )
continue;
added_emotes.add(emote.name);
out.push({ out.push({
id: `${source}-${emote.id}`, id: `${source}-${emote.id}`,
token: emote.name, token: emote.name,
tokenLower: emote.name.toLowerCase(),
srcSet: emote.srcSet, srcSet: emote.srcSet,
favorite: favorites.includes(emote.id) favorite: favorites.includes(emote.id)
}); });
@ -711,11 +730,10 @@ export default class Input extends Module {
return []; return [];
const search = input.startsWith(':') ? input.slice(1) : input, const search = input.startsWith(':') ? input.slice(1) : input,
results = [], results = [];
added_emotes = new Set();
for(const emote of emotes) { for(const emote of emotes) {
if ( inst.doesEmoteMatchTerm(emote, search) && ! added_emotes.has(emote.name) ) { if ( inst.doesEmoteMatchTerm(emote, search) )
results.push({ results.push({
current: input, current: input,
replacement: emote.token, replacement: emote.token,
@ -724,7 +742,6 @@ export default class Input extends Module {
count: 0 // TODO: Count stuff? count: 0 // TODO: Count stuff?
}); });
} }
}
return results; return results;

View file

@ -333,7 +333,7 @@ other {# messages were deleted by a moderator.}
onContextMenu: t.actions.handleUserContext onContextMenu: t.actions.handleUserContext
}, override_name ? [ }, override_name ? [
e('span', { e('span', {
className: 'chat-author__display_name' className: 'chat-author__display-name'
}, override_name), }, override_name),
e('div', { e('div', {
className: 'tw-tooltip tw-tooltip--down tw-tooltip--align-center' className: 'tw-tooltip tw-tooltip--down tw-tooltip--align-center'

View file

@ -13,12 +13,12 @@ const STYLE_VALIDATOR = document.createElement('span');
const CLASSES = { const CLASSES = {
'top-discover': '.navigation-link[data-a-target="discover-link"]', 'top-discover': '.navigation-link[data-a-target="discover-link"]',
'side-nav': '.side-nav', 'side-nav': '.side-nav',
'side-rec-channels': '.side-nav .recommended-channels', 'side-rec-channels': '.side-nav .recommended-channels,.side-nav .side-nav-section + .side-nav-section',
'side-rec-friends': '.side-nav .recommended-friends', //'side-rec-friends': '.side-nav .recommended-friends',
'side-friends': '.side-nav .online-friends', 'side-friends': '.side-nav .online-friends',
'side-closed-friends': '.side-nav--collapsed .online-friends', 'side-closed-friends': '.side-nav--collapsed .online-friends',
'side-closed-rec-channels': '.side-nav--collapsed .recommended-channels', 'side-closed-rec-channels': '.side-nav--collapsed .recommended-channels,.side-nav--collapsed .side-nav-section + .side-nav-section',
//'side-offline-channels': '.side-nav-card__link[href*="/videos/"],.side-nav-card[href*="/videos/"]', 'side-offline-channels': '.side-nav-card.ffz--offline-side-nav',
'side-rerun-channels': '.side-nav .ffz--side-nav-card-rerun', 'side-rerun-channels': '.side-nav .ffz--side-nav-card-rerun',
'community-highlights': '.community-highlight-stack__card', 'community-highlights': '.community-highlight-stack__card',
@ -37,7 +37,7 @@ const CLASSES = {
'dir-live-ind': '.preview-card[data-ffz-type="live"] .tw-channel-status-text-indicator,.live-channel-card:not([data-a-target*="host"]) .stream-type-indicator.stream-type-indicator--live,.stream-thumbnail__card .stream-type-indicator.stream-type-indicator--live,.preview-card .stream-type-indicator.stream-type-indicator--live,.preview-card .preview-card-stat.preview-card-stat--live', 'dir-live-ind': '.preview-card[data-ffz-type="live"] .tw-channel-status-text-indicator,.live-channel-card:not([data-a-target*="host"]) .stream-type-indicator.stream-type-indicator--live,.stream-thumbnail__card .stream-type-indicator.stream-type-indicator--live,.preview-card .stream-type-indicator.stream-type-indicator--live,.preview-card .preview-card-stat.preview-card-stat--live',
'profile-hover': '.preview-card .tw-relative:hover .ffz-channel-avatar', 'profile-hover': '.preview-card .tw-relative:hover .ffz-channel-avatar',
'not-live-bar': 'div[data-test-selector="non-live-video-banner-layout"]', 'not-live-bar': 'div[data-test-selector="non-live-video-banner-layout"]',
'channel-live-ind': '.channel-header__user .tw-channel-status-text-indicator', 'channel-live-ind': '.channel-header__user .tw-channel-status-text-indicator,.channel-info-content .user-avatar-animated__live',
'celebration': 'body .celebration__overlay', 'celebration': 'body .celebration__overlay',
'mod-view': '.chat-input__buttons-container .tw-core-button[href*="/moderator"]' 'mod-view': '.chat-input__buttons-container .tw-core-button[href*="/moderator"]'
}; };
@ -153,7 +153,7 @@ export default class CSSTweaks extends Module {
} }
}); });
this.settings.add('layout.side-nav.show-rec-friends', { /*this.settings.add('layout.side-nav.show-rec-friends', {
default: true, default: true,
ui: { ui: {
path: 'Appearance > Layout >> Side Navigation', path: 'Appearance > Layout >> Side Navigation',
@ -161,9 +161,9 @@ export default class CSSTweaks extends Module {
component: 'setting-check-box' component: 'setting-check-box'
}, },
changed: val => this.toggleHide('side-rec-friends', !val) changed: val => this.toggleHide('side-rec-friends', !val)
}); });*/
/*this.settings.add('layout.side-nav.hide-offline', { this.settings.add('layout.side-nav.hide-offline', {
default: false, default: false,
ui: { ui: {
path: 'Appearance > Layout >> Side Navigation', path: 'Appearance > Layout >> Side Navigation',
@ -171,7 +171,7 @@ export default class CSSTweaks extends Module {
component: 'setting-check-box' component: 'setting-check-box'
}, },
changed: val => this.toggleHide('side-offline-channels', val) changed: val => this.toggleHide('side-offline-channels', val)
});*/ });
this.settings.add('layout.side-nav.rerun-style', { this.settings.add('layout.side-nav.rerun-style', {
default: 1, default: 1,
@ -351,8 +351,8 @@ export default class CSSTweaks extends Module {
this.toggle('hide-side-nav-avatars', ! this.settings.get('layout.side-nav.show-avatars')); this.toggle('hide-side-nav-avatars', ! this.settings.get('layout.side-nav.show-avatars'));
this.toggle('hide-side-nav', !this.settings.get('layout.side-nav.show')); this.toggle('hide-side-nav', !this.settings.get('layout.side-nav.show'));
this.toggleHide('side-rec-friends', !this.settings.get('layout.side-nav.show-rec-friends')); //this.toggleHide('side-rec-friends', !this.settings.get('layout.side-nav.show-rec-friends'));
//this.toggleHide('side-offline-channels', this.settings.get('layout.side-nav.hide-offline')); this.toggleHide('side-offline-channels', this.settings.get('layout.side-nav.hide-offline'));
this.toggleHide('prime-offers', !this.settings.get('layout.prime-offers')); this.toggleHide('prime-offers', !this.settings.get('layout.prime-offers'));
this.toggleHide('top-discover', !this.settings.get('layout.discover')); this.toggleHide('top-discover', !this.settings.get('layout.discover'));

View file

@ -1,21 +1,24 @@
.twilight-main { order: 2 } .twilight-main { order: 2 }
#sideNav,
.side-nav { order: 3 } .side-nav { order: 3 }
.right-column { .right-column {
order: 1; order: 1;
z-index: 2; z-index: 2;
} }
.side-nav__toggle-visibility { #sideNav .collapse-toggle {
right: unset !important; svg {
left: -2.5rem; transform: rotate(180deg);
z-index: 10 !important; }
svg { transform: rotate(180deg) }
} }
.right-column__toggle-visibility { .right-column__toggle-visibility {
//left: unset !important; .tw-tooltip--left {
//right: -2.5rem; left: 100% !important;
//z-index: 10 !important; right: auto !important;
margin-left: 6px;
}
svg { transform: rotate(180deg) } svg { transform: rotate(180deg) }
.right-column--collapsed & { .right-column--collapsed & {
@ -24,14 +27,6 @@
} }
} }
.channel-header {
padding-left: 4rem !important;
.tw-sm-pd-r-4 {
padding-right: 1rem !important;
}
}
.side-nav__theme-wrapper.tw-border-r { .side-nav__theme-wrapper.tw-border-r {
border-right: none !important; border-right: none !important;

View file

@ -128,6 +128,9 @@ export class Tooltip {
cleanup() { cleanup() {
if ( this.options.manual )
return;
for(const el of this.elements) { for(const el of this.elements) {
const tip = el[this._accessor]; const tip = el[this._accessor];
if ( document.body.contains(el) ) if ( document.body.contains(el) )

View file

@ -62,6 +62,7 @@ body {
} }
} }
.ffz-action-balloon,
.ffz-metadata-balloon, .ffz-metadata-balloon,
.ffz__tooltip { .ffz__tooltip {
.loader { .loader {

View file

@ -375,6 +375,16 @@ textarea.tw-input {
} }
} }
.ffz-override-editor {
label {
min-width: 5rem;
}
.ffz--color-widget {
flex-grow: 1;
}
}
.ffz--report-upload { .ffz--report-upload {
z-index: 1; z-index: 1;
position: absolute; position: absolute;