diff --git a/src/main.js b/src/main.js
index af225732..239c7f62 100644
--- a/src/main.js
+++ b/src/main.js
@@ -100,7 +100,7 @@ class FrankerFaceZ extends Module {
FrankerFaceZ.Logger = Logger;
const VER = FrankerFaceZ.version_info = {
- major: 4, minor: 0, revision: 0, extra: '-rc12.23',
+ major: 4, minor: 0, revision: 0, extra: '-rc13',
commit: __git_commit__,
build: __webpack_hash__,
toString: () =>
diff --git a/src/modules/chat/index.js b/src/modules/chat/index.js
index b3b4df37..33d9f962 100644
--- a/src/modules/chat/index.js
+++ b/src/modules/chat/index.js
@@ -522,22 +522,27 @@ export default class Chat extends Module {
}
});
+ const ts = new Date(0).toLocaleTimeString().toUpperCase(),
+ default_24 = ts.lastIndexOf('PM') === -1 && ts.lastIndexOf('AM') === -1;
+
this.settings.add('chat.timestamp-format', {
- default: 'H:mm',
+ default: default_24 ? 'H:mm' : 'h:mm',
ui: {
path: 'Chat > Appearance >> Chat Lines',
title: 'Timestamp Format',
- component: 'setting-select-box',
+ component: 'setting-combo-box',
+
+ description: 'Timestamps are formatted using the [Day.js](https://github.com/iamkun/dayjs#readme) library. More details about formatting strings [can be found here](https://github.com/iamkun/dayjs/blob/HEAD/docs/en/API-reference.md#list-of-all-available-formats)',
data: [
- {value: 'h:mm', title: 'Default (h:mm)'},
- {value: 'h:mm:ss', title: 'Default with Seconds (h:mm:ss)'},
- {value: 'H:mm', title: '24 Hour (H:mm)'},
- {value: 'H:mm:ss', title: '24 Hour with Seconds (H:mm:ss)'},
- {value: 'hh:mm', title: 'Padded (hh:mm)'},
- {value: 'hh:mm:ss', title: 'Padded with Seconds (hh:mm:ss)'},
- {value: 'HH:mm', title: 'Padded 24 Hour (HH:mm)'},
- {value: 'HH:mm:ss', title: 'Padded 24 Hour with Seconds (HH:mm:ss)'},
+ {value: 'h:mm', title: '12 Hour'},
+ {value: 'h:mm:ss', title: '12 Hour with Seconds'},
+ {value: 'H:mm', title: '24 Hour'},
+ {value: 'H:mm:ss', title: '24 Hour with Seconds'},
+ {value: 'hh:mm', title: 'Padded'},
+ {value: 'hh:mm:ss', title: 'Padded with Seconds'},
+ {value: 'HH:mm', title: 'Padded 24 Hour'},
+ {value: 'HH:mm:ss', title: 'Padded 24 Hour with Seconds'},
]
}
});
@@ -939,9 +944,8 @@ export default class Chat extends Module {
if (!( time instanceof Date ))
time = new Date(time);
- const fmt = this.settings.get('chat.timestamp-format');
-
- return dayjs(time).format(fmt);
+ const fmt = this.context.get('chat.timestamp-format');
+ return dayjs(time).locale(this.i18n.locale).format(fmt);
}
diff --git a/src/modules/chat/tokenizers.jsx b/src/modules/chat/tokenizers.jsx
index 50342e09..d00adae0 100644
--- a/src/modules/chat/tokenizers.jsx
+++ b/src/modules/chat/tokenizers.jsx
@@ -78,9 +78,13 @@ export const Links = {
content = ` ${content}`
setTimeout(() => {
- if ( tip.element )
- for(const el of tip.element.querySelectorAll('video,img'))
- el.addEventListener('load', tip.update)
+ if ( tip.element ) {
+ for(const el of tip.element.querySelectorAll('img'))
+ el.addEventListener('load', tip.update);
+
+ for(const el of tip.element.querySelectorAll('video'))
+ el.addEventListener('loadedmetadata', tip.update);
+ }
});
} else if ( content.length )
diff --git a/src/modules/main_menu/components/menu-page.vue b/src/modules/main_menu/components/menu-page.vue
index d973a0de..37856d59 100644
--- a/src/modules/main_menu/components/menu-page.vue
+++ b/src/modules/main_menu/components/menu-page.vue
@@ -33,8 +33,9 @@
+ >
+
+
diff --git a/src/modules/main_menu/components/setting-hotkey.vue b/src/modules/main_menu/components/setting-hotkey.vue
index 2cd5ab5a..e4ed99fa 100644
--- a/src/modules/main_menu/components/setting-hotkey.vue
+++ b/src/modules/main_menu/components/setting-hotkey.vue
@@ -23,8 +23,10 @@
+ class="tw-c-text-alt-2"
+ >
+
+
diff --git a/src/modules/main_menu/components/setting-radio-buttons.vue b/src/modules/main_menu/components/setting-radio-buttons.vue
index fc6e8393..d7559024 100644
--- a/src/modules/main_menu/components/setting-radio-buttons.vue
+++ b/src/modules/main_menu/components/setting-radio-buttons.vue
@@ -6,8 +6,9 @@
+ >
+
+
+ >
+
+
diff --git a/src/modules/main_menu/components/setting-text-box.vue b/src/modules/main_menu/components/setting-text-box.vue
index badd1708..3d40ae39 100644
--- a/src/modules/main_menu/components/setting-text-box.vue
+++ b/src/modules/main_menu/components/setting-text-box.vue
@@ -12,7 +12,7 @@
ref="control"
:id="item.full_key"
:value="value"
- class="tw-border-radius-medium tw-font-size-6 tw-input tw-pd-x-1 tw-pd-y-05 tw-mg-05 tw-input"
+ class="tw-border-radius-medium tw-font-size-6 tw-pd-x-1 tw-pd-y-05 tw-mg-05 tw-input"
@change="onChange"
>
@@ -37,8 +37,9 @@
+ >
+
+
diff --git a/src/modules/metadata.jsx b/src/modules/metadata.jsx
index a6ded93e..a928df7d 100644
--- a/src/modules/metadata.jsx
+++ b/src/modules/metadata.jsx
@@ -256,11 +256,11 @@ export default class Metadata extends Module {
legacy_bar.updateMetadata(inst, keys);
}
- const game_header = this.resolve('site.directory.game');
+ /*const game_header = this.resolve('site.directory.game');
if ( game_header ) {
for(const inst of game_header.GameHeader.instances)
game_header.updateMetadata(inst, keys);
- }
+ }*/
}
diff --git a/src/sites/twitch-twilight/modules/chat/line.js b/src/sites/twitch-twilight/modules/chat/line.js
index 41a9fa01..4b01ba06 100644
--- a/src/sites/twitch-twilight/modules/chat/line.js
+++ b/src/sites/twitch-twilight/modules/chat/line.js
@@ -61,6 +61,7 @@ export default class ChatLine extends Module {
this.chat.context.on('changed:chat.actions.inline', this.updateLines, this);
this.chat.context.on('changed:chat.filtering.show-deleted', this.updateLines, this);
this.chat.context.on('changed:chat.filtering.process-own', this.updateLines, this);
+ this.chat.context.on('changed:chat.timestamp-format', this.updateLines, this);
this.chat.context.on('changed:chat.filtering.highlight-basic-terms--color-regex', this.updateLines, this);
this.chat.context.on('changed:chat.filtering.highlight-basic-blocked--regex', this.updateLines, this);
diff --git a/src/sites/twitch-twilight/modules/directory/game.jsx b/src/sites/twitch-twilight/modules/directory/game.jsx
index d84cca33..50fa8d7d 100644
--- a/src/sites/twitch-twilight/modules/directory/game.jsx
+++ b/src/sites/twitch-twilight/modules/directory/game.jsx
@@ -6,6 +6,7 @@
import {SiteModule} from 'utilities/module';
import {createElement} from 'utilities/dom';
+import { get } from 'utilities/object';
import GAME_QUERY from './game.gql';
@@ -16,11 +17,11 @@ export default class Game extends SiteModule {
this.inject('site.fine');
this.inject('site.apollo');
- this.inject('metadata');
+ //this.inject('metadata');
this.inject('i18n');
this.inject('settings');
- this.metadata.definitions.block_game = {
+ /*this.metadata.definitions.block_game = {
type: 'directory',
button(data) {
return `ffz-directory-toggle-block${data.blocked ? ' active' : ''}`
@@ -83,17 +84,11 @@ export default class Game extends SiteModule {
},
click: this.generateClickHandler('directory.game.hidden-thumbnails')
- }
-
- this.LegacyGameHeader = this.fine.define(
- 'legacy-game-header',
- n => n.renderFollowButton && n.renderGameDetailsTab,
- ['dir-game-index', 'dir-community']
- );
+ }*/
this.GameHeader = this.fine.define(
'game-header',
- n => n.renderDirectoryMetadata,
+ n => n.props && n.props.data && n.renderDropsAvailable,
['dir-game-index', 'dir-community', 'dir-game-videos', 'dir-game-clips', 'dir-game-details']
);
@@ -101,27 +96,99 @@ export default class Game extends SiteModule {
}
onEnable() {
- this.GameHeader.on('unmount', this.unmountGameHeader, this);
this.GameHeader.on('mount', this.updateGameHeader, this);
this.GameHeader.on('update', this.updateGameHeader, this);
this.GameHeader.ready((cls, instances) => {
- this.settings.updateContext({new_channel: true});
-
for(const inst of instances)
this.updateGameHeader(inst);
});
-
- this.LegacyGameHeader.ready((cls, instances) => {
- for(const inst of instances)
- this.updateButtons(inst);
- });
-
- this.LegacyGameHeader.on('update', this.updateButtons, this);
}
- unmountGameHeader(inst) { // eslint-disable-line class-methods-use-this
+ updateGameHeader(inst) {
+ this.updateButtons(inst);
+ }
+
+
+ updateButtons(inst) {
+ const container = this.fine.getChildNode(inst);
+ if ( get('data.variables.type', inst.props) !== 'GAME' || ! container || ! container.querySelector )
+ return;
+
+ const buttons = container.querySelector('.tw-flex > .tw-inline-flex');
+ if ( ! buttons )
+ return;
+
+ const ffz_buttons = buttons.querySelector('.ffz-buttons');
+ if ( ffz_buttons )
+ ffz_buttons.remove();
+
+ let block_btn, block_label,
+ hidden_btn, hidden_label;
+
+ const game = get('data.directory.name', inst.props),
+ update_block = () => {
+ const blocked_games = this.settings.provider.get('directory.game.blocked-games', []),
+ blocked = blocked_games.includes(game);
+
+ block_btn.classList.toggle('active', blocked);
+ block_label.textContent = blocked ?
+ this.i18n.t('directory.unblock', 'Unblock') :
+ this.i18n.t('directory.block', 'Block');
+ },
+ update_hidden = () => {
+ const hidden_games = this.settings.provider.get('directory.game.hidden-thumbnails', []),
+ hidden = hidden_games.includes(game);
+
+ hidden_btn.classList.toggle('active', hidden);
+ hidden_label.textContent = hidden ?
+ this.i18n.t('directory.show-thumbnails', 'Show Thumbnails') :
+ this.i18n.t('directory.hide-thumbnails', 'Hide Thumbnails');
+ };
+
+ block_btn = (
+ {block_label = }
+ );
+
+ update_block();
+
+ hidden_btn = (
+ {hidden_label = }
+ );
+
+ update_hidden();
+
+ buttons.appendChild(
+ {block_btn}
+ {hidden_btn}
+
);
+ }
+
+ generateClickHandler(setting, game, update_func) {
+ return e => {
+ e.preventDefault();
+ const values = this.settings.provider.get(setting) || [],
+ idx = values.indexOf(game);
+
+ if ( idx === -1 )
+ values.push(game);
+ else
+ values.splice(idx, 1);
+
+ this.settings.provider.set(setting, values);
+ this.parent.DirectoryCard.forceUpdate();
+ update_func();
+ }
+ }
+
+ /*unmountGameHeader(inst) { // eslint-disable-line class-methods-use-this
const timers = inst._ffz_meta_timers;
if ( timers )
for(const key in timers)
@@ -134,7 +201,6 @@ export default class Game extends SiteModule {
this.updateMetadata(inst);
}
-
updateMetadata(inst, keys) {
const container = this.fine.getChildNode(inst),
wrapper = container && container.querySelector && container.querySelector('.side-nav-directory-info__info-wrapper > div + div');
@@ -164,90 +230,6 @@ export default class Game extends SiteModule {
this.metadata.render(key, data, metabar, timers, refresh_func);
}
-
- updateButtons(inst, update = false) {
- const container = this.fine.getChildNode(inst);
- if ( inst.props.directoryType !== 'GAMES' || ! container || ! container.querySelector )
- return;
-
- const buttons = container.querySelector('div > div.tw-align-items-center'),
- ffz_buttons = buttons && buttons.querySelector('.ffz-buttons');
-
- if ( ! buttons || (ffz_buttons && ! update) )
- return;
-
- if ( ffz_buttons )
- ffz_buttons.remove();
-
- // The Block / Unblock Button
- let block_btn, block_label,
- hidden_btn, hidden_label;
-
- const game = inst.props.directoryName,
- update_block = () => {
- const blocked_games = this.settings.provider.get('directory.game.blocked-games') || [],
- blocked = blocked_games.includes(game);
-
- block_btn.classList.toggle('active', blocked);
- block_label.textContent = blocked ?
- this.i18n.t('directory.unblock', 'Unblock') :
- this.i18n.t('directory.block', 'Block');
- }
-
-
- block_btn = (
- {block_label = }
- );
-
- update_block();
-
-
- const update_hidden = () => {
- const hidden_games = this.settings.provider.get('directory.game.hidden-thumbnails') || [],
- hidden = hidden_games.includes(game);
-
- hidden_btn.classList.toggle('active', hidden);
- hidden_label.textContent = hidden ?
- this.i18n.t('directory.show-thumbnails', 'Show Thumbnails') :
- this.i18n.t('directory.hide-thumbnails', 'Hide Thumbnails');
-
- this.parent.DirectoryCard.forceUpdate();
- }
-
- hidden_btn = (
- {hidden_label = }
- )
-
- update_hidden();
-
- buttons.appendChild(
- {block_btn}
- {hidden_btn}
-
);
- }
-
- generateLegacyClickHandler(setting, game, update_func) {
- return e => {
- e.preventDefault();
- const values = this.settings.provider.get(setting) || [],
- idx = values.indexOf(game);
-
- if ( idx === -1 )
- values.push(game);
- else
- values.splice(idx, 1);
-
- this.settings.provider.set(setting, values);
- update_func();
- }
- }
-
generateClickHandler(setting) {
return (data, event, update_func) => {
const values = this.settings.provider.get(setting, []),
@@ -263,5 +245,5 @@ export default class Game extends SiteModule {
this.parent.DirectoryCard.forceUpdate();
update_func();
}
- }
+ }*/
}
\ No newline at end of file
diff --git a/src/sites/twitch-twilight/modules/player.jsx b/src/sites/twitch-twilight/modules/player.jsx
index d4ca5cb4..aa089005 100644
--- a/src/sites/twitch-twilight/modules/player.jsx
+++ b/src/sites/twitch-twilight/modules/player.jsx
@@ -39,7 +39,7 @@ export default class Player extends Module {
ui: {
path: 'Channel > Player >> Volume',
title: 'Adjust volume by scrolling with the mouse wheel.',
- description: 'This setting will not work properly on streams with visible extensions when mouse interaction with extensions is allowed. ',
+ description: '*This setting will not work properly on streams with visible extensions when mouse interaction with extensions is allowed.*',
component: 'setting-check-box'
},
diff --git a/src/sites/twitch-twilight/modules/theme/index.js b/src/sites/twitch-twilight/modules/theme/index.js
index a9dfd2a3..6057f2a4 100644
--- a/src/sites/twitch-twilight/modules/theme/index.js
+++ b/src/sites/twitch-twilight/modules/theme/index.js
@@ -33,7 +33,11 @@ export default class ThemeEngine extends Module {
ui: {
path: 'Appearance @{"description": "Personalize the appearance of Twitch. Change the color scheme and fonts and tune the layout to optimize your experience."} > Theme >> General',
title: 'Gray (no Purple)',
- description: 'Requires Dark Theme to be Enabled. I see my website and I want it painted black... This is a very early feature and will change as there is time.',
+ description: `*Requires Dark Theme to be Enabled.*
+
+I see my website and I want it painted black...
+
+This is a very early feature and will change as there is time.`,
component: 'setting-check-box'
},