diff --git a/src/sites/twitch-twilight/modules/directory/community.js b/src/sites/twitch-twilight/modules/directory/community.js index 544dc566..33d7f816 100644 --- a/src/sites/twitch-twilight/modules/directory/community.js +++ b/src/sites/twitch-twilight/modules/directory/community.js @@ -64,7 +64,7 @@ export default class Community extends SiteModule { for (let i = 0; i < edges.length; i++) { const edge = edges[i]; const node = edge.node; - + const s = node.viewersCount = new Number(node.viewersCount || 0); s.profileImageURL = node.broadcaster.profileImageURL; s.createdAt = node.createdAt; @@ -135,7 +135,7 @@ export default class Community extends SiteModule { const up_since = new Date(inst.props.streamNode.viewersCount.createdAt); const uptime = up_since && Math.floor((Date.now() - up_since) / 1000) || 0; const uptimeText = duration_to_string(uptime, false, false, false, this.settings.get('directory.following.uptime') === 1); - + if (uptime > 0) { if (inst.uptimeElement === undefined) { inst.uptimeElementSpan = e('span', 'tw-stat__value ffz-uptime', `${uptimeText}`); @@ -148,7 +148,7 @@ export default class Community extends SiteModule { ), inst.uptimeElementSpan ]); - + if (card.querySelector('.ffz-uptime') === null) card.appendChild(inst.uptimeElement); } else { inst.uptimeElementSpan.textContent = `${uptimeText}`; @@ -166,11 +166,11 @@ export default class Community extends SiteModule { if (container === null || card === null) return; if (!inst.props.streamNode.viewersCount.createdAt) return; - + // Remove old elements const hiddenBodyCard = card.querySelector('.tw-card-body.hide'); if (hiddenBodyCard !== null) hiddenBodyCard.classList.remove('hide'); - + const ffzChannelData = card.querySelector('.ffz-channel-data'); if (ffzChannelData !== null) ffzChannelData.remove(); @@ -192,7 +192,7 @@ export default class Community extends SiteModule { onclick: event => { event.preventDefault(); event.stopPropagation(); - + this.router.navigate('user', { userName: inst.props.streamNode.broadcaster.login}); } }, e('img', { @@ -202,7 +202,7 @@ export default class Community extends SiteModule { })); const cardDivParent = cardDiv.parentElement; - + if (cardDivParent.querySelector('.ffz-channel-data') === null) { cardDiv.classList.add('hide'); @@ -218,7 +218,7 @@ export default class Community extends SiteModule { onclick: event => { event.preventDefault(); event.stopPropagation(); - + this.router.navigate('user', { userName: inst.props.streamNode.broadcaster.login}); } }, e('div', 'live-channel-card__boxart bottom-0 absolute', @@ -241,10 +241,10 @@ export default class Community extends SiteModule { const container = this.fine.getHostNode(inst); // We can't get the buttons through querySelector('button ...') so this has to do for now... const buttons = container && container.querySelector && container.querySelector('div > div.align-items-center'); - + const ffzButtons = buttons.querySelector('.ffz-buttons'); if (ffzButtons !== null) ffzButtons.remove(); - + if (buttons.querySelector('.ffz-buttons') === null) { // Block / Unblock Games const blockedGames = this.settings.provider.get('directory.game.blocked-games') || []; diff --git a/src/sites/twitch-twilight/modules/directory/following.js b/src/sites/twitch-twilight/modules/directory/following.js index f9c026e4..536573c1 100644 --- a/src/sites/twitch-twilight/modules/directory/following.js +++ b/src/sites/twitch-twilight/modules/directory/following.js @@ -160,7 +160,7 @@ export default class Following extends SiteModule { } } }`); - + this.apollo.registerModifier('FollowingHosts_CurrentUser', `query { currentUser { followedHosts { @@ -223,7 +223,7 @@ export default class Following extends SiteModule { modifyLiveHosts(res) { // eslint-disable-line class-methods-use-this if (!this.isRouteAcceptable()) return res; - + const hiddenThumbnails = this.settings.provider.get('directory.game.hidden-thumbnails') || []; const blockedGames = this.settings.provider.get('directory.game.blocked-games') || []; @@ -295,8 +295,7 @@ export default class Following extends SiteModule { }); this.ChannelCard.on('mount', inst => this.updateChannelCard(inst), this); - - this.ChannelCard.on('unmount', inst => this.updateUptime(inst), this); + this.ChannelCard.on('unmount', inst => this.parent.clearUptime(inst), this); document.body.addEventListener('click', this.destroyHostMenu.bind(this)); } @@ -309,61 +308,6 @@ export default class Following extends SiteModule { } } - updateUptime(inst) { - const container = this.fine.getHostNode(inst); - const card = container && container.querySelector && container.querySelector('.tw-card .tw-aspect > div'); - - // if (container === null || card === null) { - // if (inst.updateTimer !== undefined) { - // clearInterval(inst.updateTimer); - // inst.updateTimer = undefined; - // return; - // } - // } - - if (this.settings.get('directory.following.uptime') === 0) { - if (inst.updateTimer !== undefined) { - clearInterval(inst.updateTimer); - inst.updateTimer = undefined; - } - - if (inst.uptimeElement !== undefined) { - inst.uptimeElement.remove(); - inst.uptimeElementSpan = inst.uptimeElement = undefined; - } - } else { - if (inst.updateTimer === undefined) { - inst.updateTimer = setInterval( - this.updateUptime.bind(this, inst), - 1000 - ); - } - - const up_since = new Date(inst.props.viewerCount.createdAt); - const uptime = up_since && Math.floor((Date.now() - up_since) / 1000) || 0; - const uptimeText = duration_to_string(uptime, false, false, false, this.settings.get('directory.following.uptime') === 1); - - if (uptime > 0) { - if (inst.uptimeElement === undefined) { - inst.uptimeElementSpan = e('span', 'tw-stat__value ffz-uptime', `${uptimeText}`); - inst.uptimeElement = e('div', { - className: 'c-background-overlay c-text-overlay font-size-6 top-0 right-0 z-default inline-flex absolute mg-05', - style: 'padding-left: 4px; padding-right: 4px;' - }, [ - e('span', 'tw-stat__icon', - e('figure', 'ffz-i-clock') - ), - inst.uptimeElementSpan - ]); - - if (card.querySelector('.ffz-uptime') === null) card.appendChild(inst.uptimeElement); - } else { - inst.uptimeElementSpan.textContent = `${uptimeText}`; - } - } - } - } - showHostMenu(inst, { channels }, event) { if (this.settings.get('directory.following.host-menus') === 0 || this.settings.get('directory.following.host-menus') === 1 && channels.length < 2) return; @@ -393,7 +337,7 @@ export default class Following extends SiteModule { onclick: event => { event.preventDefault(); event.stopPropagation(); - + this.router.navigate('user', { userName: inst.props.linkTo.pathname.substring(1)}); } }, e('div', 'align-items-center flex flex-row flex-nowrap mg-x-1 mg-y-05', @@ -483,27 +427,29 @@ export default class Following extends SiteModule { } updateChannelCard(inst) { - this.updateUptime(inst); + this.parent.updateUptime(inst, 'props.viewerCount.createdAt', '.tw-card .tw-aspect > div'); - const container = this.fine.getHostNode(inst); - const card = container && container.querySelector && container.querySelector('.tw-card'); - - if (container === null || card === null) return; + const container = this.fine.getHostNode(inst), + card = container && container.querySelector && container.querySelector('.tw-card'); + + if ( container === null || card === null ) + return; const channelCardTitle = card.querySelector('.live-channel-card__title'); - if (channelCardTitle === null) return; - + if ( channelCardTitle === null ) + return; + // Remove old elements const hiddenBodyCard = card.querySelector('.tw-card-body.hide'); if (hiddenBodyCard !== null) hiddenBodyCard.classList.remove('hide'); - + const ffzChannelData = card.querySelector('.ffz-channel-data'); if (ffzChannelData !== null) ffzChannelData.remove(); - + const channelAvatar = card.querySelector('.channel-avatar'); if (channelAvatar !== null) channelAvatar.remove(); - + if (inst.props.viewerCount.profileImageURL) { const hosting = inst.props.viewerCount.hostData; let channel, displayName; @@ -511,13 +457,13 @@ export default class Following extends SiteModule { channel = inst.props.viewerCount.hostData.channel; displayName = inst.props.viewerCount.hostData.displayName; } - + const avatarSetting = this.settings.get('directory.following.show-channel-avatar'); const cardDiv = card.querySelector('.tw-card-body'); const modifiedDiv = e('div', { innerHTML: cardDiv.innerHTML }); - + let avatarDiv; if (avatarSetting === 1) { avatarDiv = e('a', { @@ -536,7 +482,7 @@ export default class Following extends SiteModule { onclick: event => { event.preventDefault(); event.stopPropagation(); - + this.router.navigate('user', { userName: inst.props.streamNode.broadcaster.login}); } }, e('div', 'live-channel-card__boxart bottom-0 absolute', @@ -569,16 +515,16 @@ export default class Following extends SiteModule { if (this.settings.get('directory.following.group-hosts')) { const titleLink = card.querySelector('.ffz-channel-data a[data-a-target="live-channel-card-title-link"]'); const thumbnailLink = card.querySelector('a[data-a-target="live-channel-card-thumbnail-link"]'); - + if (hostObj.channels.length > 1) { const textContent = `${hostObj.channels.length} hosting ${displayName}`; channelCardTitle.textContent = channelCardTitle.title = textContent; - + if (thumbnailLink !== null) thumbnailLink.title = textContent; } - + if (titleLink !== null) titleLink.onclick = this.showHostMenu.bind(this, inst, hostObj); if (thumbnailLink !== null) thumbnailLink.onclick = this.showHostMenu.bind(this, inst, hostObj); } diff --git a/src/sites/twitch-twilight/modules/directory/game.js b/src/sites/twitch-twilight/modules/directory/game.js index ebfc3d02..d9f3211f 100644 --- a/src/sites/twitch-twilight/modules/directory/game.js +++ b/src/sites/twitch-twilight/modules/directory/game.js @@ -67,7 +67,7 @@ export default class Game extends SiteModule { for (let i = 0; i < edges.length; i++) { const edge = edges[i]; const node = edge.node; - + const s = node.viewersCount = new Number(node.viewersCount || 0); s.profileImageURL = node.broadcaster.profileImageURL; s.createdAt = node.createdAt; @@ -140,7 +140,7 @@ export default class Game extends SiteModule { const up_since = new Date(inst.props.streamNode.viewersCount.createdAt); const uptime = up_since && Math.floor((Date.now() - up_since) / 1000) || 0; const uptimeText = duration_to_string(uptime, false, false, false, this.settings.get('directory.following.uptime') === 1); - + if (uptime > 0) { if (inst.uptimeElement === undefined) { inst.uptimeElementSpan = e('span', 'tw-stat__value ffz-uptime', `${uptimeText}`); @@ -153,7 +153,7 @@ export default class Game extends SiteModule { ), inst.uptimeElementSpan ]); - + if (card.querySelector('.ffz-uptime') === null) card.appendChild(inst.uptimeElement); } else { inst.uptimeElementSpan.textContent = `${uptimeText}`; @@ -167,15 +167,15 @@ export default class Game extends SiteModule { const container = this.fine.getHostNode(inst); const card = container && container.querySelector && container.querySelector('.tw-thumbnail-card'); - + if (container === null || card === null) return; if (!inst.props.streamNode.viewersCount.createdAt || container === null || card === null) return; - + // Remove old elements const hiddenBodyCard = card.querySelector('.tw-card-body.hide'); if (hiddenBodyCard !== null) hiddenBodyCard.classList.remove('hide'); - + const ffzChannelData = card.querySelector('.ffz-channel-data'); if (ffzChannelData !== null) ffzChannelData.remove(); @@ -184,14 +184,13 @@ export default class Game extends SiteModule { const hiddenThumbnails = this.settings.provider.get('directory.game.hidden-thumbnails') || []; const thumbnailBlocked = hiddenThumbnails.includes(inst.props.directoryName); - this.log.warn(inst); if (thumbnailBlocked) { card.classList.add('ffz-thumbnail-hidden'); } else { card.classList.remove('ffz-thumbnail-hidden'); } - + if (inst.props.streamNode.viewersCount.profileImageURL) { const avatarSetting = this.settings.get('directory.following.show-channel-avatar'); if (avatarSetting === 1) { @@ -207,7 +206,7 @@ export default class Game extends SiteModule { onclick: event => { event.preventDefault(); event.stopPropagation(); - + this.router.navigate('user', { userName: inst.props.streamNode.broadcaster.login}); } }, e('img', { @@ -217,7 +216,7 @@ export default class Game extends SiteModule { })); const cardDivParent = cardDiv.parentElement; - + if (cardDivParent.querySelector('.ffz-channel-data') === null) { cardDiv.classList.add('hide'); @@ -233,7 +232,7 @@ export default class Game extends SiteModule { onclick: event => { event.preventDefault(); event.stopPropagation(); - + this.router.navigate('user', { userName: inst.props.streamNode.broadcaster.login}); } }, e('div', 'live-channel-card__boxart bottom-0 absolute', @@ -256,10 +255,10 @@ export default class Game extends SiteModule { const container = this.fine.getHostNode(inst); // We can't get the buttons through querySelector('button ...') so this has to do for now... const buttons = container && container.querySelector && container.querySelector('div > div.align-items-center'); - + const ffzButtons = buttons.querySelector('.ffz-buttons'); if (ffzButtons !== null) ffzButtons.remove(); - + if (buttons.querySelector('.ffz-buttons') === null) { // Block / Unblock Games const blockedGames = this.settings.provider.get('directory.game.blocked-games') || []; diff --git a/src/sites/twitch-twilight/modules/directory/index.js b/src/sites/twitch-twilight/modules/directory/index.js deleted file mode 100644 index 428da086..00000000 --- a/src/sites/twitch-twilight/modules/directory/index.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; - -// ============================================================================ -// Directory -// ============================================================================ - -import {SiteModule} from 'utilities/module'; - -import Following from './following'; -import Game from './game'; -import Community from './community'; - -export default class Directory extends SiteModule { - constructor(...args) { - super(...args); - - this.should_enable = true; - - this.inject(Following); - this.inject(Game); - this.inject(Community); - } -} \ No newline at end of file diff --git a/src/sites/twitch-twilight/modules/directory/index.off b/src/sites/twitch-twilight/modules/directory/index.off new file mode 100644 index 00000000..eccb6f03 --- /dev/null +++ b/src/sites/twitch-twilight/modules/directory/index.off @@ -0,0 +1,77 @@ +'use strict'; + +// ============================================================================ +// Directory +// ============================================================================ + +import {SiteModule} from 'utilities/module'; +import {duration_to_string} from 'utilities/time'; +import {createElement as e} from 'utilities/dom'; +import {get} from 'utilities/object'; + +import Following from './following'; +import Game from './game'; +import Community from './community'; + +export default class Directory extends SiteModule { + constructor(...args) { + super(...args); + + this.should_enable = true; + + this.inject('i18n'); + this.inject('settings'); + this.inject('site.fine'); + + this.inject(Following); + this.inject(Game); + this.inject(Community); + } + + + clearUptime(inst) { // eslint-disable-line class-methods-use-this + if ( inst.ffz_update_timer ) { + clearInterval(inst.ffz_update_timer); + inst.ffz_update_timer = null; + } + + if ( inst.ffz_uptime_el ) { + inst.ffz_uptime_el.parentElement.removeChild(inst.ffz_uptime_el); + inst.ffz_uptime_el = null; + inst.ffz_uptime_span = null; + inst.ffz_uptime_tt = null; + } + } + + + updateUptime(inst, created_path, selector) { + const container = this.fine.getHostNode(inst), + card = container && container.querySelector && container.querySelector(selector), + setting = this.settings.get('directory.following.uptime'), + created_at = get(created_path, inst), + up_since = created_at && new Date(created_at), + uptime = up_since && Math.floor((Date.now() - up_since) / 1000) || 0; + + if ( ! card || setting === 0 || uptime < 1 ) + return this.clearUptime(inst); + + const up_text = duration_to_string(uptime, false, false, false, setting === 1); + + if ( ! inst.ffz_uptime_el ) + 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', + e('div', 'tw-tooltip-wrapper inline-flex', [ + e('div', 'tw-stat', [ + e('span', 'c-text-live tw-stat__icon', e('figure', 'ffz-i-clock')), + inst.ffz_uptime_span = e('span', 'tw-stat__value') + ]), + inst.ffz_uptime_tt = e('div', 'tw-tooltip tw-tooltip--down tw-tooltip--align-center') + ]))); + + if ( ! inst.ffz_update_timer ) + inst.ffz_update_timer = setInterval(this.updateUptime.bind(this, inst, created_path, selector), 1000); + + inst.ffz_uptime_span.textContent = up_text; + inst.ffz_uptime_tt.textContent = up_since.toLocaleString(); + } +} \ No newline at end of file diff --git a/src/sites/twitch-twilight/modules/following_link.js b/src/sites/twitch-twilight/modules/following_link.off similarity index 98% rename from src/sites/twitch-twilight/modules/following_link.js rename to src/sites/twitch-twilight/modules/following_link.off index 62077aaa..cb437400 100644 --- a/src/sites/twitch-twilight/modules/following_link.js +++ b/src/sites/twitch-twilight/modules/following_link.off @@ -1,7 +1,7 @@ 'use strict'; // ============================================================================ -// Following Button Modification +// Following Button Modification // ============================================================================ import {SiteModule} from 'utilities/module'; @@ -16,7 +16,6 @@ export default class FollowingText extends SiteModule { this.should_enable = true; - // this.inject('site'); this.inject('settings'); this.inject('site.router'); this.inject('site.apollo'); @@ -71,12 +70,12 @@ export default class FollowingText extends SiteModule { for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; - + if (blockedGames.includes(node.stream.game.name)) { filtered += 1; continue; } - + c += 1; if (c > max_lines) { const div = e('div', { @@ -89,7 +88,7 @@ export default class FollowingText extends SiteModule { innerContent.push(div); break; } - + const up_since = new Date(node.stream.createdAt); const uptime = up_since && Math.floor((Date.now() - up_since) / 1000) || 0; const uptimeText = duration_to_string(uptime, false, false, false, true); @@ -100,7 +99,7 @@ export default class FollowingText extends SiteModule { }, [ e('div', { className: 'top-stream-info', - style: 'padding-bottom: 16px;' + style: 'padding-bottom: 16px;' }, [ // Username e('a', { @@ -111,7 +110,7 @@ export default class FollowingText extends SiteModule { onclick: event => { event.preventDefault(); event.stopPropagation(); - + this.router.navigate('user', { userName: node.login }); } }), @@ -194,7 +193,7 @@ export default class FollowingText extends SiteModule { onclick: event => { event.preventDefault(); event.stopPropagation(); - + this.router.navigate('dir-following'); } }), @@ -205,7 +204,7 @@ export default class FollowingText extends SiteModule { }), tipDiv ]); - + topNavContainer.insertBefore(newFollowing, followingText); followingText.classList.add('hide');