1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-08-15 10:30:53 +00:00

Remove hard-coded styles from the directory. Make the directory up-time tool-tips nicer. Only update the up-time tool-tips when necessary. Add localization support to the game block/unblock and thumbnail hide/show buttons. Make the buttons appear like they did before. Refactor the code for the buttons to reduce code duplication.

This commit is contained in:
SirStendec 2017-12-01 16:22:45 -05:00
parent 60f86033e8
commit cbaf4b6878
5 changed files with 133 additions and 80 deletions

View file

@ -416,7 +416,7 @@ export default class Following extends SiteModule {
updateChannelCard(inst) { updateChannelCard(inst) {
if (!this.isRouteAcceptable()) return; if (!this.isRouteAcceptable()) return;
this.parent.updateUptime(inst, 'props.viewerCount.createdAt', '.tw-card .tw-aspect > div'); this.parent.updateUptime(inst, 'props.viewerCount.createdAt', '.tw-card .tw-aspect > div');
const container = this.fine.getHostNode(inst), const container = this.fine.getHostNode(inst),
@ -432,7 +432,7 @@ export default class Following extends SiteModule {
const ffzChannelData = card.querySelector('.ffz-channel-data'); const ffzChannelData = card.querySelector('.ffz-channel-data');
if (ffzChannelData !== null) ffzChannelData.remove(); if (ffzChannelData !== null) ffzChannelData.remove();
const channelAvatar = card.querySelector('.channel-avatar'); const channelAvatar = card.querySelector('.ffz-channel-avatar');
if (channelAvatar !== null) channelAvatar.remove(); if (channelAvatar !== null) channelAvatar.remove();
if (inst.props.viewerCount.profileImageURL) { if (inst.props.viewerCount.profileImageURL) {
@ -452,17 +452,15 @@ export default class Following extends SiteModule {
let avatarDiv; let avatarDiv;
if (avatarSetting === 1) { if (avatarSetting === 1) {
avatarDiv = e('a', { avatarDiv = e('a', {
className: 'channel-avatar', className: 'ffz-channel-avatar mg-r-05 mg-t-05',
href: hosting ? `/${channel}` : inst.props.linkTo.pathname, href: hosting ? `/${channel}` : inst.props.linkTo.pathname,
style: 'margin-right: 8px; min-width: 4rem; margin-top: 0.5rem;'
}, e('img', { }, e('img', {
title: inst.props.channelName, title: inst.props.channelName,
src: inst.props.viewerCount.profileImageURL, src: inst.props.viewerCount.profileImageURL
style: 'height: 4rem;'
})); }));
} else if (avatarSetting === 2 || avatarSetting === 3) { } else if (avatarSetting === 2 || avatarSetting === 3) {
const avatarElement = e('a', { const avatarElement = e('a', {
className: 'channel-avatar', className: 'ffz-channel-avatar',
href: hosting ? `/${channel}` : inst.props.linkTo.pathname, href: hosting ? `/${channel}` : inst.props.linkTo.pathname,
onclick: event => this.parent.hijackUserClick(event, inst.props.streamNode.broadcaster.login) onclick: event => this.parent.hijackUserClick(event, inst.props.streamNode.broadcaster.login)
}, e('div', 'live-channel-card__boxart bottom-0 absolute', }, e('div', 'live-channel-card__boxart bottom-0 absolute',
@ -476,7 +474,7 @@ export default class Following extends SiteModule {
); );
const divToAppend = card.querySelector('.tw-aspect > div'); const divToAppend = card.querySelector('.tw-aspect > div');
if (divToAppend.querySelector('.channel-avatar') === null) divToAppend.appendChild(avatarElement); if (divToAppend.querySelector('.ffz-channel-avatar') === null) divToAppend.appendChild(avatarElement);
} }
const cardDivParent = cardDiv.parentElement; const cardDivParent = cardDiv.parentElement;

View file

@ -14,6 +14,7 @@ export default class Game extends SiteModule {
this.inject('site.fine'); this.inject('site.fine');
this.inject('site.apollo'); this.inject('site.apollo');
this.inject('i18n');
this.inject('settings'); this.inject('settings');
this.GameHeader = this.fine.define( this.GameHeader = this.fine.define(
@ -49,72 +50,82 @@ export default class Game extends SiteModule {
} }
updateButtons(inst, update = false) { updateButtons(inst, update = false) {
if (inst.props.directoryType !== 'GAMES') return;
const container = this.fine.getHostNode(inst); const container = this.fine.getHostNode(inst);
// We can't get the buttons through querySelector('button ...') so this has to do for now... if ( inst.props.directoryType !== 'GAMES' || ! container || ! container.querySelector )
const buttons = container && container.querySelector && container.querySelector('div > div.align-items-center'); return;
const ffzButtons = buttons.querySelector('.ffz-buttons'); const buttons = container.querySelector('div > div.align-items-center'),
if (ffzButtons !== null && !update) return; ffz_buttons = buttons && buttons.querySelector('.ffz-buttons');
else if (ffzButtons) ffzButtons.remove();
if (buttons.querySelector('.ffz-buttons') === null) { if ( ! buttons || (ffz_buttons && ! update) )
// Block / Unblock Games return;
const blockedGames = this.settings.provider.get('directory.game.blocked-games') || [];
const gameBlocked = blockedGames.includes(inst.props.directoryName);
const blockButton = e('button', { if ( ffz_buttons )
className: 'mg-l-1 tw-button ffz-toggle-game-block', ffz_buttons.remove();
style: `background-color: ${gameBlocked ? '#228B22' : '#B22222'};`
}, e('span', {
className: 'tw-button__text',
textContent: `${gameBlocked ? 'Unblock' : 'Block'}`
})
);
blockButton.addEventListener('click', () => { // The Block / Unblock Button
const gameName = inst.props.directoryName; let block_btn, block_label,
const blockedGames = this.settings.provider.get('directory.game.blocked-games') || []; hidden_btn, hidden_label;
if (blockedGames.includes(gameName)) blockedGames.splice(blockedGames.indexOf(gameName), 1);
else blockedGames.push(gameName);
this.settings.provider.set('directory.game.blocked-games', blockedGames); const game = inst.props.directoryName,
update_block = () => {
const blocked_games = this.settings.provider.get('directory.game.blocked-games') || [],
blocked = blocked_games.includes(game);
this.updateButtons(inst, true); block_btn.classList.toggle('active', blocked);
}); block_label.textContent = blocked ?
this.i18n.t('directory.unblock', 'Unblock') :
this.i18n.t('directory.block', 'Block');
}
// Hide / Unhide Thumbnails
const hiddenThumbnails = this.settings.provider.get('directory.game.hidden-thumbnails') || [];
const thumbnailBlocked = hiddenThumbnails.includes(inst.props.directoryName);
const hideThumbnailButton = e('button', { block_btn = e('button', {
className: 'mg-l-1 tw-button ffz-toggle-thumbnail', className: 'mg-l-1 tw-button ffz-directory-toggle-block',
style: `background-color: ${thumbnailBlocked ? '#228B22' : '#B22222'};` onClick: this.generateClickHandler('directory.game.blocked-games', game, update_block)
}, e('span', { }, block_label = e('span', 'tw-button__text'));
className: 'tw-button__text',
textContent: `${thumbnailBlocked ? 'Unhide Thumbnails' : 'Hide Thumbnails'}`
})
);
hideThumbnailButton.addEventListener('click', () => { update_block();
const gameName = inst.props.directoryName;
const hiddenThumbnails = this.settings.provider.get('directory.game.hidden-thumbnails') || [];
if (hiddenThumbnails.includes(gameName)) hiddenThumbnails.splice(hiddenThumbnails.indexOf(gameName), 1);
else hiddenThumbnails.push(gameName);
this.settings.provider.set('directory.game.hidden-thumbnails', hiddenThumbnails);
this.parent.ChannelCard.forceUpdate(); const update_hidden = () => {
this.updateButtons(inst, true); const hidden_games = this.settings.provider.get('directory.game.hidden-thumbnails') || [],
}); hidden = hidden_games.includes(game);
const ffzButtons = e('div', 'ffz-buttons', [ hidden_btn.classList.toggle('active', hidden);
blockButton, hidden_label.textContent = hidden ?
hideThumbnailButton this.i18n.t('directory.show-thumbnails', 'Show Thumbnails') :
]); this.i18n.t('directory.hide-thumbnails', 'Hide Thumbnails');
buttons.appendChild(ffzButtons); this.parent.ChannelCard.forceUpdate();
}
hidden_btn = e('button', {
className: 'mg-l-1 tw-button ffz-directory-toggle-thumbnail',
onClick: this.generateClickHandler('directory.game.hidden-thumbnails', game, update_hidden)
}, hidden_label = e('span', 'tw-button__text'));
update_hidden();
buttons.appendChild(e('div', 'ffz-buttons', [
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);
update_func();
} }
} }
} }

View file

@ -24,6 +24,7 @@ export default class Directory extends SiteModule {
this.inject('site.apollo'); this.inject('site.apollo');
this.inject('site.css_tweaks'); this.inject('site.css_tweaks');
this.inject('i18n');
this.inject('settings'); this.inject('settings');
this.inject(Following); this.inject(Following);
@ -48,16 +49,16 @@ export default class Directory extends SiteModule {
onEnable() { onEnable() {
this.css_tweaks.toggleHide('profile-hover-game', this.settings.get('directory.following.show-channel-avatar') === 2); this.css_tweaks.toggleHide('profile-hover-game', this.settings.get('directory.following.show-channel-avatar') === 2);
this.ChannelCard.ready((cls, instances) => { this.ChannelCard.ready((cls, instances) => {
this.apollo.ensureQuery( this.apollo.ensureQuery(
'GamePage_Game', 'GamePage_Game',
'data.directory.streams.edges.0.node.createdAt' 'data.directory.streams.edges.0.node.createdAt'
); );
for(const inst of instances) this.updateChannelCard(inst); for(const inst of instances) this.updateChannelCard(inst);
}); });
this.ChannelCard.on('update', inst => this.updateChannelCard(inst), this); this.ChannelCard.on('update', inst => this.updateChannelCard(inst), this);
this.ChannelCard.on('mount', inst => this.updateChannelCard(inst), this); this.ChannelCard.on('mount', inst => this.updateChannelCard(inst), this);
this.ChannelCard.on('unmount', inst => this.clearUptime(inst), this); this.ChannelCard.on('unmount', inst => this.clearUptime(inst), this);
@ -74,11 +75,11 @@ export default class Directory extends SiteModule {
const type = inst.props.directoryType; const type = inst.props.directoryType;
const hiddenThumbnails = this.settings.provider.get('directory.game.hidden-thumbnails') || []; const hiddenThumbnails = this.settings.provider.get('directory.game.hidden-thumbnails') || [];
const hiddenPreview = 'https://static-cdn.jtvnw.net/ttv-static/404_preview-320x180.jpg'; const hiddenPreview = 'https://static-cdn.jtvnw.net/ttv-static/404_preview-320x180.jpg';
const container = this.fine.getHostNode(inst); const container = this.fine.getHostNode(inst);
const img = container && container.querySelector && container.querySelector(`${uptimeSel} img`); const img = container && container.querySelector && container.querySelector(`${uptimeSel} img`);
if (img === null) return; if (img === null) return;
if (type === 'GAMES' && hiddenThumbnails.includes(inst.props.directoryName) || if (type === 'GAMES' && hiddenThumbnails.includes(inst.props.directoryName) ||
type === 'COMMUNITIES' && hiddenThumbnails.includes(inst.props.streamNode.game.name)) { type === 'COMMUNITIES' && hiddenThumbnails.includes(inst.props.streamNode.game.name)) {
img.src = hiddenPreview; img.src = hiddenPreview;
@ -118,6 +119,7 @@ export default class Directory extends SiteModule {
inst.ffz_uptime_el = null; inst.ffz_uptime_el = null;
inst.ffz_uptime_span = null; inst.ffz_uptime_span = null;
inst.ffz_uptime_tt = null; inst.ffz_uptime_tt = null;
inst.ffz_last_created_at = null;
} }
} }
@ -135,7 +137,7 @@ export default class Directory extends SiteModule {
const up_text = duration_to_string(uptime, false, false, false, setting === 1); const up_text = duration_to_string(uptime, false, false, false, setting === 1);
if ( ! inst.ffz_uptime_el ) if ( ! inst.ffz_uptime_el ) {
card.appendChild(inst.ffz_uptime_el = e('div', card.appendChild(inst.ffz_uptime_el = e('div',
'video-preview-card__preview-overlay-stat c-background-overlay c-text-overlay font-size-6 top-0 right-0 z-default inline-flex absolute mg-05', 'video-preview-card__preview-overlay-stat c-background-overlay c-text-overlay font-size-6 top-0 right-0 z-default inline-flex absolute mg-05',
e('div', 'tw-tooltip-wrapper inline-flex', [ e('div', 'tw-tooltip-wrapper inline-flex', [
@ -145,13 +147,25 @@ export default class Directory extends SiteModule {
]), ]),
inst.ffz_uptime_tt = e('div', 'tw-tooltip tw-tooltip--down tw-tooltip--align-center') inst.ffz_uptime_tt = e('div', 'tw-tooltip tw-tooltip--down tw-tooltip--align-center')
]))); ])));
}
if ( ! inst.ffz_update_timer ) if ( ! inst.ffz_update_timer )
inst.ffz_update_timer = setInterval(this.updateUptime.bind(this, inst, created_path, selector), 1000); inst.ffz_update_timer = setInterval(this.updateUptime.bind(this, inst, created_path, selector), 1000);
inst.ffz_uptime_span.textContent = up_text; inst.ffz_uptime_span.textContent = up_text;
inst.ffz_uptime_tt.textContent = up_since.toLocaleString();
if ( inst.ffz_last_created_at !== created_at ) {
inst.ffz_uptime_tt.innerHTML = `${this.i18n.t(
'metadata.uptime.tooltip',
'Stream Uptime'
)}<div class="pd-t-05">${this.i18n.t(
'metadata.uptime.since',
'(since %{since})',
{since: up_since.toLocaleString()}
)}</div>`;
inst.ffz_last_created_at = created_at;
}
} }
@ -162,14 +176,17 @@ export default class Directory extends SiteModule {
// Remove old elements // Remove old elements
const hiddenBodyCard = card.querySelector('.tw-card-body.hide'); const hiddenBodyCard = card.querySelector('.tw-card-body.hide');
if (hiddenBodyCard !== null) hiddenBodyCard.classList.remove('hide'); if (hiddenBodyCard !== null)
hiddenBodyCard.classList.remove('hide');
const ffzChannelData = card.querySelector('.ffz-channel-data'); const ffzChannelData = card.querySelector('.ffz-channel-data');
if (ffzChannelData !== null) ffzChannelData.remove(); if (ffzChannelData !== null)
ffzChannelData.remove();
const channelAvatar = card.querySelector('.ffz-channel-avatar');
if (channelAvatar !== null)
channelAvatar.remove();
const channelAvatar = card.querySelector('.channel-avatar');
if (channelAvatar !== null) channelAvatar.remove();
if ( ! card || setting === 0 ) if ( ! card || setting === 0 )
return; return;
@ -181,14 +198,12 @@ export default class Directory extends SiteModule {
}); });
const avatarDiv = e('a', { const avatarDiv = e('a', {
className: 'channel-avatar', className: 'ffz-channel-avatar mg-r-05 mg-t-05',
href: `/${inst.props.streamNode.broadcaster.login}`, href: `/${inst.props.streamNode.broadcaster.login}`,
style: 'margin-right: 8px; min-width: 4rem; margin-top: 0.5rem;',
onclick: event => this.hijackUserClick(event, inst.props.streamNode.broadcaster.login) onclick: event => this.hijackUserClick(event, inst.props.streamNode.broadcaster.login)
}, e('img', { }, e('img', {
title: inst.props.streamNode.broadcaster.displayName, title: inst.props.streamNode.broadcaster.displayName,
src: inst.props.streamNode.viewersCount.profileImageURL, src: inst.props.streamNode.viewersCount.profileImageURL
style: 'height: 4rem;'
})); }));
const cardDivParent = cardDiv.parentElement; const cardDivParent = cardDiv.parentElement;
@ -203,7 +218,7 @@ export default class Directory extends SiteModule {
} }
} else if (setting === 2 || setting === 3) { } else if (setting === 2 || setting === 3) {
const avatarElement = e('a', { const avatarElement = e('a', {
className: 'channel-avatar', className: 'ffz-channel-avatar',
href: `/${inst.props.streamNode.broadcaster.login}`, href: `/${inst.props.streamNode.broadcaster.login}`,
onclick: event => this.hijackUserClick(event, inst.props.streamNode.broadcaster.login) onclick: event => this.hijackUserClick(event, inst.props.streamNode.broadcaster.login)
}, e('div', 'live-channel-card__boxart bottom-0 absolute', }, e('div', 'live-channel-card__boxart bottom-0 absolute',
@ -213,11 +228,11 @@ export default class Directory extends SiteModule {
src: inst.props.streamNode.viewersCount.profileImageURL src: inst.props.streamNode.viewersCount.profileImageURL
}) })
) )
) ));
);
const divToAppend = card.querySelector('figure.tw-aspect'); const divToAppend = card.querySelector('figure.tw-aspect');
if (divToAppend.querySelector('.channel-avatar') === null) divToAppend.appendChild(avatarElement); if (divToAppend.querySelector('.ffz-channel-avatar') === null)
divToAppend.appendChild(avatarElement);
} }
} }
} }

View file

@ -0,0 +1,27 @@
.ffz-channel-avatar {
flex-shrink: 0 !important;
width: 4rem;
img {
width: 4rem;
height: 4rem
}
}
// TODO: Color variables
.ffz-directory-toggle-thumbnail {
background: #555 !important;
&:hover { background: #247324 !important }
&.active { background: #006700 !important }
}
.ffz-directory-toggle-block {
background: #555 !important;
&:hover { background: #a94444 !important }
&.active { background: #973333 !important }
}

View file

@ -6,4 +6,6 @@
@import 'channel'; @import 'channel';
@import 'chat'; @import 'chat';
@import 'directory';
@import 'fixes'; @import 'fixes';