misskey/src/client/app/init.ts

489 lines
9.4 KiB
TypeScript
Raw Normal View History

2017-05-17 22:06:55 +02:00
/**
* App initializer
*/
2018-02-09 05:32:41 +01:00
import Vue from 'vue';
2018-04-29 11:16:02 +02:00
import Vuex from 'vuex';
2018-02-09 05:32:41 +01:00
import VueRouter from 'vue-router';
2018-03-10 05:22:20 +01:00
import VAnimateCss from 'v-animate-css';
2018-09-01 13:47:49 +02:00
import VModal from 'vue-js-modal';
import VueI18n from 'vue-i18n';
2018-12-16 03:32:20 +01:00
import SequentialEntrance from 'vue-sequential-entrance';
2018-03-03 06:25:36 +01:00
2018-09-26 12:14:11 +02:00
import VueHotkey from './common/hotkey';
2019-02-16 00:51:35 +01:00
import VueSize from './common/size';
2018-03-03 06:25:36 +01:00
import App from './app.vue';
import checkForUpdate from './common/scripts/check-for-update';
import MiOS from './mios';
2019-02-17 20:52:40 +01:00
import { version, codename, lang, locale } from './config';
2018-10-02 09:04:31 +02:00
import { builtinThemes, lightTheme, applyTheme } from './theme';
2018-12-02 07:28:52 +01:00
import Dialog from './common/views/components/dialog.vue';
2018-09-26 12:14:11 +02:00
if (localStorage.getItem('theme') == null) {
2018-09-28 17:01:11 +02:00
applyTheme(lightTheme);
2018-09-26 12:14:11 +02:00
}
2018-03-03 06:25:36 +01:00
//#region FontAwesome
import { library } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import {
faRetweet,
faPlus,
faUser,
faCog,
faCheck,
faStar,
faReply,
faEllipsisH,
faQuoteLeft,
faQuoteRight,
faAngleUp,
faAngleDown,
faAt,
faHashtag,
faHome,
faGlobe,
faCircle,
faList,
faHeart,
faUnlock,
faRssSquare,
faSort,
faChartPie,
faChartBar,
faPencilAlt,
faColumns,
faComments,
faGamepad,
faCloud,
faPowerOff,
faChevronCircleLeft,
faChevronCircleRight,
faShareAlt,
faTimes,
faThumbtack,
faSearch,
faAngleRight,
faWrench,
faTerminal,
faMoon,
faPalette,
faSlidersH,
faDesktop,
faVolumeUp,
faLanguage,
faInfoCircle,
faExclamationTriangle,
faKey,
faBan,
faCogs,
faUnlockAlt,
faPuzzlePiece,
faMobileAlt,
faSignInAlt,
faSyncAlt,
faPaperPlane,
faUpload,
faMapMarkerAlt,
faEnvelope,
faLock,
faFolderOpen,
faBirthdayCake,
faImage,
faEye,
faDownload,
faFileImport,
faLink,
faArrowRight,
faICursor,
faCaretRight,
faReplyAll,
faCamera,
faMinus,
faCaretDown,
faCalculator,
faUsers,
faBars,
faFileImage,
faPollH,
faFolder,
faMicrochip,
faMemory,
faServer,
faExclamationCircle,
2018-11-13 14:45:28 +01:00
faSpinner,
2018-11-14 06:57:59 +01:00
faBroadcastTower,
faChartLine,
2018-11-14 10:03:38 +01:00
faEllipsisV,
2018-11-14 10:07:38 +01:00
faStickyNote,
faUserClock,
2018-11-14 17:43:26 +01:00
faUserPlus,
2018-11-14 19:14:52 +01:00
faExternalLinkSquareAlt,
2018-11-14 19:17:48 +01:00
faSync,
faArrowLeft,
faMapMarker,
faRobot,
2018-12-20 18:30:49 +01:00
faHourglassHalf,
faGavel
} from '@fortawesome/free-solid-svg-icons';
import {
faBell as farBell,
faEnvelope as farEnvelope,
faComments as farComments,
faTrashAlt as farTrashAlt,
faWindowRestore as farWindowRestore,
faFolder as farFolder,
faLaugh as farLaugh,
faSmile as farSmile,
faEyeSlash as farEyeSlash,
faFolderOpen as farFolderOpen,
faSave as farSave,
faImages as farImages,
faChartBar as farChartBar,
faCommentAlt as farCommentAlt,
faClock as farClock,
faCalendarAlt as farCalendarAlt,
faHdd as farHdd,
2018-11-15 21:38:16 +01:00
faMoon as farMoon,
faPlayCircle as farPlayCircle,
2018-12-01 19:43:05 +01:00
faLightbulb as farLightbulb,
faStickyNote as farStickyNote,
} from '@fortawesome/free-regular-svg-icons';
2018-11-13 17:45:15 +01:00
import {
faTwitter as fabTwitter,
faGithub as fabGithub,
faDiscord as fabDiscord
2018-11-13 17:45:15 +01:00
} from '@fortawesome/free-brands-svg-icons';
2018-11-13 19:05:13 +01:00
import i18n from './i18n';
2018-11-13 17:45:15 +01:00
library.add(
faRetweet,
faPlus,
faUser,
faCog,
faCheck,
faStar,
faReply,
faEllipsisH,
faQuoteLeft,
faQuoteRight,
faAngleUp,
faAngleDown,
faAt,
faHashtag,
faHome,
faGlobe,
faCircle,
faList,
faHeart,
faUnlock,
faRssSquare,
faSort,
faChartPie,
faChartBar,
faPencilAlt,
faColumns,
faComments,
faGamepad,
faCloud,
faPowerOff,
faChevronCircleLeft,
faChevronCircleRight,
faShareAlt,
faTimes,
faThumbtack,
faSearch,
faAngleRight,
faWrench,
faTerminal,
faMoon,
faPalette,
faSlidersH,
faDesktop,
faVolumeUp,
faLanguage,
faInfoCircle,
faExclamationTriangle,
faKey,
faBan,
faCogs,
faUnlockAlt,
faPuzzlePiece,
faMobileAlt,
faSignInAlt,
faSyncAlt,
faPaperPlane,
faUpload,
faMapMarkerAlt,
faEnvelope,
faLock,
faFolderOpen,
faBirthdayCake,
faImage,
faEye,
faDownload,
faFileImport,
faLink,
faArrowRight,
faICursor,
faCaretRight,
faReplyAll,
faCamera,
faMinus,
faCaretDown,
faCalculator,
faUsers,
faBars,
faFileImage,
faPollH,
faFolder,
faMicrochip,
faMemory,
faServer,
faExclamationCircle,
2018-11-13 14:45:28 +01:00
faSpinner,
2018-11-13 18:04:24 +01:00
faBroadcastTower,
2018-11-14 06:57:59 +01:00
faChartLine,
2018-11-14 10:03:38 +01:00
faEllipsisV,
2018-11-14 10:07:38 +01:00
faStickyNote,
faUserClock,
2018-11-14 17:43:26 +01:00
faUserPlus,
2018-11-14 19:14:52 +01:00
faExternalLinkSquareAlt,
2018-11-14 19:17:48 +01:00
faSync,
faArrowLeft,
faMapMarker,
2018-12-01 19:43:05 +01:00
faRobot,
2018-12-20 18:30:49 +01:00
faHourglassHalf,
faGavel,
farBell,
farEnvelope,
farComments,
farTrashAlt,
farWindowRestore,
farFolder,
farLaugh,
farSmile,
farEyeSlash,
farFolderOpen,
farSave,
farImages,
farChartBar,
farCommentAlt,
farClock,
farCalendarAlt,
farHdd,
2018-11-15 21:38:16 +01:00
farMoon,
farPlayCircle,
2018-12-01 19:43:05 +01:00
farLightbulb,
farStickyNote,
2018-11-13 17:45:15 +01:00
fabTwitter,
fabGithub,
fabDiscord
);
//#endregion
Vue.use(Vuex);
2018-02-09 05:32:41 +01:00
Vue.use(VueRouter);
2018-03-10 05:22:20 +01:00
Vue.use(VAnimateCss);
2018-09-01 13:47:49 +02:00
Vue.use(VModal);
Vue.use(VueHotkey);
2019-02-16 00:51:35 +01:00
Vue.use(VueSize);
Vue.use(VueI18n);
2018-12-16 03:32:20 +01:00
Vue.use(SequentialEntrance);
2018-02-09 05:32:41 +01:00
Vue.component('fa', FontAwesomeIcon);
2018-02-11 16:17:51 +01:00
// Register global directives
require('./common/views/directives');
// Register global components
require('./common/views/components');
2018-02-24 16:18:09 +01:00
require('./common/views/widgets');
2018-02-11 16:17:51 +01:00
2018-02-19 23:56:39 +01:00
// Register global filters
2018-02-26 18:36:19 +01:00
require('./common/views/filters');
2018-02-19 23:56:39 +01:00
2018-02-16 19:53:21 +01:00
Vue.mixin({
2018-09-15 14:53:04 +02:00
methods: {
destroyDom() {
this.$destroy();
if (this.$el.parentNode) {
this.$el.parentNode.removeChild(this.$el);
}
2018-02-17 10:14:23 +01:00
}
2018-02-16 19:53:21 +01:00
}
});
2017-05-17 22:06:55 +02:00
/**
* APP ENTRY POINT!
*/
2018-03-29 07:48:47 +02:00
console.info(`Misskey v${version} (${codename})`);
2018-02-24 02:34:36 +01:00
console.info(
`%c${locale['common']['do-not-copy-paste']}`,
2018-03-06 06:32:15 +01:00
'color: red; background: yellow; font-size: 16px; font-weight: bold;');
2017-05-17 22:06:55 +02:00
2017-11-28 07:05:55 +01:00
// BootTimer解除
window.clearTimeout((window as any).mkBootTimer);
delete (window as any).mkBootTimer;
2018-02-09 10:28:06 +01:00
//#region Set lang attr
const html = document.documentElement;
2018-02-24 16:18:09 +01:00
html.setAttribute('lang', lang);
2018-02-09 10:28:06 +01:00
//#endregion
2017-05-17 22:06:55 +02:00
// iOSでプライベートモードだとlocalStorageが使えないので既存のメソッドを上書きする
try {
localStorage.setItem('kyoppie', 'yuppie');
} catch (e) {
Storage.prototype.setItem = () => { }; // noop
}
// クライアントを更新すべきならする
if (localStorage.getItem('should-refresh') == 'true') {
localStorage.removeItem('should-refresh');
location.reload(true);
}
2017-11-15 19:06:52 +01:00
// MiOSを初期化してコールバックする
export default (callback: (launch: (router: VueRouter) => [Vue, MiOS], os: MiOS) => void, sw = false) => {
2018-02-18 04:35:18 +01:00
const os = new MiOS(sw);
2017-06-06 17:04:28 +02:00
2018-02-18 04:35:18 +01:00
os.init(() => {
2017-05-17 22:06:55 +02:00
// アプリ基底要素マウント
2018-02-10 02:52:26 +01:00
document.body.innerHTML = '<div id="app"></div>';
2018-02-09 10:57:42 +01:00
const launch = (router: VueRouter) => {
2018-09-28 17:01:11 +02:00
//#region theme
os.store.watch(s => {
return s.device.darkmode;
}, v => {
const themes = os.store.state.device.themes.concat(builtinThemes);
2018-10-02 09:04:31 +02:00
const dark = themes.find(t => t.id == os.store.state.device.darkTheme);
const light = themes.find(t => t.id == os.store.state.device.lightTheme);
2018-09-28 17:01:11 +02:00
applyTheme(v ? dark : light);
});
os.store.watch(s => {
return s.device.lightTheme;
}, v => {
const themes = os.store.state.device.themes.concat(builtinThemes);
2018-10-02 09:04:31 +02:00
const theme = themes.find(t => t.id == v);
2018-09-28 17:01:11 +02:00
if (!os.store.state.device.darkmode) {
applyTheme(theme);
}
});
os.store.watch(s => {
return s.device.darkTheme;
}, v => {
const themes = os.store.state.device.themes.concat(builtinThemes);
2018-10-02 09:04:31 +02:00
const theme = themes.find(t => t.id == v);
2018-09-28 17:01:11 +02:00
if (os.store.state.device.darkmode) {
applyTheme(theme);
}
});
//#endregion
// Reapply current theme
try {
const themeName = os.store.state.device.darkmode ? os.store.state.device.darkTheme : os.store.state.device.lightTheme;
const themes = os.store.state.device.themes.concat(builtinThemes);
const theme = themes.find(t => t.id == themeName);
if (theme) {
applyTheme(theme);
}
} catch (e) {
console.log(`Cannot reapply theme. ${e}`);
}
2018-12-30 06:00:57 +01:00
//#region line width
document.documentElement.style.setProperty('--lineWidth', `${os.store.state.device.lineWidth}px`);
2018-12-30 06:00:57 +01:00
os.store.watch(s => {
return s.device.lineWidth;
2018-12-30 06:00:57 +01:00
}, v => {
document.documentElement.style.setProperty('--lineWidth', `${os.store.state.device.lineWidth}px`);
2018-12-30 06:00:57 +01:00
});
//#endregion
2018-10-19 07:34:51 +02:00
document.addEventListener('visibilitychange', () => {
if (!document.hidden) {
os.store.commit('clearBehindNotes');
}
}, false);
2018-10-22 11:23:20 +02:00
window.addEventListener('scroll', () => {
if (window.scrollY <= 8) {
os.store.commit('clearBehindNotes');
}
}, { passive: true });
2018-02-22 23:50:42 +01:00
const app = new Vue({
2018-11-13 19:05:13 +01:00
i18n: i18n(),
2018-04-29 10:17:15 +02:00
store: os.store,
2018-11-09 00:13:34 +01:00
data() {
return {
os: {
windows: os.windows
},
stream: os.stream,
2018-11-09 00:26:32 +01:00
instanceName: os.instanceName
2018-11-09 00:13:34 +01:00
};
},
methods: {
api: os.api,
getMeta: os.getMeta,
getMetaSync: os.getMetaSync,
2018-11-09 10:25:21 +01:00
signout: os.signout,
new(vm, props) {
const x = new vm({
parent: this,
propsData: props
}).$mount();
document.body.appendChild(x.$el);
return x;
},
2018-12-02 07:28:52 +01:00
dialog(opts) {
2018-12-03 12:26:46 +01:00
const vm = this.new(Dialog, opts);
2018-11-14 08:30:58 +01:00
return new Promise((res) => {
2018-12-02 12:10:53 +01:00
vm.$once('ok', result => res({ canceled: false, result }));
vm.$once('cancel', () => res({ canceled: true }));
2018-11-14 08:30:58 +01:00
});
}
2018-11-09 00:13:34 +01:00
},
2018-03-27 07:13:12 +02:00
router,
2018-02-22 23:50:42 +01:00
render: createEl => createEl(App)
});
os.app = app;
2018-02-22 15:53:07 +01:00
// マウント
app.$mount('#app');
2018-02-20 18:53:34 +01:00
//#region 更新チェック
const preventUpdate = os.store.state.device.preventUpdate;
if (!preventUpdate) {
setTimeout(() => {
checkForUpdate(app);
}, 3000);
}
//#endregion
2018-02-20 18:53:34 +01:00
return [app, os] as [Vue, MiOS];
2018-02-10 06:56:33 +01:00
};
2017-05-17 22:06:55 +02:00
// Deck mode
os.store.commit('device/set', {
key: 'inDeckMode',
value: os.store.getters.isSignedIn && os.store.state.device.deckMode
&& (document.location.pathname === '/' || window.performance.navigation.type === 1)
});
callback(launch, os);
2017-05-17 22:06:55 +02:00
});
2017-11-15 19:06:52 +01:00
};