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:
parent
60f86033e8
commit
cbaf4b6878
5 changed files with 133 additions and 80 deletions
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
27
src/sites/twitch-twilight/styles/directory.scss
Normal file
27
src/sites/twitch-twilight/styles/directory.scss
Normal 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 }
|
||||||
|
}
|
|
@ -6,4 +6,6 @@
|
||||||
@import 'channel';
|
@import 'channel';
|
||||||
|
|
||||||
@import 'chat';
|
@import 'chat';
|
||||||
|
@import 'directory';
|
||||||
|
|
||||||
@import 'fixes';
|
@import 'fixes';
|
Loading…
Add table
Add a link
Reference in a new issue