1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-28 05:15:54 +00:00
FrankerFaceZ/src/utilities/vue.js
SirStendec aa25bff498 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.
2019-06-08 17:35:48 -04:00

167 lines
No EOL
3.7 KiB
JavaScript

'use strict';
// ============================================================================
// Vue Library
// Loads Vue + Translation Shim
// ============================================================================
import Module from 'utilities/module';
import {has} from 'utilities/object';
import {DEBUG} from 'utilities/constants';
export class Vue extends Module {
constructor(...args) {
super(...args);
this._components = {};
this.inject('i18n');
}
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);
Vue.use(ObserveVisibility);
if ( ! DEBUG && this.root.raven )
this.root.raven.addPlugin(RavenVue, Vue);
for(const key in components)
if ( has(components, key) )
Vue.component(key, components[key]);
this._components = null;
Vue.use(this);
}
component(name, component) {
if ( typeof name === 'function' ) {
for(const key of name.keys())
this.component(key.slice(2, key.length - 4), name(key).default);
} else if ( typeof name === 'object' ) {
for(const key in name)
if ( has(name, key) )
this.component(key, name[key]);
} else if ( this.Vue )
this.Vue.component(name, component);
else
this._components[name] = component;
}
install(vue) {
// This is a mess. I'm sure there's an easier way to tie the systems
// together. However, for now, this works.
const t = this;
if ( ! this._vue_i18n ) {
this._vue_i18n = new this.Vue({
data() {
return {
locale: t.i18n.locale,
phrases: {}
}
},
methods: {
t_(key, phrase, options) {
this.locale && this.phrases[key];
return t.i18n.t(key, phrase, options);
},
tList_(key, phrase, options) {
this.locale && this.phrases[key];
return t.i18n.tList(key, phrase, options);
},
setLocale(locale) {
t.i18n.locale = locale;
}
}
});
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 = {};
});
this.on('i18n:loaded', keys => {
const i = this._vue_i18n,
p = i.phrases;
for(const key of keys)
i.$set(p, key, (p[key]||0) + 1);
});
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) {
const router = t.resolve('site.router');
if ( router && router.history ) {
if ( event ) {
event.preventDefault();
event.stopPropagation();
}
router.history.push(url);
}
},
t(key, phrase, options) {
return this.$i18n.t_(key, phrase, options);
},
tList(key, phrase, options) {
return this.$i18n.tList_(key, phrase, options);
}
}
});
}
}
export default Vue;