mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-10-14 06:51:58 +00:00
4.3.0
* Added: Setting to hide the "Not Live" bar beneath videos and clips that appears when the channel is currently live. * Fixed: Handling of `https://www.twitch.tv/<channel>/clip/<slug>` urls for rich chat embeds and rich link tool-tips. * Fixed: Lower the priority of custom highlight terms so they will not break links. * Fixed: Holding multiple modifier keys to display in-line chat actions. * Fixed: Clean up out-dated avatar display setting for the directory. * API Added: Allow add-ons to access the Popper JS library via `FrankerFaceZ.utilities.popper`. * API Added: `<icon-picker />` Vue component for selecting an icon. * API Added: `<react-link />` Vue component for creating links that cause the React app to navigate without a page load. * API Added: `<t-list />` Vue component for translating text including Vue elements. * API Added: `maybeLoad(icon)` function for font awesome to only load the font if the icon is from font awesome. * API Added: `generateUUID()` function to `FrankerFaceZ.utilities.object` * API Added: The `vue-observe-visibility` module is now loaded with Vue and made available in all Vue contexts.
This commit is contained in:
parent
3157aeb390
commit
aa25bff498
22 changed files with 210 additions and 218 deletions
|
@ -237,3 +237,9 @@ export const load = () => {
|
|||
}));
|
||||
}
|
||||
|
||||
export const maybeLoad = icon => {
|
||||
if ( loaded || ! String(icon).startsWith('fa-') && ! String(icon).startsWith('ffz-fa') )
|
||||
return;
|
||||
|
||||
load();
|
||||
}
|
|
@ -2,6 +2,28 @@
|
|||
|
||||
const HOP = Object.prototype.hasOwnProperty;
|
||||
|
||||
// Source: https://gist.github.com/jed/982883 (WTFPL)
|
||||
export function generateUUID(input) {
|
||||
return input // if the placeholder was passed, return
|
||||
? ( // a random number from 0 to 15
|
||||
input ^ // unless b is 8,
|
||||
Math.random() // in which case
|
||||
* 16 // a random number from
|
||||
>> input/4 // 8 to 11
|
||||
).toString(16) // in hexadecimal
|
||||
: ( // or otherwise a concatenated string:
|
||||
[1e7] + // 10000000 +
|
||||
-1e3 + // -1000 +
|
||||
-4e3 + // -4000 +
|
||||
-8e3 + // -80000000 +
|
||||
-1e11 // -100000000000,
|
||||
).replace( // replacing
|
||||
/[018]/g, // zeroes, ones, and eights with
|
||||
generateUUID // random hex digits
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export function has(object, key) {
|
||||
return object ? HOP.call(object, key) : false;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import Module from 'utilities/module';
|
||||
import {has} from 'utilities/object';
|
||||
import {DEBUG} from 'utilities/constants';
|
||||
|
||||
|
||||
export class Vue extends Module {
|
||||
|
@ -18,12 +19,15 @@ export class Vue extends Module {
|
|||
|
||||
async onLoad() {
|
||||
const Vue = window.ffzVue = this.Vue = (await import(/* webpackChunkName: "vue" */ 'vue')).default,
|
||||
ObserveVisibility = await import(/* webpackChunkName: "vue" */ 'vue-observe-visibility'),
|
||||
RavenVue = await import(/* webpackChunkName: "vue" */ 'raven-js/plugins/vue'),
|
||||
components = this._components;
|
||||
|
||||
this.component((await import(/* webpackChunkName: "vue" */ 'src/std-components/index.js')).default);
|
||||
|
||||
if ( this.root.raven )
|
||||
Vue.use(ObserveVisibility);
|
||||
|
||||
if ( ! DEBUG && this.root.raven )
|
||||
this.root.raven.addPlugin(RavenVue, Vue);
|
||||
|
||||
for(const key in components)
|
||||
|
@ -82,6 +86,11 @@ export class Vue extends Module {
|
|||
}
|
||||
});
|
||||
|
||||
this.on('i18n:transform', () => {
|
||||
this._vue_i18n.locale = this.i18n.locale;
|
||||
this._vue_i18n.phrases = {};
|
||||
});
|
||||
|
||||
this.on('i18n:changed', () => {
|
||||
this._vue_i18n.locale = this.i18n.locale;
|
||||
this._vue_i18n.phrases = {};
|
||||
|
@ -97,6 +106,41 @@ export class Vue extends Module {
|
|||
vue.prototype.$i18n = this._vue_i18n;
|
||||
}
|
||||
|
||||
vue.component('t-list', {
|
||||
props: {
|
||||
tag: {
|
||||
required: false
|
||||
},
|
||||
phrase: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
default: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
|
||||
render(createElement) {
|
||||
return createElement(
|
||||
this.tag || 'span',
|
||||
this.$i18n.tList_(
|
||||
this.phrase,
|
||||
this.default,
|
||||
Object.assign({}, this.data, this.$scopedSlots)
|
||||
).map(out => {
|
||||
if ( typeof out === 'function' )
|
||||
return out();
|
||||
return out;
|
||||
})
|
||||
);
|
||||
}
|
||||
})
|
||||
|
||||
vue.mixin({
|
||||
methods: {
|
||||
reactNavigate(url, event) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue