Skip to content

Commit

Permalink
Fix bug tokenizing cheers in messages. Try to fix any bugs getting a …
Browse files Browse the repository at this point in the history
…user for a room. Strip apollo 404 messages from Sentry. Don't show the expansion arrows in the emote menu when using a filter. Fix emoji tab completion a bit. `:bee:` should not match `:beer:`. Start using crossorigin for script serving. Add a debug transformation for localization.
  • Loading branch information
SirStendec committed Apr 15, 2018
1 parent 730e212 commit e581b50
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 18 deletions.
8 changes: 8 additions & 0 deletions changelog.html
@@ -1,3 +1,11 @@
<div class="list-header">4.0.0-beta2.18<span>@c8636911fc387a9f5e0c</span> <time datetime="2018-04-15">(2018-04-15)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Added: Debugging setting for localization to help test UI issues, identify strings, and find strings that aren't localized.</li>
<li>Fixed: Issue tokenizing cheers in messages.</li>
<li>Fixed: Clean up tab-completion of emoji a bit more.</li>
<li>Changed: Start using `crossorigin="anonymous"` when loading scripts from our CDN.</li>
</ul>

<div class="list-header">4.0.0-beta2.17<span>@dce1b0c5268bdd3fe086</span> <time datetime="2018-04-13">(2018-04-13)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Fixed: An issue in automatic error reporting potentially swallowing errors when error reporting is disabled.</li>
Expand Down
1 change: 1 addition & 0 deletions src/entry.js
Expand Up @@ -13,6 +13,7 @@
script = document.createElement('script');

script.id = 'ffz-script';
script.crossOrigin = 'anonymous';
script.src = `${SERVER}/script/${BABEL}${FLAVOR}.js?_=${Date.now()}`;
document.head.appendChild(script);
})();
81 changes: 80 additions & 1 deletion src/i18n.js
Expand Up @@ -7,10 +7,59 @@
// ============================================================================

import {SERVER} from 'utilities/constants';
import {has} from 'utilities/object';
import {pick_random, has} from 'utilities/object';
import Module from 'utilities/module';


const FACES = ['(・`ω´・)', ';;w;;', 'owo', 'UwU', '>w<', '^w^'],

format_text = (phrase, token_regex, formatter) => {
const out = [];

let i = 0, match;
token_regex.lastIndex = 0;

while((match = token_regex.exec(phrase))) {
if ( match.index !== i )
out.push(formatter(phrase.slice(i, match.index)))

out.push(match[0]);
i = match.index + match[0].length;
}

if ( i < phrase.length )
out.push(formatter(phrase.slice(i)));

return out.join('')
},

owo = text => text
.replace(/(?:r|l)/g, 'w')
.replace(/(?:R|L)/g, 'W')
.replace(/n([aeiou])/g, 'ny$1')
.replace(/N([aeiou])/g, 'Ny$1')
.replace(/N([AEIOU])/g, 'NY$1')
.replace(/ove/g, 'uv')
.replace(/!+/g, ` ${pick_random(FACES)} `),


TRANSFORMATIONS = {
double: (key, text) =>
`${text} ${text}`,

upper: (key, text, opts, locale, token_regex) =>
format_text(text, token_regex, t => t.toUpperCase()),

lower: (key, text, opts, locale, token_regex) =>
format_text(text, token_regex, t => t.toLowerCase()),

append_key: (key, text) => `${text} (${key})`,

owo: (key, text, opts, locale, token_regex) =>
format_text(text, token_regex, t => owo(t))
};


// ============================================================================
// TranslationManager
// ============================================================================
Expand All @@ -28,6 +77,31 @@ export class TranslationManager extends Module {
//ja: { name: '日本語' }
}


this.settings.add('i18n.debug.transform', {
default: null,
ui: {
path: 'Debugging > Localization >> General',
title: 'Transformation',
description: 'Transform all localized strings to test string coverage as well as length.',
component: 'setting-select-box',
data: [
{value: null, title: 'Disabled'},
{value: 'upper', title: 'Upper Case'},
{value: 'lower', title: 'Lower Case'},
{value: 'append_key', title: 'Append Key'},
{value: 'double', title: 'Double'},
{value: 'owo', title: "owo what's this"}
]
},

changed: val => {
this._.transformation = TRANSFORMATIONS[val];
this.emit(':update')
}
});


