mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-03 23:14:13 +00:00 
			
		
		
		
	Refactor client (#3178)
* wip * wip * wip * wip * wip * wip * wip * wip * wip * wip
This commit is contained in:
		
							parent
							
								
									5d882dc3df
								
							
						
					
					
						commit
						3f79c9ae49
					
				
					 52 changed files with 328 additions and 421 deletions
				
			
		| 
						 | 
					@ -1,8 +1,7 @@
 | 
				
			||||||
import MiOS from '../../mios';
 | 
					 | 
				
			||||||
import { clientVersion as current } from '../../config';
 | 
					import { clientVersion as current } from '../../config';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default async function(mios: MiOS, force = false, silent = false) {
 | 
					export default async function($root: any, force = false, silent = false) {
 | 
				
			||||||
	const meta = await mios.getMeta(force);
 | 
						const meta = await $root.getMeta(force);
 | 
				
			||||||
	const newer = meta.clientVersion;
 | 
						const newer = meta.clientVersion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (newer != current) {
 | 
						if (newer != current) {
 | 
				
			||||||
| 
						 | 
					@ -23,7 +22,7 @@ export default async function(mios: MiOS, force = false, silent = false) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!silent) {
 | 
							if (!silent) {
 | 
				
			||||||
			mios.apis.dialog({
 | 
								$root.$dialog({
 | 
				
			||||||
				title: '%i18n:common.update-available-title%',
 | 
									title: '%i18n:common.update-available-title%',
 | 
				
			||||||
				text: '%i18n:common.update-available%'.replace('{newer}', newer).replace('{current}', current)
 | 
									text: '%i18n:common.update-available%'.replace('{newer}', newer).replace('{current}', current)
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,10 @@
 | 
				
			||||||
declare const fuckAdBlock: any;
 | 
					declare const fuckAdBlock: any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default (os) => {
 | 
					export default ($root: any) => {
 | 
				
			||||||
	require('fuckadblock');
 | 
						require('fuckadblock');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function adBlockDetected() {
 | 
						function adBlockDetected() {
 | 
				
			||||||
		os.apis.dialog({
 | 
							$root.$dialog({
 | 
				
			||||||
			title: '%fa:exclamation-triangle%%i18n:common.adblock.detected%',
 | 
								title: '%fa:exclamation-triangle%%i18n:common.adblock.detected%',
 | 
				
			||||||
			text: '%i18n:common.adblock.warning%',
 | 
								text: '%i18n:common.adblock.warning%',
 | 
				
			||||||
			actins: [{
 | 
								actins: [{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,7 +88,7 @@ export default (opts: Opts = {}) => ({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		reply(viaKeyboard = false) {
 | 
							reply(viaKeyboard = false) {
 | 
				
			||||||
			this.$root.apis.post({
 | 
								this.$root.$post({
 | 
				
			||||||
				reply: this.appearNote,
 | 
									reply: this.appearNote,
 | 
				
			||||||
				animation: !viaKeyboard,
 | 
									animation: !viaKeyboard,
 | 
				
			||||||
				cb: () => {
 | 
									cb: () => {
 | 
				
			||||||
| 
						 | 
					@ -98,7 +98,7 @@ export default (opts: Opts = {}) => ({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		renote(viaKeyboard = false) {
 | 
							renote(viaKeyboard = false) {
 | 
				
			||||||
			this.$root.apis.post({
 | 
								this.$root.$post({
 | 
				
			||||||
				renote: this.appearNote,
 | 
									renote: this.appearNote,
 | 
				
			||||||
				animation: !viaKeyboard,
 | 
									animation: !viaKeyboard,
 | 
				
			||||||
				cb: () => {
 | 
									cb: () => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,7 +50,7 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		regenerateToken() {
 | 
							regenerateToken() {
 | 
				
			||||||
			this.$root.apis.input({
 | 
								this.$input({
 | 
				
			||||||
				title: this.$t('enter-password'),
 | 
									title: this.$t('enter-password'),
 | 
				
			||||||
				type: 'password'
 | 
									type: 'password'
 | 
				
			||||||
			}).then(password => {
 | 
								}).then(password => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,7 +100,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		match() {
 | 
							match() {
 | 
				
			||||||
			this.$root.apis.input({
 | 
								this.$input({
 | 
				
			||||||
				title: this.$t('enter-username')
 | 
									title: this.$t('enter-username')
 | 
				
			||||||
			}).then(username => {
 | 
								}).then(username => {
 | 
				
			||||||
				this.$root.api('users/show', {
 | 
									this.$root.api('users/show', {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,7 +131,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		chooseFileFromDrive() {
 | 
							chooseFileFromDrive() {
 | 
				
			||||||
			this.$root.apis.chooseDriveFile({
 | 
								this.$chooseDriveFile({
 | 
				
			||||||
				multiple: false
 | 
									multiple: false
 | 
				
			||||||
			}).then(file => {
 | 
								}).then(file => {
 | 
				
			||||||
				this.file = file;
 | 
									this.file = file;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,20 +12,20 @@ export default Vue.extend({
 | 
				
			||||||
	i18n: i18n('common/views/components/password-settings.vue'),
 | 
						i18n: i18n('common/views/components/password-settings.vue'),
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		reset() {
 | 
							reset() {
 | 
				
			||||||
			this.$root.apis.input({
 | 
								this.$input({
 | 
				
			||||||
				title: this.$t('enter-current-password'),
 | 
									title: this.$t('enter-current-password'),
 | 
				
			||||||
				type: 'password'
 | 
									type: 'password'
 | 
				
			||||||
			}).then(currentPassword => {
 | 
								}).then(currentPassword => {
 | 
				
			||||||
				this.$root.apis.input({
 | 
									this.$input({
 | 
				
			||||||
					title: this.$t('enter-new-password'),
 | 
										title: this.$t('enter-new-password'),
 | 
				
			||||||
					type: 'password'
 | 
										type: 'password'
 | 
				
			||||||
				}).then(newPassword => {
 | 
									}).then(newPassword => {
 | 
				
			||||||
					this.$root.apis.input({
 | 
										this.$input({
 | 
				
			||||||
						title: this.$t('enter-new-password-again'),
 | 
											title: this.$t('enter-new-password-again'),
 | 
				
			||||||
						type: 'password'
 | 
											type: 'password'
 | 
				
			||||||
					}).then(newPassword2 => {
 | 
										}).then(newPassword2 => {
 | 
				
			||||||
						if (newPassword !== newPassword2) {
 | 
											if (newPassword !== newPassword2) {
 | 
				
			||||||
							this.$root.apis.dialog({
 | 
												this.$dialog({
 | 
				
			||||||
								title: null,
 | 
													title: null,
 | 
				
			||||||
								text: this.$t('not-match'),
 | 
													text: this.$t('not-match'),
 | 
				
			||||||
								actions: [{
 | 
													actions: [{
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,7 @@ export default Vue.extend({
 | 
				
			||||||
							currentPasword: currentPassword,
 | 
												currentPasword: currentPassword,
 | 
				
			||||||
							newPassword: newPassword
 | 
												newPassword: newPassword
 | 
				
			||||||
						}).then(() => {
 | 
											}).then(() => {
 | 
				
			||||||
							this.$root.apis.notify(this.$t('changed'));
 | 
												this.$notify(this.$t('changed'));
 | 
				
			||||||
						});
 | 
											});
 | 
				
			||||||
					});
 | 
										});
 | 
				
			||||||
				});
 | 
									});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -114,7 +114,7 @@ export default define({
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		choose() {
 | 
							choose() {
 | 
				
			||||||
			this.$root.apis.chooseDriveFolder().then(folder => {
 | 
								this.$chooseDriveFolder().then(folder => {
 | 
				
			||||||
				this.props.folder = folder ? folder.id : null;
 | 
									this.props.folder = folder ? folder.id : null;
 | 
				
			||||||
				this.save();
 | 
									this.save();
 | 
				
			||||||
				this.fetch();
 | 
									this.fetch();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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');
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,18 +0,0 @@
 | 
				
			||||||
import OS from '../../mios';
 | 
					 | 
				
			||||||
import Dialog from '../views/components/dialog.vue';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default (os: OS) => opts => {
 | 
					 | 
				
			||||||
	return new Promise<string>((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);
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,19 +0,0 @@
 | 
				
			||||||
import OS from '../../mios';
 | 
					 | 
				
			||||||
import InputDialog from '../views/components/input-dialog.vue';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default (os: OS) => opts => {
 | 
					 | 
				
			||||||
	return new Promise<string>((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);
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,15 +1,14 @@
 | 
				
			||||||
import OS from '../../mios';
 | 
					 | 
				
			||||||
import { apiUrl } from '../../config';
 | 
					import { apiUrl } from '../../config';
 | 
				
			||||||
import CropWindow from '../views/components/crop-window.vue';
 | 
					import CropWindow from '../views/components/crop-window.vue';
 | 
				
			||||||
import ProgressDialog from '../views/components/progress-dialog.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 cropImage = file => new Promise((resolve, reject) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const regex = RegExp('\.(jpg|jpeg|png|gif|webp|bmp|tiff)$');
 | 
							const regex = RegExp('\.(jpg|jpeg|png|gif|webp|bmp|tiff)$');
 | 
				
			||||||
		if (!regex.test(file.name) ) {
 | 
							if (!regex.test(file.name) ) {
 | 
				
			||||||
			os.apis.dialog({
 | 
								$root.$dialog({
 | 
				
			||||||
				title: '%fa:info-circle% %i18n:desktop.invalid-filetype%',
 | 
									title: '%fa:info-circle% %i18n:desktop.invalid-filetype%',
 | 
				
			||||||
				text: null,
 | 
									text: null,
 | 
				
			||||||
				actions: [{
 | 
									actions: [{
 | 
				
			||||||
| 
						 | 
					@ -19,7 +18,7 @@ export default (os: OS) => {
 | 
				
			||||||
			return reject('invalid-filetype');
 | 
								return reject('invalid-filetype');
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const w = os.new(CropWindow, {
 | 
							const w = $root.new(CropWindow, {
 | 
				
			||||||
			image: file,
 | 
								image: file,
 | 
				
			||||||
			title: '%i18n:desktop.avatar-crop-title%',
 | 
								title: '%i18n:desktop.avatar-crop-title%',
 | 
				
			||||||
			aspectRatio: 1 / 1
 | 
								aspectRatio: 1 / 1
 | 
				
			||||||
| 
						 | 
					@ -27,14 +26,14 @@ export default (os: OS) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		w.$once('cropped', blob => {
 | 
							w.$once('cropped', blob => {
 | 
				
			||||||
			const data = new FormData();
 | 
								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');
 | 
								data.append('file', blob, file.name + '.cropped.png');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			os.api('drive/folders/find', {
 | 
								$root.api('drive/folders/find', {
 | 
				
			||||||
				name: '%i18n:desktop.avatar%'
 | 
									name: '%i18n:desktop.avatar%'
 | 
				
			||||||
			}).then(avatarFolder => {
 | 
								}).then(avatarFolder => {
 | 
				
			||||||
				if (avatarFolder.length === 0) {
 | 
									if (avatarFolder.length === 0) {
 | 
				
			||||||
					os.api('drive/folders/create', {
 | 
										$root.api('drive/folders/create', {
 | 
				
			||||||
						name: '%i18n:desktop.avatar%'
 | 
											name: '%i18n:desktop.avatar%'
 | 
				
			||||||
					}).then(iconFolder => {
 | 
										}).then(iconFolder => {
 | 
				
			||||||
						resolve(upload(data, iconFolder));
 | 
											resolve(upload(data, iconFolder));
 | 
				
			||||||
| 
						 | 
					@ -55,7 +54,7 @@ export default (os: OS) => {
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const upload = (data, folder) => new Promise((resolve, reject) => {
 | 
						const upload = (data, folder) => new Promise((resolve, reject) => {
 | 
				
			||||||
		const dialog = os.new(ProgressDialog, {
 | 
							const dialog = $root.new(ProgressDialog, {
 | 
				
			||||||
			title: '%i18n:desktop.uploading-avatar%'
 | 
								title: '%i18n:desktop.uploading-avatar%'
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
		document.body.appendChild(dialog.$el);
 | 
							document.body.appendChild(dialog.$el);
 | 
				
			||||||
| 
						 | 
					@ -79,19 +78,19 @@ export default (os: OS) => {
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const setAvatar = file => {
 | 
						const setAvatar = file => {
 | 
				
			||||||
		return os.api('i/update', {
 | 
							return $root.api('i/update', {
 | 
				
			||||||
			avatarId: file.id
 | 
								avatarId: file.id
 | 
				
			||||||
		}).then(i => {
 | 
							}).then(i => {
 | 
				
			||||||
			os.store.commit('updateIKeyValue', {
 | 
								$root.$store.commit('updateIKeyValue', {
 | 
				
			||||||
				key: 'avatarId',
 | 
									key: 'avatarId',
 | 
				
			||||||
				value: i.avatarId
 | 
									value: i.avatarId
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
			os.store.commit('updateIKeyValue', {
 | 
								$root.$store.commit('updateIKeyValue', {
 | 
				
			||||||
				key: 'avatarUrl',
 | 
									key: 'avatarUrl',
 | 
				
			||||||
				value: i.avatarUrl
 | 
									value: i.avatarUrl
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			os.apis.dialog({
 | 
								$root.$dialog({
 | 
				
			||||||
				title: '%fa:info-circle% %i18n:desktop.avatar-updated%',
 | 
									title: '%fa:info-circle% %i18n:desktop.avatar-updated%',
 | 
				
			||||||
				text: null,
 | 
									text: null,
 | 
				
			||||||
				actions: [{
 | 
									actions: [{
 | 
				
			||||||
| 
						 | 
					@ -106,7 +105,7 @@ export default (os: OS) => {
 | 
				
			||||||
	return (file = null) => {
 | 
						return (file = null) => {
 | 
				
			||||||
		const selectedFile = file
 | 
							const selectedFile = file
 | 
				
			||||||
			? Promise.resolve(file)
 | 
								? Promise.resolve(file)
 | 
				
			||||||
			: os.apis.chooseDriveFile({
 | 
								: $root.$chooseDriveFile({
 | 
				
			||||||
				multiple: false,
 | 
									multiple: false,
 | 
				
			||||||
				title: '%fa:image% %i18n:desktop.choose-avatar%'
 | 
									title: '%fa:image% %i18n:desktop.choose-avatar%'
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,15 +1,14 @@
 | 
				
			||||||
import OS from '../../mios';
 | 
					 | 
				
			||||||
import { apiUrl } from '../../config';
 | 
					import { apiUrl } from '../../config';
 | 
				
			||||||
import CropWindow from '../views/components/crop-window.vue';
 | 
					import CropWindow from '../views/components/crop-window.vue';
 | 
				
			||||||
import ProgressDialog from '../views/components/progress-dialog.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 cropImage = file => new Promise((resolve, reject) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const regex = RegExp('\.(jpg|jpeg|png|gif|webp|bmp|tiff)$');
 | 
							const regex = RegExp('\.(jpg|jpeg|png|gif|webp|bmp|tiff)$');
 | 
				
			||||||
		if (!regex.test(file.name) ) {
 | 
							if (!regex.test(file.name) ) {
 | 
				
			||||||
			os.apis.dialog({
 | 
								$root.dialog({
 | 
				
			||||||
				title: '%fa:info-circle% %i18n:desktop.invalid-filetype%',
 | 
									title: '%fa:info-circle% %i18n:desktop.invalid-filetype%',
 | 
				
			||||||
				text: null,
 | 
									text: null,
 | 
				
			||||||
				actions: [{
 | 
									actions: [{
 | 
				
			||||||
| 
						 | 
					@ -19,7 +18,7 @@ export default (os: OS) => {
 | 
				
			||||||
			return reject('invalid-filetype');
 | 
								return reject('invalid-filetype');
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const w = os.new(CropWindow, {
 | 
							const w = $root.new(CropWindow, {
 | 
				
			||||||
			image: file,
 | 
								image: file,
 | 
				
			||||||
			title: '%i18n:desktop.banner-crop-title%',
 | 
								title: '%i18n:desktop.banner-crop-title%',
 | 
				
			||||||
			aspectRatio: 16 / 9
 | 
								aspectRatio: 16 / 9
 | 
				
			||||||
| 
						 | 
					@ -27,14 +26,14 @@ export default (os: OS) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		w.$once('cropped', blob => {
 | 
							w.$once('cropped', blob => {
 | 
				
			||||||
			const data = new FormData();
 | 
								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');
 | 
								data.append('file', blob, file.name + '.cropped.png');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			os.api('drive/folders/find', {
 | 
								$root.api('drive/folders/find', {
 | 
				
			||||||
				name: '%i18n:desktop.banner%'
 | 
									name: '%i18n:desktop.banner%'
 | 
				
			||||||
			}).then(bannerFolder => {
 | 
								}).then(bannerFolder => {
 | 
				
			||||||
				if (bannerFolder.length === 0) {
 | 
									if (bannerFolder.length === 0) {
 | 
				
			||||||
					os.api('drive/folders/create', {
 | 
										$root.api('drive/folders/create', {
 | 
				
			||||||
						name: '%i18n:desktop.banner%'
 | 
											name: '%i18n:desktop.banner%'
 | 
				
			||||||
					}).then(iconFolder => {
 | 
										}).then(iconFolder => {
 | 
				
			||||||
						resolve(upload(data, iconFolder));
 | 
											resolve(upload(data, iconFolder));
 | 
				
			||||||
| 
						 | 
					@ -55,7 +54,7 @@ export default (os: OS) => {
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const upload = (data, folder) => new Promise((resolve, reject) => {
 | 
						const upload = (data, folder) => new Promise((resolve, reject) => {
 | 
				
			||||||
		const dialog = os.new(ProgressDialog, {
 | 
							const dialog = $root.new(ProgressDialog, {
 | 
				
			||||||
			title: '%i18n:desktop.uploading-banner%'
 | 
								title: '%i18n:desktop.uploading-banner%'
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
		document.body.appendChild(dialog.$el);
 | 
							document.body.appendChild(dialog.$el);
 | 
				
			||||||
| 
						 | 
					@ -79,19 +78,19 @@ export default (os: OS) => {
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const setBanner = file => {
 | 
						const setBanner = file => {
 | 
				
			||||||
		return os.api('i/update', {
 | 
							return $root.api('i/update', {
 | 
				
			||||||
			bannerId: file.id
 | 
								bannerId: file.id
 | 
				
			||||||
		}).then(i => {
 | 
							}).then(i => {
 | 
				
			||||||
			os.store.commit('updateIKeyValue', {
 | 
								$root.$store.commit('updateIKeyValue', {
 | 
				
			||||||
				key: 'bannerId',
 | 
									key: 'bannerId',
 | 
				
			||||||
				value: i.bannerId
 | 
									value: i.bannerId
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
			os.store.commit('updateIKeyValue', {
 | 
								$root.$store.commit('updateIKeyValue', {
 | 
				
			||||||
				key: 'bannerUrl',
 | 
									key: 'bannerUrl',
 | 
				
			||||||
				value: i.bannerUrl
 | 
									value: i.bannerUrl
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			os.apis.dialog({
 | 
								$root.$dialog({
 | 
				
			||||||
				title: '%fa:info-circle% %i18n:desktop.banner-updated%',
 | 
									title: '%fa:info-circle% %i18n:desktop.banner-updated%',
 | 
				
			||||||
				text: null,
 | 
									text: null,
 | 
				
			||||||
				actions: [{
 | 
									actions: [{
 | 
				
			||||||
| 
						 | 
					@ -106,7 +105,7 @@ export default (os: OS) => {
 | 
				
			||||||
	return (file = null) => {
 | 
						return (file = null) => {
 | 
				
			||||||
		const selectedFile = file
 | 
							const selectedFile = file
 | 
				
			||||||
			? Promise.resolve(file)
 | 
								? Promise.resolve(file)
 | 
				
			||||||
			: os.apis.chooseDriveFile({
 | 
								: $root.$chooseDriveFile({
 | 
				
			||||||
				multiple: false,
 | 
									multiple: false,
 | 
				
			||||||
				title: '%fa:image% %i18n:desktop.choose-banner%'
 | 
									title: '%fa:image% %i18n:desktop.choose-banner%'
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
 * Desktop Client
 | 
					 * Desktop Client
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Vue from 'vue';
 | 
				
			||||||
import VueRouter from 'vue-router';
 | 
					import VueRouter from 'vue-router';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Style
 | 
					// Style
 | 
				
			||||||
| 
						 | 
					@ -11,15 +12,6 @@ import init from '../init';
 | 
				
			||||||
import fuckAdBlock from '../common/scripts/fuck-ad-block';
 | 
					import fuckAdBlock from '../common/scripts/fuck-ad-block';
 | 
				
			||||||
import composeNotification from '../common/scripts/compose-notification';
 | 
					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 MkIndex from './views/pages/index.vue';
 | 
				
			||||||
import MkHome from './views/pages/home.vue';
 | 
					import MkHome from './views/pages/home.vue';
 | 
				
			||||||
import MkDeck from './views/pages/deck/deck.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 MkReversi from './views/pages/games/reversi.vue';
 | 
				
			||||||
import MkShare from './views/pages/share.vue';
 | 
					import MkShare from './views/pages/share.vue';
 | 
				
			||||||
import MkFollow from '../common/views/pages/follow.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';
 | 
					import MiOS from '../mios';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * init
 | 
					 * init
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
init(async (launch) => {
 | 
					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<string>((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<string>((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
 | 
						// Register directives
 | 
				
			||||||
	require('./views/directives');
 | 
						require('./views/directives');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,22 +186,13 @@ init(async (launch) => {
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Launch the app
 | 
						// Launch the app
 | 
				
			||||||
	const [, os] = launch(router, os => ({
 | 
						const [app, os] = launch(router);
 | 
				
			||||||
		chooseDriveFolder: chooseDriveFolder(os),
 | 
					 | 
				
			||||||
		chooseDriveFile: chooseDriveFile(os),
 | 
					 | 
				
			||||||
		dialog: dialog(os),
 | 
					 | 
				
			||||||
		input: input(os),
 | 
					 | 
				
			||||||
		post: post(os),
 | 
					 | 
				
			||||||
		notify: notify(os),
 | 
					 | 
				
			||||||
		updateAvatar: updateAvatar(os),
 | 
					 | 
				
			||||||
		updateBanner: updateBanner(os)
 | 
					 | 
				
			||||||
	}));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (os.store.getters.isSignedIn) {
 | 
						if (os.store.getters.isSignedIn) {
 | 
				
			||||||
		/**
 | 
							/**
 | 
				
			||||||
		 * Fuck AD Block
 | 
							 * Fuck AD Block
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		fuckAdBlock(os);
 | 
							fuckAdBlock(app);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,6 @@
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
import i18n from '../../../i18n';
 | 
					import i18n from '../../../i18n';
 | 
				
			||||||
import * as anime from 'animejs';
 | 
					import * as anime from 'animejs';
 | 
				
			||||||
import contextmenu from '../../api/contextmenu';
 | 
					 | 
				
			||||||
import copyToClipboard from '../../../common/scripts/copy-to-clipboard';
 | 
					import copyToClipboard from '../../../common/scripts/copy-to-clipboard';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
| 
						 | 
					@ -70,7 +69,7 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onContextmenu(e) {
 | 
							onContextmenu(e) {
 | 
				
			||||||
			this.isContextmenuShowing = true;
 | 
								this.isContextmenuShowing = true;
 | 
				
			||||||
			contextmenu((this as any).os)(e, [{
 | 
								this.$contextmenu(e, [{
 | 
				
			||||||
				type: 'item',
 | 
									type: 'item',
 | 
				
			||||||
				text: this.$t('contextmenu.rename'),
 | 
									text: this.$t('contextmenu.rename'),
 | 
				
			||||||
				icon: 'i-cursor',
 | 
									icon: 'i-cursor',
 | 
				
			||||||
| 
						 | 
					@ -149,7 +148,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rename() {
 | 
							rename() {
 | 
				
			||||||
			this.$root.apis.input({
 | 
								this.$input({
 | 
				
			||||||
				title: this.$t('contextmenu.rename-file'),
 | 
									title: this.$t('contextmenu.rename-file'),
 | 
				
			||||||
				placeholder: this.$t('contextmenu.input-new-file-name'),
 | 
									placeholder: this.$t('contextmenu.input-new-file-name'),
 | 
				
			||||||
				default: this.file.name,
 | 
									default: this.file.name,
 | 
				
			||||||
| 
						 | 
					@ -171,7 +170,7 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		copyUrl() {
 | 
							copyUrl() {
 | 
				
			||||||
			copyToClipboard(this.file.url);
 | 
								copyToClipboard(this.file.url);
 | 
				
			||||||
			this.$root.apis.dialog({
 | 
								this.$dialog({
 | 
				
			||||||
				title: this.$t('contextmenu.copied'),
 | 
									title: this.$t('contextmenu.copied'),
 | 
				
			||||||
				text: this.$t('contextmenu.copied-url-to-clipboard'),
 | 
									text: this.$t('contextmenu.copied-url-to-clipboard'),
 | 
				
			||||||
				actions: [{
 | 
									actions: [{
 | 
				
			||||||
| 
						 | 
					@ -181,11 +180,11 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		setAsAvatar() {
 | 
							setAsAvatar() {
 | 
				
			||||||
			this.$root.apis.updateAvatar(this.file);
 | 
								this.$updateAvatar(this.file);
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		setAsBanner() {
 | 
							setAsBanner() {
 | 
				
			||||||
			this.$root.apis.updateBanner(this.file);
 | 
								this.$updateBanner(this.file);
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		addApp() {
 | 
							addApp() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,6 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
import i18n from '../../../i18n';
 | 
					import i18n from '../../../i18n';
 | 
				
			||||||
import contextmenu from '../../api/contextmenu';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
	i18n: i18n('desktop/views/components/drive.folder.vue'),
 | 
						i18n: i18n('desktop/views/components/drive.folder.vue'),
 | 
				
			||||||
| 
						 | 
					@ -54,7 +53,7 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onContextmenu(e) {
 | 
							onContextmenu(e) {
 | 
				
			||||||
			this.isContextmenuShowing = true;
 | 
								this.isContextmenuShowing = true;
 | 
				
			||||||
			contextmenu((this as any).os)(e, [{
 | 
								this.$contextmenu(e, [{
 | 
				
			||||||
				type: 'item',
 | 
									type: 'item',
 | 
				
			||||||
				text: this.$t('contextmenu.move-to-this-folder'),
 | 
									text: this.$t('contextmenu.move-to-this-folder'),
 | 
				
			||||||
				icon: 'arrow-right',
 | 
									icon: 'arrow-right',
 | 
				
			||||||
| 
						 | 
					@ -156,7 +155,7 @@ export default Vue.extend({
 | 
				
			||||||
				}).catch(err => {
 | 
									}).catch(err => {
 | 
				
			||||||
					switch (err) {
 | 
										switch (err) {
 | 
				
			||||||
						case 'detected-circular-definition':
 | 
											case 'detected-circular-definition':
 | 
				
			||||||
							this.$root.apis.dialog({
 | 
												this.$dialog({
 | 
				
			||||||
								title: this.$t('unable-to-process'),
 | 
													title: this.$t('unable-to-process'),
 | 
				
			||||||
								text: this.$t('circular-reference-detected'),
 | 
													text: this.$t('circular-reference-detected'),
 | 
				
			||||||
								actions: [{
 | 
													actions: [{
 | 
				
			||||||
| 
						 | 
					@ -196,7 +195,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rename() {
 | 
							rename() {
 | 
				
			||||||
			this.$root.apis.input({
 | 
								this.$input({
 | 
				
			||||||
				title: this.$t('contextmenu.rename-folder'),
 | 
									title: this.$t('contextmenu.rename-folder'),
 | 
				
			||||||
				placeholder: this.$t('contextmenu.input-new-folder-name'),
 | 
									placeholder: this.$t('contextmenu.input-new-folder-name'),
 | 
				
			||||||
				default: this.folder.name
 | 
									default: this.folder.name
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,6 @@ import XNavFolder from './drive.nav-folder.vue';
 | 
				
			||||||
import XFolder from './drive.folder.vue';
 | 
					import XFolder from './drive.folder.vue';
 | 
				
			||||||
import XFile from './drive.file.vue';
 | 
					import XFile from './drive.file.vue';
 | 
				
			||||||
import contains from '../../../common/scripts/contains';
 | 
					import contains from '../../../common/scripts/contains';
 | 
				
			||||||
import contextmenu from '../../api/contextmenu';
 | 
					 | 
				
			||||||
import { url } from '../../../config';
 | 
					import { url } from '../../../config';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
| 
						 | 
					@ -137,7 +136,7 @@ export default Vue.extend({
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		onContextmenu(e) {
 | 
							onContextmenu(e) {
 | 
				
			||||||
			contextmenu((this as any).os)(e, [{
 | 
								this.$contextmenu(e, [{
 | 
				
			||||||
				type: 'item',
 | 
									type: 'item',
 | 
				
			||||||
				text: this.$t('contextmenu.create-folder'),
 | 
									text: this.$t('contextmenu.create-folder'),
 | 
				
			||||||
				icon: ['far', 'folder'],
 | 
									icon: ['far', 'folder'],
 | 
				
			||||||
| 
						 | 
					@ -314,7 +313,7 @@ export default Vue.extend({
 | 
				
			||||||
				}).catch(err => {
 | 
									}).catch(err => {
 | 
				
			||||||
					switch (err) {
 | 
										switch (err) {
 | 
				
			||||||
						case 'detected-circular-definition':
 | 
											case 'detected-circular-definition':
 | 
				
			||||||
							this.$root.apis.dialog({
 | 
												this.$dialog({
 | 
				
			||||||
								title: this.$t('unable-to-process'),
 | 
													title: this.$t('unable-to-process'),
 | 
				
			||||||
								text: this.$t('circular-reference-detected'),
 | 
													text: this.$t('circular-reference-detected'),
 | 
				
			||||||
								actions: [{
 | 
													actions: [{
 | 
				
			||||||
| 
						 | 
					@ -335,7 +334,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		urlUpload() {
 | 
							urlUpload() {
 | 
				
			||||||
			this.$root.apis.input({
 | 
								this.$input({
 | 
				
			||||||
				title: this.$t('url-upload'),
 | 
									title: this.$t('url-upload'),
 | 
				
			||||||
				placeholder: this.$t('url-of-file')
 | 
									placeholder: this.$t('url-of-file')
 | 
				
			||||||
			}).then(url => {
 | 
								}).then(url => {
 | 
				
			||||||
| 
						 | 
					@ -344,7 +343,7 @@ export default Vue.extend({
 | 
				
			||||||
					folderId: this.folder ? this.folder.id : undefined
 | 
										folderId: this.folder ? this.folder.id : undefined
 | 
				
			||||||
				});
 | 
									});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				this.$root.apis.dialog({
 | 
									this.$dialog({
 | 
				
			||||||
					title: this.$t('url-upload-requested'),
 | 
										title: this.$t('url-upload-requested'),
 | 
				
			||||||
					text: this.$t('may-take-time'),
 | 
										text: this.$t('may-take-time'),
 | 
				
			||||||
					actions: [{
 | 
										actions: [{
 | 
				
			||||||
| 
						 | 
					@ -355,7 +354,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		createFolder() {
 | 
							createFolder() {
 | 
				
			||||||
			this.$root.apis.input({
 | 
								this.$input({
 | 
				
			||||||
				title: this.$t('create-folder'),
 | 
									title: this.$t('create-folder'),
 | 
				
			||||||
				placeholder: this.$t('folder-name')
 | 
									placeholder: this.$t('folder-name')
 | 
				
			||||||
			}).then(name => {
 | 
								}).then(name => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -186,7 +186,7 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		hint() {
 | 
							hint() {
 | 
				
			||||||
			this.$root.apis.dialog({
 | 
								this.$dialog({
 | 
				
			||||||
				title: this.$t('@.customization-tips.title'),
 | 
									title: this.$t('@.customization-tips.title'),
 | 
				
			||||||
				text: this.$t('@.customization-tips.paragraph'),
 | 
									text: this.$t('@.customization-tips.paragraph'),
 | 
				
			||||||
				actions: [{
 | 
									actions: [{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -245,7 +245,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		chooseFileFromDrive() {
 | 
							chooseFileFromDrive() {
 | 
				
			||||||
			this.$root.apis.chooseDriveFile({
 | 
								this.$chooseDriveFile({
 | 
				
			||||||
				multiple: true
 | 
									multiple: true
 | 
				
			||||||
			}).then(files => {
 | 
								}).then(files => {
 | 
				
			||||||
				files.forEach(this.attachMedia);
 | 
									files.forEach(this.attachMedia);
 | 
				
			||||||
| 
						 | 
					@ -363,7 +363,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		addVisibleUser() {
 | 
							addVisibleUser() {
 | 
				
			||||||
			this.$root.apis.input({
 | 
								this.$input({
 | 
				
			||||||
				title: this.$t('enter-username')
 | 
									title: this.$t('enter-username')
 | 
				
			||||||
			}).then(acct => {
 | 
								}).then(acct => {
 | 
				
			||||||
				if (acct.startsWith('@')) acct = acct.substr(1);
 | 
									if (acct.startsWith('@')) acct = acct.substr(1);
 | 
				
			||||||
| 
						 | 
					@ -401,13 +401,13 @@ export default Vue.extend({
 | 
				
			||||||
				this.clear();
 | 
									this.clear();
 | 
				
			||||||
				this.deleteDraft();
 | 
									this.deleteDraft();
 | 
				
			||||||
				this.$emit('posted');
 | 
									this.$emit('posted');
 | 
				
			||||||
				this.$root.apis.notify(this.renote
 | 
									this.$notify(this.renote
 | 
				
			||||||
					? this.$t('reposted')
 | 
										? this.$t('reposted')
 | 
				
			||||||
					: this.reply
 | 
										: this.reply
 | 
				
			||||||
						? this.$t('replied')
 | 
											? this.$t('replied')
 | 
				
			||||||
						: this.$t('posted'));
 | 
											: this.$t('posted'));
 | 
				
			||||||
			}).catch(err => {
 | 
								}).catch(err => {
 | 
				
			||||||
				this.$root.apis.notify(this.renote
 | 
									this.$notify(this.renote
 | 
				
			||||||
					? this.$t('renote-failed')
 | 
										? this.$t('renote-failed')
 | 
				
			||||||
					: this.reply
 | 
										: this.reply
 | 
				
			||||||
						? this.$t('reply-failed')
 | 
											? this.$t('reply-failed')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,9 +34,9 @@ export default Vue.extend({
 | 
				
			||||||
				renoteId: this.note.id
 | 
									renoteId: this.note.id
 | 
				
			||||||
			}).then(data => {
 | 
								}).then(data => {
 | 
				
			||||||
				this.$emit('posted');
 | 
									this.$emit('posted');
 | 
				
			||||||
				this.$root.apis.notify(this.$t('success'));
 | 
									this.$notify(this.$t('success'));
 | 
				
			||||||
			}).catch(err => {
 | 
								}).catch(err => {
 | 
				
			||||||
				this.$root.apis.notify(this.$t('failure'));
 | 
									this.$notify(this.$t('failure'));
 | 
				
			||||||
			}).then(() => {
 | 
								}).then(() => {
 | 
				
			||||||
				this.wait = false;
 | 
									this.wait = false;
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,7 @@ export default Vue.extend({
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		register() {
 | 
							register() {
 | 
				
			||||||
			this.$root.apis.input({
 | 
								this.$input({
 | 
				
			||||||
				title: this.$t('enter-password'),
 | 
									title: this.$t('enter-password'),
 | 
				
			||||||
				type: 'password'
 | 
									type: 'password'
 | 
				
			||||||
			}).then(password => {
 | 
								}).then(password => {
 | 
				
			||||||
| 
						 | 
					@ -48,14 +48,14 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		unregister() {
 | 
							unregister() {
 | 
				
			||||||
			this.$root.apis.input({
 | 
								this.$input({
 | 
				
			||||||
				title: this.$t('enter-password'),
 | 
									title: this.$t('enter-password'),
 | 
				
			||||||
				type: 'password'
 | 
									type: 'password'
 | 
				
			||||||
			}).then(password => {
 | 
								}).then(password => {
 | 
				
			||||||
				this.$root.api('i/2fa/unregister', {
 | 
									this.$root.api('i/2fa/unregister', {
 | 
				
			||||||
					password: password
 | 
										password: password
 | 
				
			||||||
				}).then(() => {
 | 
									}).then(() => {
 | 
				
			||||||
					this.$root.apis.notify(this.$t('unregistered'));
 | 
										this.$notify(this.$t('unregistered'));
 | 
				
			||||||
					this.$store.state.i.twoFactorEnabled = false;
 | 
										this.$store.state.i.twoFactorEnabled = false;
 | 
				
			||||||
				});
 | 
									});
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
| 
						 | 
					@ -65,10 +65,10 @@ export default Vue.extend({
 | 
				
			||||||
			this.$root.api('i/2fa/done', {
 | 
								this.$root.api('i/2fa/done', {
 | 
				
			||||||
				token: this.token
 | 
									token: this.token
 | 
				
			||||||
			}).then(() => {
 | 
								}).then(() => {
 | 
				
			||||||
				this.$root.apis.notify(this.$t('success'));
 | 
									this.$notify(this.$t('success'));
 | 
				
			||||||
				this.$store.state.i.twoFactorEnabled = true;
 | 
									this.$store.state.i.twoFactorEnabled = true;
 | 
				
			||||||
			}).catch(() => {
 | 
								}).catch(() => {
 | 
				
			||||||
				this.$root.apis.notify(this.$t('failed'));
 | 
									this.$notify(this.$t('failed'));
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -513,7 +513,7 @@ export default Vue.extend({
 | 
				
			||||||
			this.$emit('done');
 | 
								this.$emit('done');
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		updateWallpaper() {
 | 
							updateWallpaper() {
 | 
				
			||||||
			this.$root.apis.chooseDriveFile({
 | 
								this.$chooseDriveFile({
 | 
				
			||||||
				multiple: false
 | 
									multiple: false
 | 
				
			||||||
			}).then(file => {
 | 
								}).then(file => {
 | 
				
			||||||
				this.$root.api('i/update', {
 | 
									this.$root.api('i/update', {
 | 
				
			||||||
| 
						 | 
					@ -533,16 +533,16 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		checkForUpdate() {
 | 
							checkForUpdate() {
 | 
				
			||||||
			this.checkingForUpdate = true;
 | 
								this.checkingForUpdate = true;
 | 
				
			||||||
			checkForUpdate((this as any).os, true, true).then(newer => {
 | 
								checkForUpdate(this.$root, true, true).then(newer => {
 | 
				
			||||||
				this.checkingForUpdate = false;
 | 
									this.checkingForUpdate = false;
 | 
				
			||||||
				this.latestVersion = newer;
 | 
									this.latestVersion = newer;
 | 
				
			||||||
				if (newer == null) {
 | 
									if (newer == null) {
 | 
				
			||||||
					this.$root.apis.dialog({
 | 
										this.$dialog({
 | 
				
			||||||
						title: this.$t('no-updates'),
 | 
											title: this.$t('no-updates'),
 | 
				
			||||||
						text: this.$t('no-updates-desc')
 | 
											text: this.$t('no-updates-desc')
 | 
				
			||||||
					});
 | 
										});
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					this.$root.apis.dialog({
 | 
										this.$dialog({
 | 
				
			||||||
						title: this.$t('update-available'),
 | 
											title: this.$t('update-available'),
 | 
				
			||||||
						text: this.$t('update-available-desc')
 | 
											text: this.$t('update-available-desc')
 | 
				
			||||||
					});
 | 
										});
 | 
				
			||||||
| 
						 | 
					@ -551,7 +551,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		clean() {
 | 
							clean() {
 | 
				
			||||||
			localStorage.clear();
 | 
								localStorage.clear();
 | 
				
			||||||
			this.$root.apis.dialog({
 | 
								this.$dialog({
 | 
				
			||||||
				title: this.$t('cache-cleared'),
 | 
									title: this.$t('cache-cleared'),
 | 
				
			||||||
				text: this.$t('cache-cleared-desc')
 | 
									text: this.$t('cache-cleared-desc')
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,7 +109,7 @@ export default Vue.extend({
 | 
				
			||||||
				icon: 'plus',
 | 
									icon: 'plus',
 | 
				
			||||||
				text: this.$t('add-list'),
 | 
									text: this.$t('add-list'),
 | 
				
			||||||
				action: () => {
 | 
									action: () => {
 | 
				
			||||||
					this.$root.apis.input({
 | 
										this.$input({
 | 
				
			||||||
						title: this.$t('list-name'),
 | 
											title: this.$t('list-name'),
 | 
				
			||||||
					}).then(async title => {
 | 
										}).then(async title => {
 | 
				
			||||||
						const list = await this.$root.api('users/lists/create', {
 | 
											const list = await this.$root.api('users/lists/create', {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@ export default Vue.extend({
 | 
				
			||||||
	i18n: i18n('desktop/views/components/ui.header.post.vue'),
 | 
						i18n: i18n('desktop/views/components/ui.header.post.vue'),
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		post() {
 | 
							post() {
 | 
				
			||||||
			this.$root.apis.post();
 | 
								this.$post();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -139,7 +139,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		post() {
 | 
							post() {
 | 
				
			||||||
			this.$root.apis.post();
 | 
								this.$post();
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		drive() {
 | 
							drive() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,7 +67,7 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		post() {
 | 
							post() {
 | 
				
			||||||
			this.$root.apis.post();
 | 
								this.$post();
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		toggleZenMode() {
 | 
							toggleZenMode() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,7 @@ export default Vue.extend({
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		add() {
 | 
							add() {
 | 
				
			||||||
			this.$root.apis.input({
 | 
								this.$input({
 | 
				
			||||||
				title: this.$t('list-name'),
 | 
									title: this.$t('list-name'),
 | 
				
			||||||
			}).then(async title => {
 | 
								}).then(async title => {
 | 
				
			||||||
				const list = await this.$root.api('users/lists/create', {
 | 
									const list = await this.$root.api('users/lists/create', {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,6 @@
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
import i18n from '../../../../i18n';
 | 
					import i18n from '../../../../i18n';
 | 
				
			||||||
import Menu from '../../../../common/views/components/menu.vue';
 | 
					import Menu from '../../../../common/views/components/menu.vue';
 | 
				
			||||||
import contextmenu from '../../../api/contextmenu';
 | 
					 | 
				
			||||||
import { countIf } from '../../../../../../prelude/array';
 | 
					import { countIf } from '../../../../../../prelude/array';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
| 
						 | 
					@ -168,7 +167,7 @@ export default Vue.extend({
 | 
				
			||||||
				icon: 'pencil-alt',
 | 
									icon: 'pencil-alt',
 | 
				
			||||||
				text: this.$t('rename'),
 | 
									text: this.$t('rename'),
 | 
				
			||||||
				action: () => {
 | 
									action: () => {
 | 
				
			||||||
					this.$root.apis.input({
 | 
										this.$input({
 | 
				
			||||||
						title: this.$t('rename'),
 | 
											title: this.$t('rename'),
 | 
				
			||||||
						default: this.name,
 | 
											default: this.name,
 | 
				
			||||||
						allowEmpty: false
 | 
											allowEmpty: false
 | 
				
			||||||
| 
						 | 
					@ -230,7 +229,7 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onContextmenu(e) {
 | 
							onContextmenu(e) {
 | 
				
			||||||
			if (this.isTemporaryColumn) return;
 | 
								if (this.isTemporaryColumn) return;
 | 
				
			||||||
			contextmenu((this as any).os)(e, this.getMenu());
 | 
								this.$contextmenu(e, this.getMenu());
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		showMenu() {
 | 
							showMenu() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -255,7 +255,7 @@ export default Vue.extend({
 | 
				
			||||||
					icon: 'hashtag',
 | 
										icon: 'hashtag',
 | 
				
			||||||
					text: this.$t('@deck.hashtag'),
 | 
										text: this.$t('@deck.hashtag'),
 | 
				
			||||||
					action: () => {
 | 
										action: () => {
 | 
				
			||||||
						this.$root.apis.input({
 | 
											this.$input({
 | 
				
			||||||
							title: this.$t('enter-hashtag-tl-title')
 | 
												title: this.$t('enter-hashtag-tl-title')
 | 
				
			||||||
						}).then(title => {
 | 
											}).then(title => {
 | 
				
			||||||
							this.$store.dispatch('settings/addDeckColumn', {
 | 
												this.$store.dispatch('settings/addDeckColumn', {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,7 +81,7 @@ export default Vue.extend({
 | 
				
			||||||
		onBannerClick() {
 | 
							onBannerClick() {
 | 
				
			||||||
			if (!this.$store.getters.isSignedIn || this.$store.state.i.id != this.user.id) return;
 | 
								if (!this.$store.getters.isSignedIn || this.$store.state.i.id != this.user.id) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			this.$root.apis.updateBanner().then(i => {
 | 
								this.$updateBanner().then(i => {
 | 
				
			||||||
				this.user.bannerUrl = i.bannerUrl;
 | 
									this.user.bannerUrl = i.bannerUrl;
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,7 +101,7 @@ export default Vue.extend({
 | 
				
			||||||
					listId: list.id,
 | 
										listId: list.id,
 | 
				
			||||||
					userId: this.user.id
 | 
										userId: this.user.id
 | 
				
			||||||
				});
 | 
									});
 | 
				
			||||||
				this.$root.apis.dialog({
 | 
									this.$dialog({
 | 
				
			||||||
					title: 'Done!',
 | 
										title: 'Done!',
 | 
				
			||||||
					text: this.$t('list-pushed').replace('{user}', this.user.name).replace('{list}', list.title)
 | 
										text: this.$t('list-pushed').replace('{user}', this.user.name).replace('{list}', list.title)
 | 
				
			||||||
				});
 | 
									});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,7 @@ import VueI18n from 'vue-i18n';
 | 
				
			||||||
import VueHotkey from './common/hotkey';
 | 
					import VueHotkey from './common/hotkey';
 | 
				
			||||||
import App from './app.vue';
 | 
					import App from './app.vue';
 | 
				
			||||||
import checkForUpdate from './common/scripts/check-for-update';
 | 
					import checkForUpdate from './common/scripts/check-for-update';
 | 
				
			||||||
import MiOS, { API } from './mios';
 | 
					import MiOS from './mios';
 | 
				
			||||||
import { clientVersion as version, codename, lang } from './config';
 | 
					import { clientVersion as version, codename, lang } from './config';
 | 
				
			||||||
import { builtinThemes, lightTheme, applyTheme } from './theme';
 | 
					import { builtinThemes, lightTheme, applyTheme } from './theme';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -180,16 +180,14 @@ if (localStorage.getItem('should-refresh') == 'true') {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MiOSを初期化してコールバックする
 | 
					// MiOSを初期化してコールバックする
 | 
				
			||||||
export default (callback: (launch: (router: VueRouter, api?: (os: MiOS) => API) => [Vue, MiOS]) => void, sw = false) => {
 | 
					export default (callback: (launch: (router: VueRouter) => [Vue, MiOS]) => void, sw = false) => {
 | 
				
			||||||
	const os = new MiOS(sw);
 | 
						const os = new MiOS(sw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	os.init(() => {
 | 
						os.init(() => {
 | 
				
			||||||
		// アプリ基底要素マウント
 | 
							// アプリ基底要素マウント
 | 
				
			||||||
		document.body.innerHTML = '<div id="app"></div>';
 | 
							document.body.innerHTML = '<div id="app"></div>';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const launch = (router: VueRouter, api?: (os: MiOS) => API) => {
 | 
							const launch = (router: VueRouter) => {
 | 
				
			||||||
			os.apis = api ? api(os) : null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			//#region theme
 | 
								//#region theme
 | 
				
			||||||
			os.store.watch(s => {
 | 
								os.store.watch(s => {
 | 
				
			||||||
				return s.device.darkmode;
 | 
									return s.device.darkmode;
 | 
				
			||||||
| 
						 | 
					@ -285,7 +283,6 @@ export default (callback: (launch: (router: VueRouter, api?: (os: MiOS) => API)
 | 
				
			||||||
							windows: os.windows
 | 
												windows: os.windows
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
						stream: os.stream,
 | 
											stream: os.stream,
 | 
				
			||||||
						apis: os.apis,
 | 
					 | 
				
			||||||
						instanceName: os.instanceName
 | 
											instanceName: os.instanceName
 | 
				
			||||||
					};
 | 
										};
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
| 
						 | 
					@ -293,7 +290,14 @@ export default (callback: (launch: (router: VueRouter, api?: (os: MiOS) => API)
 | 
				
			||||||
					api: os.api,
 | 
										api: os.api,
 | 
				
			||||||
					getMeta: os.getMeta,
 | 
										getMeta: os.getMeta,
 | 
				
			||||||
					getMetaSync: os.getMetaSync,
 | 
										getMetaSync: os.getMetaSync,
 | 
				
			||||||
					new: os.new,
 | 
										new(vm, props) {
 | 
				
			||||||
 | 
											const x = new vm({
 | 
				
			||||||
 | 
												parent: this,
 | 
				
			||||||
 | 
												propsData: props
 | 
				
			||||||
 | 
											}).$mount();
 | 
				
			||||||
 | 
											document.body.appendChild(x.$el);
 | 
				
			||||||
 | 
											return x;
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				router,
 | 
									router,
 | 
				
			||||||
				render: createEl => createEl(App)
 | 
									render: createEl => createEl(App)
 | 
				
			||||||
| 
						 | 
					@ -304,18 +308,18 @@ export default (callback: (launch: (router: VueRouter, api?: (os: MiOS) => API)
 | 
				
			||||||
			// マウント
 | 
								// マウント
 | 
				
			||||||
			app.$mount('#app');
 | 
								app.$mount('#app');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return [app, os] as [Vue, MiOS];
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		callback(launch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			//#region 更新チェック
 | 
								//#region 更新チェック
 | 
				
			||||||
			const preventUpdate = os.store.state.device.preventUpdate;
 | 
								const preventUpdate = os.store.state.device.preventUpdate;
 | 
				
			||||||
			if (!preventUpdate) {
 | 
								if (!preventUpdate) {
 | 
				
			||||||
				setTimeout(() => {
 | 
									setTimeout(() => {
 | 
				
			||||||
				checkForUpdate(os);
 | 
										checkForUpdate(app);
 | 
				
			||||||
				}, 3000);
 | 
									}, 3000);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			//#endregion
 | 
								//#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return [app, os] as [Vue, MiOS];
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							callback(launch);
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,41 +15,6 @@ let spinner = null;
 | 
				
			||||||
let pending = 0;
 | 
					let pending = 0;
 | 
				
			||||||
//#endregion
 | 
					//#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type API = {
 | 
					 | 
				
			||||||
	chooseDriveFile: (opts: {
 | 
					 | 
				
			||||||
		title?: string;
 | 
					 | 
				
			||||||
		currentFolder?: any;
 | 
					 | 
				
			||||||
		multiple?: boolean;
 | 
					 | 
				
			||||||
	}) => Promise<any>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	chooseDriveFolder: (opts: {
 | 
					 | 
				
			||||||
		title?: string;
 | 
					 | 
				
			||||||
		currentFolder?: any;
 | 
					 | 
				
			||||||
	}) => Promise<any>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dialog: (opts: {
 | 
					 | 
				
			||||||
		title: string;
 | 
					 | 
				
			||||||
		text: string;
 | 
					 | 
				
			||||||
		actions?: Array<{
 | 
					 | 
				
			||||||
			text: string;
 | 
					 | 
				
			||||||
			id?: string;
 | 
					 | 
				
			||||||
		}>;
 | 
					 | 
				
			||||||
	}) => Promise<string>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	input: (opts: {
 | 
					 | 
				
			||||||
		title: string;
 | 
					 | 
				
			||||||
		placeholder?: string;
 | 
					 | 
				
			||||||
		default?: string;
 | 
					 | 
				
			||||||
	}) => Promise<string>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	post: (opts?: {
 | 
					 | 
				
			||||||
		reply?: any;
 | 
					 | 
				
			||||||
		renote?: any;
 | 
					 | 
				
			||||||
	}) => void;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	notify: (message: string) => void;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Misskey Operating System
 | 
					 * Misskey Operating System
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -70,16 +35,6 @@ export default class MiOS extends EventEmitter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public app: Vue;
 | 
						public app: Vue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@autobind
 | 
					 | 
				
			||||||
	public new(vm, props) {
 | 
					 | 
				
			||||||
		const x = new vm({
 | 
					 | 
				
			||||||
			parent: this.app,
 | 
					 | 
				
			||||||
			propsData: props
 | 
					 | 
				
			||||||
		}).$mount();
 | 
					 | 
				
			||||||
		document.body.appendChild(x.$el);
 | 
					 | 
				
			||||||
		return x;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Whether is debug mode
 | 
						 * Whether is debug mode
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
| 
						 | 
					@ -89,8 +44,6 @@ export default class MiOS extends EventEmitter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public store: ReturnType<typeof initStore>;
 | 
						public store: ReturnType<typeof initStore>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public apis: API;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * A connection manager of home stream
 | 
						 * A connection manager of home stream
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,18 +0,0 @@
 | 
				
			||||||
import Chooser from '../views/components/drive-file-chooser.vue';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function(opts) {
 | 
					 | 
				
			||||||
	return new Promise((res, rej) => {
 | 
					 | 
				
			||||||
		const o = opts || {};
 | 
					 | 
				
			||||||
		const w = new Chooser({
 | 
					 | 
				
			||||||
			propsData: {
 | 
					 | 
				
			||||||
				title: o.title,
 | 
					 | 
				
			||||||
				multiple: o.multiple,
 | 
					 | 
				
			||||||
				initFolder: o.currentFolder
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}).$mount();
 | 
					 | 
				
			||||||
		w.$once('selected', file => {
 | 
					 | 
				
			||||||
			res(file);
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		document.body.appendChild(w.$el);
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,17 +0,0 @@
 | 
				
			||||||
import Chooser from '../views/components/drive-folder-chooser.vue';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function(opts) {
 | 
					 | 
				
			||||||
	return new Promise((res, rej) => {
 | 
					 | 
				
			||||||
		const o = opts || {};
 | 
					 | 
				
			||||||
		const w = new Chooser({
 | 
					 | 
				
			||||||
			propsData: {
 | 
					 | 
				
			||||||
				title: o.title,
 | 
					 | 
				
			||||||
				initFolder: o.currentFolder
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}).$mount();
 | 
					 | 
				
			||||||
		w.$once('selected', folder => {
 | 
					 | 
				
			||||||
			res(folder);
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		document.body.appendChild(w.$el);
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,18 +0,0 @@
 | 
				
			||||||
import OS from '../../mios';
 | 
					 | 
				
			||||||
import Dialog from '../views/components/dialog.vue';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default (os: OS) => opts => {
 | 
					 | 
				
			||||||
	return new Promise<string>((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);
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,8 +0,0 @@
 | 
				
			||||||
export default function(opts) {
 | 
					 | 
				
			||||||
	return new Promise<string>((res, rej) => {
 | 
					 | 
				
			||||||
		const x = window.prompt(opts.title);
 | 
					 | 
				
			||||||
		if (x) {
 | 
					 | 
				
			||||||
			res(x);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,3 +0,0 @@
 | 
				
			||||||
export default function(message) {
 | 
					 | 
				
			||||||
	alert(message);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,24 +0,0 @@
 | 
				
			||||||
import PostForm from '../views/components/post-form-dialog.vue';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default (os) => (opts) => {
 | 
					 | 
				
			||||||
	const o = opts || {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	document.documentElement.style.overflow = 'hidden';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	function recover() {
 | 
					 | 
				
			||||||
		document.documentElement.style.overflow = 'auto';
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	const vm = new PostForm({
 | 
					 | 
				
			||||||
		parent: os.app,
 | 
					 | 
				
			||||||
		propsData: {
 | 
					 | 
				
			||||||
			reply: o.reply,
 | 
					 | 
				
			||||||
			renote: o.renote
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}).$mount();
 | 
					 | 
				
			||||||
	vm.$once('cancel', recover);
 | 
					 | 
				
			||||||
	vm.$once('posted', recover);
 | 
					 | 
				
			||||||
	if (o.cb) vm.$once('closed', o.cb);
 | 
					 | 
				
			||||||
	document.body.appendChild(vm.$el);
 | 
					 | 
				
			||||||
	(vm as any).focus();
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
 * Mobile Client
 | 
					 * Mobile Client
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Vue from 'vue';
 | 
				
			||||||
import VueRouter from 'vue-router';
 | 
					import VueRouter from 'vue-router';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Style
 | 
					// Style
 | 
				
			||||||
| 
						 | 
					@ -9,13 +10,6 @@ import './style.styl';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import init from '../init';
 | 
					import init from '../init';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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 MkIndex from './views/pages/index.vue';
 | 
					import MkIndex from './views/pages/index.vue';
 | 
				
			||||||
import MkSignup from './views/pages/signup.vue';
 | 
					import MkSignup from './views/pages/signup.vue';
 | 
				
			||||||
import MkUser from './views/pages/user.vue';
 | 
					import MkUser from './views/pages/user.vue';
 | 
				
			||||||
| 
						 | 
					@ -39,10 +33,94 @@ import MkTag from './views/pages/tag.vue';
 | 
				
			||||||
import MkShare from './views/pages/share.vue';
 | 
					import MkShare from './views/pages/share.vue';
 | 
				
			||||||
import MkFollow from '../common/views/pages/follow.vue';
 | 
					import MkFollow from '../common/views/pages/follow.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import PostForm from './views/components/post-form-dialog.vue';
 | 
				
			||||||
 | 
					import FileChooser from './views/components/drive-file-chooser.vue';
 | 
				
			||||||
 | 
					import FolderChooser from './views/components/drive-folder-chooser.vue';
 | 
				
			||||||
 | 
					import Dialog from './views/components/dialog.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * init
 | 
					 * init
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
init((launch) => {
 | 
					init((launch) => {
 | 
				
			||||||
 | 
						Vue.mixin({
 | 
				
			||||||
 | 
							methods: {
 | 
				
			||||||
 | 
								$post(opts) {
 | 
				
			||||||
 | 
									const o = opts || {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									document.documentElement.style.overflow = 'hidden';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									function recover() {
 | 
				
			||||||
 | 
										document.documentElement.style.overflow = 'auto';
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									const vm = this.$root.new(PostForm, {
 | 
				
			||||||
 | 
										reply: o.reply,
 | 
				
			||||||
 | 
										renote: o.renote
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									vm.$once('cancel', recover);
 | 
				
			||||||
 | 
									vm.$once('posted', recover);
 | 
				
			||||||
 | 
									if (o.cb) vm.$once('closed', o.cb);
 | 
				
			||||||
 | 
									(vm as any).focus();
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								$chooseDriveFile(opts) {
 | 
				
			||||||
 | 
									return new Promise((res, rej) => {
 | 
				
			||||||
 | 
										const o = opts || {};
 | 
				
			||||||
 | 
										const vm = this.$root.new(FileChooser, {
 | 
				
			||||||
 | 
											title: o.title,
 | 
				
			||||||
 | 
											multiple: o.multiple,
 | 
				
			||||||
 | 
											initFolder: o.currentFolder
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
										vm.$once('selected', file => {
 | 
				
			||||||
 | 
											res(file);
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								$chooseDriveFolder(opts) {
 | 
				
			||||||
 | 
									return new Promise((res, rej) => {
 | 
				
			||||||
 | 
										const o = opts || {};
 | 
				
			||||||
 | 
										const vm = this.$root.new(FolderChooser, {
 | 
				
			||||||
 | 
											title: o.title,
 | 
				
			||||||
 | 
											initFolder: o.currentFolder
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
										vm.$once('selected', folder => {
 | 
				
			||||||
 | 
											res(folder);
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								$input(opts) {
 | 
				
			||||||
 | 
									return new Promise<string>((res, rej) => {
 | 
				
			||||||
 | 
										const x = window.prompt(opts.title);
 | 
				
			||||||
 | 
										if (x) {
 | 
				
			||||||
 | 
											res(x);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								$dialog(opts) {
 | 
				
			||||||
 | 
									return new Promise<string>((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);
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								$notify(message) {
 | 
				
			||||||
 | 
									alert(message);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Register directives
 | 
						// Register directives
 | 
				
			||||||
	require('./views/directives');
 | 
						require('./views/directives');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,12 +163,5 @@ init((launch) => {
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Launch the app
 | 
						// Launch the app
 | 
				
			||||||
	launch(router, os => ({
 | 
						launch(router);
 | 
				
			||||||
		chooseDriveFolder,
 | 
					 | 
				
			||||||
		chooseDriveFile,
 | 
					 | 
				
			||||||
		dialog: dialog(os),
 | 
					 | 
				
			||||||
		input,
 | 
					 | 
				
			||||||
		post: post(os),
 | 
					 | 
				
			||||||
		notify
 | 
					 | 
				
			||||||
	}));
 | 
					 | 
				
			||||||
}, true);
 | 
					}, true);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,7 +101,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		move() {
 | 
							move() {
 | 
				
			||||||
			this.$root.apis.chooseDriveFolder().then(folder => {
 | 
								this.$chooseDriveFolder().then(folder => {
 | 
				
			||||||
				this.$root.api('drive/files/update', {
 | 
									this.$root.api('drive/files/update', {
 | 
				
			||||||
					fileId: this.file.id,
 | 
										fileId: this.file.id,
 | 
				
			||||||
					folderId: folder == null ? null : folder.id
 | 
										folderId: folder == null ? null : folder.id
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -439,7 +439,7 @@ export default Vue.extend({
 | 
				
			||||||
				alert(this.$t('root-move-alert'));
 | 
									alert(this.$t('root-move-alert'));
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			this.$root.apis.chooseDriveFolder().then(folder => {
 | 
								this.$chooseDriveFolder().then(folder => {
 | 
				
			||||||
				this.$root.api('drive/folders/update', {
 | 
									this.$root.api('drive/folders/update', {
 | 
				
			||||||
					parentId: folder ? folder.id : null,
 | 
										parentId: folder ? folder.id : null,
 | 
				
			||||||
					folderId: this.folder.id
 | 
										folderId: this.folder.id
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -196,13 +196,13 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		reply() {
 | 
							reply() {
 | 
				
			||||||
			this.$root.apis.post({
 | 
								this.$post({
 | 
				
			||||||
				reply: this.p
 | 
									reply: this.p
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		renote() {
 | 
							renote() {
 | 
				
			||||||
			this.$root.apis.post({
 | 
								this.$post({
 | 
				
			||||||
				renote: this.p
 | 
									renote: this.p
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -220,7 +220,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		chooseFileFromDrive() {
 | 
							chooseFileFromDrive() {
 | 
				
			||||||
			this.$root.apis.chooseDriveFile({
 | 
								this.$chooseDriveFile({
 | 
				
			||||||
				multiple: true
 | 
									multiple: true
 | 
				
			||||||
			}).then(files => {
 | 
								}).then(files => {
 | 
				
			||||||
				files.forEach(this.attachMedia);
 | 
									files.forEach(this.attachMedia);
 | 
				
			||||||
| 
						 | 
					@ -279,7 +279,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		addVisibleUser() {
 | 
							addVisibleUser() {
 | 
				
			||||||
			this.$root.apis.input({
 | 
								this.$input({
 | 
				
			||||||
				title: this.$t('username-prompt')
 | 
									title: this.$t('username-prompt')
 | 
				
			||||||
			}).then(acct => {
 | 
								}).then(acct => {
 | 
				
			||||||
				if (acct.startsWith('@')) acct = acct.substr(1);
 | 
									if (acct.startsWith('@')) acct = acct.substr(1);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@
 | 
				
			||||||
			<button class="nav" @click="$parent.isDrawerOpening = true"><fa icon="bars"/></button>
 | 
								<button class="nav" @click="$parent.isDrawerOpening = true"><fa icon="bars"/></button>
 | 
				
			||||||
			<i v-if="hasUnreadNotification || hasUnreadMessagingMessage || hasGameInvitation" class="circle"><fa icon="circle"/></i>
 | 
								<i v-if="hasUnreadNotification || hasUnreadMessagingMessage || hasGameInvitation" class="circle"><fa icon="circle"/></i>
 | 
				
			||||||
			<h1>
 | 
								<h1>
 | 
				
			||||||
				<slot>{{ os.instanceName }}</slot>
 | 
									<slot>{{ $root.instanceName }}</slot>
 | 
				
			||||||
			</h1>
 | 
								</h1>
 | 
				
			||||||
			<slot name="func"></slot>
 | 
								<slot name="func"></slot>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -139,7 +139,7 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		fn() {
 | 
							fn() {
 | 
				
			||||||
			this.$root.apis.post();
 | 
								this.$post();
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		saveSrc() {
 | 
							saveSrc() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -339,16 +339,16 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		checkForUpdate() {
 | 
							checkForUpdate() {
 | 
				
			||||||
			this.checkingForUpdate = true;
 | 
								this.checkingForUpdate = true;
 | 
				
			||||||
			checkForUpdate((this as any).os, true, true).then(newer => {
 | 
								checkForUpdate(this.$root, true, true).then(newer => {
 | 
				
			||||||
				this.checkingForUpdate = false;
 | 
									this.checkingForUpdate = false;
 | 
				
			||||||
				this.latestVersion = newer;
 | 
									this.latestVersion = newer;
 | 
				
			||||||
				if (newer == null) {
 | 
									if (newer == null) {
 | 
				
			||||||
					this.$root.apis.dialog({
 | 
										this.$dialog({
 | 
				
			||||||
						title: this.$t('no-updates'),
 | 
											title: this.$t('no-updates'),
 | 
				
			||||||
						text: this.$t('no-updates-desc')
 | 
											text: this.$t('no-updates-desc')
 | 
				
			||||||
					});
 | 
										});
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					this.$root.apis.dialog({
 | 
										this.$dialog({
 | 
				
			||||||
						title: this.$t('update-available'),
 | 
											title: this.$t('update-available'),
 | 
				
			||||||
						text: this.$t('update-available-desc')
 | 
											text: this.$t('update-available-desc')
 | 
				
			||||||
					});
 | 
										});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,7 @@ export default Vue.extend({
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		fn() {
 | 
							fn() {
 | 
				
			||||||
			this.$root.apis.input({
 | 
								this.$input({
 | 
				
			||||||
				title: this.$t('enter-list-name'),
 | 
									title: this.$t('enter-list-name'),
 | 
				
			||||||
			}).then(async title => {
 | 
								}).then(async title => {
 | 
				
			||||||
				const list = await this.$root.api('users/lists/create', {
 | 
									const list = await this.$root.api('users/lists/create', {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue