Recv/public/src/app.js

168 lines
4.2 KiB
JavaScript

import 'babel-polyfill';
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import VueRouter from 'vue-router';
import App from './App.vue';
import messages from './lang';
import shared from './shared';
import fontawesome from '@fortawesome/fontawesome';
import FontAwesomeIcon from '@fortawesome/vue-fontawesome';
import moment from 'moment'
import merge from 'lodash/merge';
// Implicitly import the icons used, saves a lot of space in the bundle.
// Perhaps vue-fontawesome will make this easier in the upcoming release?
// See: https://github.com/FortAwesome/vue-fontawesome/issues/46
import faSpinner from '@fortawesome/fontawesome-free-solid/faSpinner';
import faBan from '@fortawesome/fontawesome-free-solid/faBan';
import faTrashAlt from '@fortawesome/fontawesome-free-solid/faTrashAlt';
import faUser from '@fortawesome/fontawesome-free-solid/faUser';
if (typeof customMessages !== 'undefined')
{
merge(messages, customMessages);
if (customMessages.hasOwnProperty('allLocales'))
{
for (var key in messages)
{
if (key !== 'allLocales' && messages.hasOwnProperty(key))
merge(messages[key], customMessages.allLocales);
}
}
}
fontawesome.library.add(faSpinner, faBan, faTrashAlt, faUser);
Vue.component('fa', FontAwesomeIcon);
Vue.use(VueI18n);
Vue.use(VueRouter);
const i18n = new VueI18n({
locale: navigator.language ? navigator.language.split('-')[0] : null,
fallbackLocale: 'en',
messages: messages
});
Vue.filter('formatDateTime', (value) =>
{
if (value)
{
return moment(String(value)).format(i18n.t('dateTimeFormat'))
}
});
Vue.filter('formatDate', (value) =>
{
if (value)
{
return moment(String(value)).format(i18n.t('dateFormat'))
}
});
Vue.filter('formatTime', (value) =>
{
if (value)
{
return moment(String(value)).format(i18n.t('timeFormat'))
}
});
// All credit goes to: https://stackoverflow.com/a/14919494
function humanFileSize(bytes, si)
{
var thresh = si ? 1000 : 1024;
if(Math.abs(bytes) < thresh)
{
return bytes + ' B';
}
var units = si
? ['kB','MB','GB','TB','PB','EB','ZB','YB']
: ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
var u = -1;
do
{
bytes /= thresh;
++u;
}
while(Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1) + ' ' + units[u];
}
Vue.filter('formatSize', (value) =>
{
return humanFileSize(value, false);
});
Vue.filter('formatSizeSI', (value) =>
{
return humanFileSize(value, true);
});
const Code = () => import('./route/Code.vue');
const AdminCodeDetail = () => import('./route/admin/CodeDetail.vue');
const AdminUserDetail = () => import('./route/admin/UserDetail.vue');
const router = new VueRouter({
routes: [
{ path: '/', component: () => import('./route/Landing.vue'),
children: [
{ path: 'c/:codeParam', component: Code, props: true },
{ path: 'u/:codeParam', component: () => import('./route/Upload.vue'), props: true },
{ path: '', component: Code }
]
},
{ path: '/admin', component: () => import('./route/admin/Landing.vue'),
children: [
{ path: 'uploads', name: 'adminDefault', component: () => import('./route/admin/Uploads.vue') },
{ path: 'codes/add', component: AdminCodeDetail },
{ path: 'codes/edit/:codeParam', component: AdminCodeDetail, props: true },
{ path: 'codes', component: () => import('./route/admin/Codes.vue') },
{ path: 'profile', component: () => import('./route/admin/Profile.vue') },
{ path: 'users/add', component: AdminUserDetail },
{ path: 'users/edit/:idParam', component: AdminUserDetail, props: true },
{ path: 'users', component: () => import('./route/admin/Users.vue') },
{ path: '', name: 'adminRoot', component: () => import('./route/admin/Login.vue') }
]
},
{ path: '*', redirect: '/' }
]
});
router.beforeEach((to, from, next) =>
{
let isAdminRoot = to.name == 'adminRoot';
if (to.path.substring(0, 7) == '/admin/' && !isAdminRoot)
{
if (!shared.adminToken)
{
router.push({ name: 'adminRoot' });
return;
}
}
else if (isAdminRoot && shared.adminToken)
{
router.push({ name: 'adminDefault' });
return;
}
next();
});
new Vue({
el: '#app',
i18n,
router,
render: h => h(App)
});