this.settings.add('i18n.locale', {
default: -1,
process: (ctx, val) => {
Expand Down Expand Up @@ -65,6 +139,7 @@ export class TranslationManager extends Module {
awarn: (...args) => this.log.info(...args)
});*/

this._.transformation = TRANSFORMATIONS[this.settings.get('i18n.debug.transform')];
this.locale = this.settings.get('i18n.locale');
}

Expand Down Expand Up @@ -311,6 +386,7 @@ export default class TranslationCore {
this.extend(options.phrases);
this.locale = options.locale || 'en';
this.defaultLocale = options.defaultLocale || this.locale;
this.transformation = null;

const allowMissing = options.allowMissing ? transformPhrase : null;
this.onMissingKey = typeof options.onMissingKey === 'function' ? options.onMissingKey : allowMissing;
Expand Down Expand Up @@ -413,6 +489,9 @@ export default class TranslationCore {
return key;
}

if ( this.transformation )
p = this.transformation(key, p, opts, locale, this.tokenRegex);

return this.transformPhrase(p, opts, locale, this.tokenRegex, this.formatters);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main.js
Expand Up @@ -100,7 +100,7 @@ class FrankerFaceZ extends Module {
FrankerFaceZ.Logger = Logger;

const VER = FrankerFaceZ.version_info = {
major: 4, minor: 0, revision: 0, extra: '-beta2.17',
major: 4, minor: 0, revision: 0, extra: '-beta2.18',
build: __webpack_hash__,
toString: () =>
`${VER.major}.${VER.minor}.${VER.revision}${VER.extra || ''}${DEBUG ? '-dev' : ''}`
Expand Down
23 changes: 17 additions & 6 deletions src/modules/chat/room.js
Expand Up @@ -116,7 +116,7 @@ export default class Room {
}


getUser(id, login, no_create, no_login) {
getUser(id, login, no_create, no_login, error = false) {
if ( this.destroyed )
return null;

Expand All @@ -130,17 +130,28 @@ export default class Room {
else if ( this.users[login] && ! no_login )
user = this.users[login];

else if ( no_create )
return null;
if ( user && user.destroyed )
user = null;

if ( ! user ) {
if ( no_create )
return null;

else
user = new User(this.manager, this, id, login);
}

if ( id && id !== user.id ) {
// If the ID isn't what we expected, something is very wrong here.
// Blame name changes.
if ( user.id )
throw new Error('id mismatch');
if ( user.id ) {
this.manager.log.warn(`Data mismatch for user #${id} -- Stored ID: ${user.id} -- Login: ${login} -- Stored Login: ${user.login}`);
if ( error )
throw new Error('id mismatch');

// Remove the old reference if we're going with this.
if ( this.user_ids[user.id] === user )
this.user_ids[user.id] = null;
}

// Otherwise, we're just here to set the ID.
user._id = id;
Expand Down
2 changes: 2 additions & 0 deletions src/modules/chat/tokenizers.jsx
Expand Up @@ -389,6 +389,8 @@ export const CheerEmotes = {
token.hidden = true;
}

text.push('');

} else
text.push(segment);
}
Expand Down
2 changes: 1 addition & 1 deletion src/raven.js
Expand Up @@ -112,7 +112,7 @@ export default class RavenLogger extends Module {
}
}));
})
})
});
});

this.raven = Raven;
Expand Down
4 changes: 2 additions & 2 deletions src/sites/twitch-twilight/modules/chat/emote_menu.jsx
Expand Up @@ -351,7 +351,7 @@ export default class EmoteMenu extends Module {
}

clickHeading() {
if ( this.props.filter )
if ( this.props.filtered )
return;

const collapsed = storage.get('emote-menu.collapsed') || [],
Expand Down Expand Up @@ -440,7 +440,7 @@ export default class EmoteMenu extends Module {
</div>
<div class="tw-flex-grow-1" />
{data.source || 'FrankerFaceZ'}
<figure class={`tw-pd-l-05 ffz-i-${collapsed ? 'left' : 'down'}-dir`} />
{filtered ? '' : <figure class={`tw-pd-l-05 ffz-i-${collapsed ? 'left' : 'down'}-dir`} />}
</heading>) : null}
{collapsed || this.renderBody(show_heading)}
</section>)
Expand Down
9 changes: 5 additions & 4 deletions src/sites/twitch-twilight/modules/chat/tab_completion.jsx
Expand Up @@ -147,13 +147,14 @@ export default class TabCompletion extends Module {
getEmojiSuggestions(input, inst) {
let search = input.slice(1).toLowerCase();
const style = this.chat.context.get('chat.emoji.style'),
results = [];
results = [],
has_colon = search.endsWith(':');

if ( search.endsWith(':') )
search = search.slice(0, -1);
if ( has_colon )
search = search.slice(0,-1);

for(const name in this.emoji.names)
if ( name.startsWith(search) ) {
if ( has_colon ? name === search : name.startsWith(search) ) {
const emoji = this.emoji.emoji[this.emoji.names[name]];
if ( emoji && (style === 0 || emoji.has[style]) )
results.push({
Expand Down
1 change: 1 addition & 0 deletions src/utilities/compat/apollo.js
Expand Up @@ -14,6 +14,7 @@ const BAD_ERRORS = [
'unable to load',
'error internal',
'context deadline exceeded',
'404',
'500',
'501',
'502',
Expand Down
11 changes: 11 additions & 0 deletions src/utilities/object.js
Expand Up @@ -235,6 +235,17 @@ export function split_chars(str) {
}


export function pick_random(obj) {
if ( ! obj )
return null;

if ( ! Array.isArray(obj) )
return obj[pick_random(Object.keys(obj))]

return obj[Math.floor(Math.random() * obj.length)];
}


export class SourcedSet {
constructor() {
this._cache = [];
Expand Down
4 changes: 2 additions & 2 deletions src/utilities/tooltip.js
Expand Up @@ -73,7 +73,7 @@ export class Tooltip {
} else if ( this.live ) {
this._onMouseOver = e => {
const target = e.target;
if ( target && target.classList.contains(this.cls) )
if ( target && target.classList && target.classList.contains(this.cls) )
this._enter(target);
};

Expand Down Expand Up @@ -296,8 +296,8 @@ export class Tooltip {


// Add everything to the DOM and create the Popper instance.
this.parent.appendChild(el);
tip.popper = new Popper(target, el, pop_opts);
this.parent.appendChild(el);
tip.visible = true;

if ( opts.onShow )
Expand Down
3 changes: 2 additions & 1 deletion webpack.common.js
Expand Up @@ -27,7 +27,8 @@ module.exports = {
output: {
chunkFilename: '[name].[chunkhash].js',
path: path.resolve(__dirname, 'dist'),
jsonpFunction: 'ffzWebpackJsonp'
jsonpFunction: 'ffzWebpackJsonp',
crossOriginLoading: 'anonymous'
},
plugins: [
new webpack.ExtendedAPIPlugin()
Expand Down

0 comments on commit e581b50

Please sign in to comment.