diff --git a/src/client/app/common/scripts/check-for-update.ts b/src/client/app/common/scripts/check-for-update.ts index a4c59fd350..ac0b5d09c8 100644 --- a/src/client/app/common/scripts/check-for-update.ts +++ b/src/client/app/common/scripts/check-for-update.ts @@ -1,8 +1,7 @@ -import MiOS from '../../mios'; import { clientVersion as current } from '../../config'; -export default async function(mios: MiOS, force = false, silent = false) { - const meta = await mios.getMeta(force); +export default async function($root: any, force = false, silent = false) { + const meta = await $root.getMeta(force); const newer = meta.clientVersion; if (newer != current) { @@ -23,7 +22,7 @@ export default async function(mios: MiOS, force = false, silent = false) { } if (!silent) { - mios.apis.dialog({ + $root.$dialog({ title: '%i18n:common.update-available-title%', text: '%i18n:common.update-available%'.replace('{newer}', newer).replace('{current}', current) }); diff --git a/src/client/app/common/scripts/fuck-ad-block.ts b/src/client/app/common/scripts/fuck-ad-block.ts index 0c802f1648..b749d363f2 100644 --- a/src/client/app/common/scripts/fuck-ad-block.ts +++ b/src/client/app/common/scripts/fuck-ad-block.ts @@ -1,10 +1,10 @@ declare const fuckAdBlock: any; -export default (os) => { +export default ($root: any) => { require('fuckadblock'); function adBlockDetected() { - os.apis.dialog({ + $root.$dialog({ title: '%fa:exclamation-triangle%%i18n:common.adblock.detected%', text: '%i18n:common.adblock.warning%', actins: [{ diff --git a/src/client/app/common/scripts/note-mixin.ts b/src/client/app/common/scripts/note-mixin.ts index 6d86c70820..dd5098f4cd 100644 --- a/src/client/app/common/scripts/note-mixin.ts +++ b/src/client/app/common/scripts/note-mixin.ts @@ -88,7 +88,7 @@ export default (opts: Opts = {}) => ({ methods: { reply(viaKeyboard = false) { - this.$root.apis.post({ + this.$root.$post({ reply: this.appearNote, animation: !viaKeyboard, cb: () => { @@ -98,7 +98,7 @@ export default (opts: Opts = {}) => ({ }, renote(viaKeyboard = false) { - this.$root.apis.post({ + this.$root.$post({ renote: this.appearNote, animation: !viaKeyboard, cb: () => { diff --git a/src/client/app/common/views/components/api-settings.vue b/src/client/app/common/views/components/api-settings.vue index a6b74d7bb4..062218b3f4 100644 --- a/src/client/app/common/views/components/api-settings.vue +++ b/src/client/app/common/views/components/api-settings.vue @@ -50,7 +50,7 @@ export default Vue.extend({ methods: { regenerateToken() { - this.$root.apis.input({ + this.$input({ title: this.$t('enter-password'), type: 'password' }).then(password => { diff --git a/src/client/app/common/views/components/games/reversi/reversi.index.vue b/src/client/app/common/views/components/games/reversi/reversi.index.vue index e1372e5246..b82a60a360 100644 --- a/src/client/app/common/views/components/games/reversi/reversi.index.vue +++ b/src/client/app/common/views/components/games/reversi/reversi.index.vue @@ -100,7 +100,7 @@ export default Vue.extend({ }, match() { - this.$root.apis.input({ + this.$input({ title: this.$t('enter-username') }).then(username => { this.$root.api('users/show', { diff --git a/src/client/app/common/views/components/messaging-room.form.vue b/src/client/app/common/views/components/messaging-room.form.vue index d25c0c86db..97e2e16e4b 100644 --- a/src/client/app/common/views/components/messaging-room.form.vue +++ b/src/client/app/common/views/components/messaging-room.form.vue @@ -131,7 +131,7 @@ export default Vue.extend({ }, chooseFileFromDrive() { - this.$root.apis.chooseDriveFile({ + this.$chooseDriveFile({ multiple: false }).then(file => { this.file = file; diff --git a/src/client/app/common/views/components/password-settings.vue b/src/client/app/common/views/components/password-settings.vue index 048770401f..8661b51538 100644 --- a/src/client/app/common/views/components/password-settings.vue +++ b/src/client/app/common/views/components/password-settings.vue @@ -12,20 +12,20 @@ export default Vue.extend({ i18n: i18n('common/views/components/password-settings.vue'), methods: { reset() { - this.$root.apis.input({ + this.$input({ title: this.$t('enter-current-password'), type: 'password' }).then(currentPassword => { - this.$root.apis.input({ + this.$input({ title: this.$t('enter-new-password'), type: 'password' }).then(newPassword => { - this.$root.apis.input({ + this.$input({ title: this.$t('enter-new-password-again'), type: 'password' }).then(newPassword2 => { if (newPassword !== newPassword2) { - this.$root.apis.dialog({ + this.$dialog({ title: null, text: this.$t('not-match'), actions: [{ @@ -38,7 +38,7 @@ export default Vue.extend({ currentPasword: currentPassword, newPassword: newPassword }).then(() => { - this.$root.apis.notify(this.$t('changed')); + this.$notify(this.$t('changed')); }); }); }); diff --git a/src/client/app/common/views/widgets/slideshow.vue b/src/client/app/common/views/widgets/slideshow.vue index 58b19d0ab3..a454a41cde 100644 --- a/src/client/app/common/views/widgets/slideshow.vue +++ b/src/client/app/common/views/widgets/slideshow.vue @@ -114,7 +114,7 @@ export default define({ }); }, choose() { - this.$root.apis.chooseDriveFolder().then(folder => { + this.$chooseDriveFolder().then(folder => { this.props.folder = folder ? folder.id : null; this.save(); this.fetch(); diff --git a/src/client/app/desktop/api/choose-drive-file.ts b/src/client/app/desktop/api/choose-drive-file.ts deleted file mode 100644 index a362a1289b..0000000000 --- a/src/client/app/desktop/api/choose-drive-file.ts +++ /dev/null @@ -1,29 +0,0 @@ -import OS from '../../mios'; -import { url } from '../../config'; -import MkChooseFileFromDriveWindow from '../views/components/choose-file-from-drive-window.vue'; - -export default (os: OS) => opts => { - return new Promise((res, rej) => { - const o = opts || {}; - - if (document.body.clientWidth > 800) { - const w = os.new(MkChooseFileFromDriveWindow, { - title: o.title, - multiple: o.multiple, - initFolder: o.currentFolder - }); - w.$once('selected', file => { - res(file); - }); - document.body.appendChild(w.$el); - } else { - window['cb'] = file => { - res(file); - }; - - window.open(url + `/selectdrive?multiple=${o.multiple}`, - 'choose_drive_window', - 'height=500, width=800'); - } - }); -}; diff --git a/src/client/app/desktop/api/choose-drive-folder.ts b/src/client/app/desktop/api/choose-drive-folder.ts deleted file mode 100644 index 68dc7988b5..0000000000 --- a/src/client/app/desktop/api/choose-drive-folder.ts +++ /dev/null @@ -1,16 +0,0 @@ -import OS from '../../mios'; -import MkChooseFolderFromDriveWindow from '../views/components/choose-folder-from-drive-window.vue'; - -export default (os: OS) => opts => { - return new Promise((res, rej) => { - const o = opts || {}; - const w = os.new(MkChooseFolderFromDriveWindow, { - title: o.title, - initFolder: o.currentFolder - }); - w.$once('selected', folder => { - res(folder); - }); - document.body.appendChild(w.$el); - }); -}; diff --git a/src/client/app/desktop/api/contextmenu.ts b/src/client/app/desktop/api/contextmenu.ts deleted file mode 100644 index c92f087551..0000000000 --- a/src/client/app/desktop/api/contextmenu.ts +++ /dev/null @@ -1,15 +0,0 @@ -import OS from '../../mios'; -import Ctx from '../views/components/context-menu.vue'; - -export default (os: OS) => (e, menu, opts?) => { - const o = opts || {}; - const vm = os.new(Ctx, { - menu, - x: e.pageX - window.pageXOffset, - y: e.pageY - window.pageYOffset, - }); - vm.$once('closed', () => { - if (o.closed) o.closed(); - }); - document.body.appendChild(vm.$el); -}; diff --git a/src/client/app/desktop/api/dialog.ts b/src/client/app/desktop/api/dialog.ts deleted file mode 100644 index 23f35b7aa9..0000000000 --- a/src/client/app/desktop/api/dialog.ts +++ /dev/null @@ -1,18 +0,0 @@ -import OS from '../../mios'; -import Dialog from '../views/components/dialog.vue'; - -export default (os: OS) => opts => { - return new Promise((res, rej) => { - const o = opts || {}; - const d = os.new(Dialog, { - title: o.title, - text: o.text, - modal: o.modal, - buttons: o.actions - }); - d.$once('clicked', id => { - res(id); - }); - document.body.appendChild(d.$el); - }); -}; diff --git a/src/client/app/desktop/api/input.ts b/src/client/app/desktop/api/input.ts deleted file mode 100644 index bd7bfa0129..0000000000 --- a/src/client/app/desktop/api/input.ts +++ /dev/null @@ -1,19 +0,0 @@ -import OS from '../../mios'; -import InputDialog from '../views/components/input-dialog.vue'; - -export default (os: OS) => opts => { - return new Promise((res, rej) => { - const o = opts || {}; - const d = os.new(InputDialog, { - title: o.title, - placeholder: o.placeholder, - default: o.default, - type: o.type || 'text', - allowEmpty: o.allowEmpty - }); - d.$once('done', text => { - res(text); - }); - document.body.appendChild(d.$el); - }); -}; diff --git a/src/client/app/desktop/api/notify.ts b/src/client/app/desktop/api/notify.ts deleted file mode 100644 index 72e5827607..0000000000 --- a/src/client/app/desktop/api/notify.ts +++ /dev/null @@ -1,9 +0,0 @@ -import OS from '../../mios'; -import Notification from '../views/components/ui-notification.vue'; - -export default (os: OS) => message => { - const vm = os.new(Notification, { - message - }); - document.body.appendChild(vm.$el); -}; diff --git a/src/client/app/desktop/api/post.ts b/src/client/app/desktop/api/post.ts deleted file mode 100644 index 3ff9c5bb8c..0000000000 --- a/src/client/app/desktop/api/post.ts +++ /dev/null @@ -1,22 +0,0 @@ -import OS from '../../mios'; -import PostFormWindow from '../views/components/post-form-window.vue'; -import RenoteFormWindow from '../views/components/renote-form-window.vue'; - -export default (os: OS) => opts => { - const o = opts || {}; - if (o.renote) { - const vm = os.new(RenoteFormWindow, { - note: o.renote, - animation: o.animation == null ? true : o.animation - }); - if (o.cb) vm.$once('closed', o.cb); - document.body.appendChild(vm.$el); - } else { - const vm = os.new(PostFormWindow, { - reply: o.reply, - animation: o.animation == null ? true : o.animation - }); - if (o.cb) vm.$once('closed', o.cb); - document.body.appendChild(vm.$el); - } -}; diff --git a/src/client/app/desktop/api/update-avatar.ts b/src/client/app/desktop/api/update-avatar.ts index f08e8a2b4e..ae8b723ea6 100644 --- a/src/client/app/desktop/api/update-avatar.ts +++ b/src/client/app/desktop/api/update-avatar.ts @@ -1,15 +1,14 @@ -import OS from '../../mios'; import { apiUrl } from '../../config'; import CropWindow from '../views/components/crop-window.vue'; import ProgressDialog from '../views/components/progress-dialog.vue'; -export default (os: OS) => { +export default ($root: any) => { const cropImage = file => new Promise((resolve, reject) => { const regex = RegExp('\.(jpg|jpeg|png|gif|webp|bmp|tiff)$'); if (!regex.test(file.name) ) { - os.apis.dialog({ + $root.$dialog({ title: '%fa:info-circle% %i18n:desktop.invalid-filetype%', text: null, actions: [{ @@ -19,7 +18,7 @@ export default (os: OS) => { return reject('invalid-filetype'); } - const w = os.new(CropWindow, { + const w = $root.new(CropWindow, { image: file, title: '%i18n:desktop.avatar-crop-title%', aspectRatio: 1 / 1 @@ -27,14 +26,14 @@ export default (os: OS) => { w.$once('cropped', blob => { const data = new FormData(); - data.append('i', os.store.state.i.token); + data.append('i', $root.$store.state.i.token); data.append('file', blob, file.name + '.cropped.png'); - os.api('drive/folders/find', { + $root.api('drive/folders/find', { name: '%i18n:desktop.avatar%' }).then(avatarFolder => { if (avatarFolder.length === 0) { - os.api('drive/folders/create', { + $root.api('drive/folders/create', { name: '%i18n:desktop.avatar%' }).then(iconFolder => { resolve(upload(data, iconFolder)); @@ -55,7 +54,7 @@ export default (os: OS) => { }); const upload = (data, folder) => new Promise((resolve, reject) => { - const dialog = os.new(ProgressDialog, { + const dialog = $root.new(ProgressDialog, { title: '%i18n:desktop.uploading-avatar%' }); document.body.appendChild(dialog.$el); @@ -79,19 +78,19 @@ export default (os: OS) => { }); const setAvatar = file => { - return os.api('i/update', { + return $root.api('i/update', { avatarId: file.id }).then(i => { - os.store.commit('updateIKeyValue', { + $root.$store.commit('updateIKeyValue', { key: 'avatarId', value: i.avatarId }); - os.store.commit('updateIKeyValue', { + $root.$store.commit('updateIKeyValue', { key: 'avatarUrl', value: i.avatarUrl }); - os.apis.dialog({ + $root.$dialog({ title: '%fa:info-circle% %i18n:desktop.avatar-updated%', text: null, actions: [{ @@ -106,7 +105,7 @@ export default (os: OS) => { return (file = null) => { const selectedFile = file ? Promise.resolve(file) - : os.apis.chooseDriveFile({ + : $root.$chooseDriveFile({ multiple: false, title: '%fa:image% %i18n:desktop.choose-avatar%' }); diff --git a/src/client/app/desktop/api/update-banner.ts b/src/client/app/desktop/api/update-banner.ts index 42c9d69349..c338d4e95c 100644 --- a/src/client/app/desktop/api/update-banner.ts +++ b/src/client/app/desktop/api/update-banner.ts @@ -1,15 +1,14 @@ -import OS from '../../mios'; import { apiUrl } from '../../config'; import CropWindow from '../views/components/crop-window.vue'; import ProgressDialog from '../views/components/progress-dialog.vue'; -export default (os: OS) => { +export default ($root: any) => { const cropImage = file => new Promise((resolve, reject) => { const regex = RegExp('\.(jpg|jpeg|png|gif|webp|bmp|tiff)$'); if (!regex.test(file.name) ) { - os.apis.dialog({ + $root.dialog({ title: '%fa:info-circle% %i18n:desktop.invalid-filetype%', text: null, actions: [{ @@ -19,7 +18,7 @@ export default (os: OS) => { return reject('invalid-filetype'); } - const w = os.new(CropWindow, { + const w = $root.new(CropWindow, { image: file, title: '%i18n:desktop.banner-crop-title%', aspectRatio: 16 / 9 @@ -27,14 +26,14 @@ export default (os: OS) => { w.$once('cropped', blob => { const data = new FormData(); - data.append('i', os.store.state.i.token); + data.append('i', $root.$store.state.i.token); data.append('file', blob, file.name + '.cropped.png'); - os.api('drive/folders/find', { + $root.api('drive/folders/find', { name: '%i18n:desktop.banner%' }).then(bannerFolder => { if (bannerFolder.length === 0) { - os.api('drive/folders/create', { + $root.api('drive/folders/create', { name: '%i18n:desktop.banner%' }).then(iconFolder => { resolve(upload(data, iconFolder)); @@ -55,7 +54,7 @@ export default (os: OS) => { }); const upload = (data, folder) => new Promise((resolve, reject) => { - const dialog = os.new(ProgressDialog, { + const dialog = $root.new(ProgressDialog, { title: '%i18n:desktop.uploading-banner%' }); document.body.appendChild(dialog.$el); @@ -79,19 +78,19 @@ export default (os: OS) => { }); const setBanner = file => { - return os.api('i/update', { + return $root.api('i/update', { bannerId: file.id }).then(i => { - os.store.commit('updateIKeyValue', { + $root.$store.commit('updateIKeyValue', { key: 'bannerId', value: i.bannerId }); - os.store.commit('updateIKeyValue', { + $root.$store.commit('updateIKeyValue', { key: 'bannerUrl', value: i.bannerUrl }); - os.apis.dialog({ + $root.$dialog({ title: '%fa:info-circle% %i18n:desktop.banner-updated%', text: null, actions: [{ @@ -106,7 +105,7 @@ export default (os: OS) => { return (file = null) => { const selectedFile = file ? Promise.resolve(file) - : os.apis.chooseDriveFile({ + : $root.$chooseDriveFile({ multiple: false, title: '%fa:image% %i18n:desktop.choose-banner%' }); diff --git a/src/client/app/desktop/script.ts b/src/client/app/desktop/script.ts index ca9771e2fe..f2d27fa16e 100644 --- a/src/client/app/desktop/script.ts +++ b/src/client/app/desktop/script.ts @@ -2,6 +2,7 @@ * Desktop Client */ +import Vue from 'vue'; import VueRouter from 'vue-router'; // Style @@ -11,15 +12,6 @@ import init from '../init'; import fuckAdBlock from '../common/scripts/fuck-ad-block'; import composeNotification from '../common/scripts/compose-notification'; -import chooseDriveFolder from './api/choose-drive-folder'; -import chooseDriveFile from './api/choose-drive-file'; -import dialog from './api/dialog'; -import input from './api/input'; -import post from './api/post'; -import notify from './api/notify'; -import updateAvatar from './api/update-avatar'; -import updateBanner from './api/update-banner'; - import MkIndex from './views/pages/index.vue'; import MkHome from './views/pages/home.vue'; import MkDeck from './views/pages/deck/deck.vue'; @@ -36,12 +28,131 @@ import MkTag from './views/pages/tag.vue'; import MkReversi from './views/pages/games/reversi.vue'; import MkShare from './views/pages/share.vue'; import MkFollow from '../common/views/pages/follow.vue'; + +import Ctx from './views/components/context-menu.vue'; +import PostFormWindow from './views/components/post-form-window.vue'; +import RenoteFormWindow from './views/components/renote-form-window.vue'; +import MkChooseFileFromDriveWindow from './views/components/choose-file-from-drive-window.vue'; +import MkChooseFolderFromDriveWindow from './views/components/choose-folder-from-drive-window.vue'; +import Dialog from './views/components/dialog.vue'; +import InputDialog from './views/components/input-dialog.vue'; +import Notification from './views/components/ui-notification.vue'; + +import { url } from '../config'; import MiOS from '../mios'; /** * init */ init(async (launch) => { + Vue.mixin({ + methods: { + $contextmenu(e, menu, opts?) { + const o = opts || {}; + const vm = this.$root.new(Ctx, { + menu, + x: e.pageX - window.pageXOffset, + y: e.pageY - window.pageYOffset, + }); + vm.$once('closed', () => { + if (o.closed) o.closed(); + }); + }, + + $post(opts) { + const o = opts || {}; + if (o.renote) { + const vm = this.$root.new(RenoteFormWindow, { + note: o.renote, + animation: o.animation == null ? true : o.animation + }); + if (o.cb) vm.$once('closed', o.cb); + } else { + const vm = this.$root.new(PostFormWindow, { + reply: o.reply, + animation: o.animation == null ? true : o.animation + }); + if (o.cb) vm.$once('closed', o.cb); + } + }, + + $chooseDriveFile(opts) { + return new Promise((res, rej) => { + const o = opts || {}; + + if (document.body.clientWidth > 800) { + const w = this.$root.new(MkChooseFileFromDriveWindow, { + title: o.title, + multiple: o.multiple, + initFolder: o.currentFolder + }); + w.$once('selected', file => { + res(file); + }); + } else { + window['cb'] = file => { + res(file); + }; + + window.open(url + `/selectdrive?multiple=${o.multiple}`, + 'choose_drive_window', + 'height=500, width=800'); + } + }); + }, + + $chooseDriveFolder(opts) { + return new Promise((res, rej) => { + const o = opts || {}; + const w = this.$root.new(MkChooseFolderFromDriveWindow, { + title: o.title, + initFolder: o.currentFolder + }); + w.$once('selected', folder => { + res(folder); + }); + }); + }, + + $dialog(opts) { + return new Promise((res, rej) => { + const o = opts || {}; + const d = this.$root.new(Dialog, { + title: o.title, + text: o.text, + modal: o.modal, + buttons: o.actions + }); + d.$once('clicked', id => { + res(id); + }); + }); + }, + + $input(opts) { + return new Promise((res, rej) => { + const o = opts || {}; + const d = this.$root.new(InputDialog, { + title: o.title, + placeholder: o.placeholder, + default: o.default, + type: o.type || 'text', + allowEmpty: o.allowEmpty + }); + d.$once('done', text => { + res(text); + }); + }); + }, + + $notify(message) { + this.$root.new(Notification, { + message + }); + } + } + }); + // Register directives require('./views/directives'); @@ -75,22 +186,13 @@ init(async (launch) => { }); // Launch the app - const [, os] = launch(router, os => ({ - chooseDriveFolder: chooseDriveFolder(os), - chooseDriveFile: chooseDriveFile(os), - dialog: dialog(os), - input: input(os), - post: post(os), - notify: notify(os), - updateAvatar: updateAvatar(os), - updateBanner: updateBanner(os) - })); + const [app, os] = launch(router); if (os.store.getters.isSignedIn) { /** * Fuck AD Block */ - fuckAdBlock(os); + fuckAdBlock(app); } /** diff --git a/src/client/app/desktop/views/components/drive.file.vue b/src/client/app/desktop/views/components/drive.file.vue index c403418b21..7840d7e748 100644 --- a/src/client/app/desktop/views/components/drive.file.vue +++ b/src/client/app/desktop/views/components/drive.file.vue @@ -35,7 +35,6 @@ import Vue from 'vue'; import i18n from '../../../i18n'; import * as anime from 'animejs'; -import contextmenu from '../../api/contextmenu'; import copyToClipboard from '../../../common/scripts/copy-to-clipboard'; export default Vue.extend({ @@ -70,7 +69,7 @@ export default Vue.extend({ onContextmenu(e) { this.isContextmenuShowing = true; - contextmenu((this as any).os)(e, [{ + this.$contextmenu(e, [{ type: 'item', text: this.$t('contextmenu.rename'), icon: 'i-cursor', @@ -116,10 +115,10 @@ export default Vue.extend({ action: this.addApp }] }*/], { - closed: () => { - this.isContextmenuShowing = false; - } - }); + closed: () => { + this.isContextmenuShowing = false; + } + }); }, onDragstart(e) { @@ -149,7 +148,7 @@ export default Vue.extend({ }, rename() { - this.$root.apis.input({ + this.$input({ title: this.$t('contextmenu.rename-file'), placeholder: this.$t('contextmenu.input-new-file-name'), default: this.file.name, @@ -171,7 +170,7 @@ export default Vue.extend({ copyUrl() { copyToClipboard(this.file.url); - this.$root.apis.dialog({ + this.$dialog({ title: this.$t('contextmenu.copied'), text: this.$t('contextmenu.copied-url-to-clipboard'), actions: [{ @@ -181,11 +180,11 @@ export default Vue.extend({ }, setAsAvatar() { - this.$root.apis.updateAvatar(this.file); + this.$updateAvatar(this.file); }, setAsBanner() { - this.$root.apis.updateBanner(this.file); + this.$updateBanner(this.file); }, addApp() { diff --git a/src/client/app/desktop/views/components/drive.folder.vue b/src/client/app/desktop/views/components/drive.folder.vue index 2f595ddbe3..fe9bad2c28 100644 --- a/src/client/app/desktop/views/components/drive.folder.vue +++ b/src/client/app/desktop/views/components/drive.folder.vue @@ -26,7 +26,6 @@