164 lines
No EOL
5.2 KiB
JavaScript
164 lines
No EOL
5.2 KiB
JavaScript
import Vue from 'vue'
|
|
import App from './App.vue'
|
|
import vuetify from './plugins/vuetify';
|
|
import store from './store'
|
|
import i18n from './plugins/lang';
|
|
import router from './router'
|
|
import matrix from './services/matrix.service'
|
|
import navigation from './services/navigation.service'
|
|
import config from './services/config.service'
|
|
import analytics from './services/analytics.service'
|
|
import 'roboto-fontface/css/roboto/roboto-fontface.css'
|
|
import 'material-design-icons-iconfont/dist/material-design-icons.css'
|
|
import VEmojiPicker from 'v-emoji-picker';
|
|
import VueResize from 'vue-resize';
|
|
import 'vue-resize/dist/vue-resize.css';
|
|
import VueClipboard from 'vue-clipboard2'
|
|
import VueSanitize from "vue-sanitize";
|
|
|
|
var defaultOptions = VueSanitize.defaults;
|
|
defaultOptions.disallowedTagsMode = "recursiveEscape";
|
|
defaultOptions.allowedTags = [];
|
|
Vue.use(VueSanitize, defaultOptions);
|
|
|
|
Vue.config.productionTip = false
|
|
|
|
Vue.use(VueResize);
|
|
Vue.use(VEmojiPicker);
|
|
Vue.use(matrix, { store: store, i18n: i18n });
|
|
Vue.use(config); // Use this before cleaninsights below, it depends on config!
|
|
Vue.use(analytics);
|
|
Vue.use(VueClipboard);
|
|
|
|
// Add bubble functionality to custom events.
|
|
// From here: https://stackoverflow.com/questions/41993508/vuejs-bubbling-custom-events
|
|
Vue.use((Vue) => {
|
|
Vue.prototype.$bubble = function $bubble(eventName, ...args) {
|
|
// Emit the event on all parent components
|
|
let component = this;
|
|
do {
|
|
component.$emit(eventName, ...args);
|
|
component = component.$parent;
|
|
} while (component);
|
|
};
|
|
});
|
|
|
|
// Register a global custom directive called `v-blur` that prevents focus
|
|
Vue.directive('blur', {
|
|
inserted: function (el) {
|
|
el.onfocus = (ev) => ev.target.blur()
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Handle long taps. Call with the timeout as argument (default 500ms) and the value
|
|
* can be either one function called on long tap or two functions, the
|
|
* first called on "short tap" and the other on "long tap".
|
|
*
|
|
* Like this: v-linkTap:500="[tapped,longTapped]"
|
|
*/
|
|
Vue.directive('longTap', {
|
|
bind: function (el, binding, ignoredvnode) {
|
|
el.longTapTimeout = parseInt(binding.arg || "500");
|
|
el.longTapCallbacks = binding.value;
|
|
for (var i = el.longTapCallbacks.length; i < 2; i++) {
|
|
el.longTapCallbacks.splice(0, 0, null);
|
|
}
|
|
|
|
const touchX = function (event) {
|
|
if (event.type.indexOf("mouse") !== -1) {
|
|
return event.clientX;
|
|
}
|
|
return event.touches[0].clientX;
|
|
};
|
|
const touchY = function (event) {
|
|
if (event.type.indexOf("mouse") !== -1) {
|
|
return event.clientY;
|
|
}
|
|
return event.touches[0].clientY;
|
|
};
|
|
|
|
/**
|
|
* Triggered when our "long tap" timer hits.
|
|
*/
|
|
const touchTimerElapsed = function () {
|
|
el.longTapHandled = true;
|
|
el.longTapCallbacks[1] && el.longTapCallbacks[1].call();
|
|
el.longTapTimer = null;
|
|
el.classList.remove("waiting-for-long-tap");
|
|
};
|
|
|
|
const touchStart = function (e) {
|
|
el.longTapHandled = false;
|
|
el.longTapStartX = touchX(e);
|
|
el.longTapStartY = touchY(e);
|
|
el.longTapTimer = setTimeout(touchTimerElapsed, el.longTapTimeout);
|
|
el.classList.add("waiting-for-long-tap");
|
|
e.preventDefault();
|
|
};
|
|
|
|
const touchCancel = function () {
|
|
el.longTapHandled = true;
|
|
el.longTapTimer && clearTimeout(el.longTapTimer);
|
|
el.longTapTimer = null;
|
|
el.classList.remove("waiting-for-long-tap");
|
|
};
|
|
|
|
const touchEnd = function () {
|
|
el.longTapTimer && clearTimeout(el.longTapTimer);
|
|
el.longTapTimer = null;
|
|
if (!el.longTapHandled) {
|
|
// Not canceled or long tapped. Just a single tap. Do we have a handler?
|
|
el.longTapCallbacks[0] && el.longTapCallbacks[0].call();
|
|
}
|
|
el.classList.remove("waiting-for-long-tap");
|
|
};
|
|
|
|
const touchMove = function (e) {
|
|
el.longTapCurrentX = touchX(e);
|
|
el.longTapCurrentY = touchY(e);
|
|
var tapTolerance = 4;
|
|
var touchMoved =
|
|
Math.abs(el.longTapStartX - el.longTapCurrentX) > tapTolerance ||
|
|
Math.abs(el.longTapStartY - el.longTapCurrentY) > tapTolerance;
|
|
if (touchMoved) {
|
|
touchCancel();
|
|
}
|
|
};
|
|
|
|
el.longTapTouchStart = touchStart;
|
|
el.longTapTouchEnd = touchEnd;
|
|
el.longTapTouchCancel = touchCancel;
|
|
el.longTapTouchMove = touchMove;
|
|
el.addEventListener("touchstart", touchStart);
|
|
el.addEventListener("touchend", touchEnd);
|
|
el.addEventListener("touchcancel", touchCancel);
|
|
el.addEventListener("touchmove", touchMove);
|
|
el.addEventListener("mousedown", touchStart);
|
|
el.addEventListener("mouseup", touchEnd);
|
|
el.addEventListener("mousemove", touchMove);
|
|
},
|
|
unbind: function (el) {
|
|
el.longTapTimer && clearTimeout(el.longTapTimer);
|
|
el.removeEventListener("touchstart", el.longTapTouchStart);
|
|
el.removeEventListener("touchend", el.longTapTouchEnd);
|
|
el.removeEventListener("touchcancel", el.longTapTouchCancel);
|
|
el.removeEventListener("touchmove", el.longTapTouchMove);
|
|
el.removeEventListener("mousedown", el.longTapTouchStart);
|
|
el.removeEventListener("mouseup", el.longTapTouchEnd);
|
|
el.removeEventListener("mousemove", el.longTapTouchMove);
|
|
},
|
|
});
|
|
|
|
Vue.use(navigation, router);
|
|
|
|
new Vue({
|
|
vuetify,
|
|
store,
|
|
i18n,
|
|
router,
|
|
matrix,
|
|
config,
|
|
analytics,
|
|
render: h => h(App)
|
|
}).$mount('#app'); |