diff --git a/src/client/app/admin/views/announcements.vue b/src/client/app/admin/views/announcements.vue
index 8fc8ad4ceb..b0e5448cf9 100644
--- a/src/client/app/admin/views/announcements.vue
+++ b/src/client/app/admin/views/announcements.vue
@@ -52,8 +52,8 @@ export default Vue.extend({
type: 'warning',
text: this.$t('_remove.are-you-sure').replace('$1', this.announcements.find((_, j) => j == i).title),
showCancelButton: true
- }).then(res => {
- if (!res) return;
+ }).then(({ canceled }) => {
+ if (canceled) return;
this.announcements = this.announcements.filter((_, j) => j !== i);
this.save(true);
this.$root.dialog({
diff --git a/src/client/app/admin/views/emoji.vue b/src/client/app/admin/views/emoji.vue
index 0dcc421613..0819a07546 100644
--- a/src/client/app/admin/views/emoji.vue
+++ b/src/client/app/admin/views/emoji.vue
@@ -120,8 +120,8 @@ export default Vue.extend({
type: 'warning',
text: this.$t('remove-emoji.are-you-sure').replace('$1', emoji.name),
showCancelButton: true
- }).then(res => {
- if (!res) return;
+ }).then(({ canceled }) => {
+ if (canceled) return;
this.$root.api('admin/emoji/remove', {
id: emoji.id
diff --git a/src/client/app/common/views/components/api-settings.vue b/src/client/app/common/views/components/api-settings.vue
index 062218b3f4..e96eb28d93 100644
--- a/src/client/app/common/views/components/api-settings.vue
+++ b/src/client/app/common/views/components/api-settings.vue
@@ -50,10 +50,13 @@ export default Vue.extend({
methods: {
regenerateToken() {
- this.$input({
+ this.$root.dialog({
title: this.$t('enter-password'),
- type: 'password'
- }).then(password => {
+ input: {
+ type: 'password'
+ }
+ }).then(({ canceled, result: password }) => {
+ if (canceled) return;
this.$root.api('i/regenerate_token', {
password: password
});
diff --git a/src/client/app/common/views/components/dialog.vue b/src/client/app/common/views/components/dialog.vue
index abbdb8536e..5cc885881b 100644
--- a/src/client/app/common/views/components/dialog.vue
+++ b/src/client/app/common/views/components/dialog.vue
@@ -2,15 +2,17 @@
-
+
+
+
@
- OK
- Cancel
+ OK
+ Cancel
@@ -20,6 +22,7 @@
import Vue from 'vue';
import * as anime from 'animejs';
import { faTimesCircle, faQuestionCircle } from '@fortawesome/free-regular-svg-icons';
+import parseAcct from "../../../../../misc/acct/parse";
export default Vue.extend({
props: {
@@ -36,9 +39,15 @@ export default Vue.extend({
type: String,
required: false
},
+ input: {
+ required: false
+ },
select: {
required: false
},
+ user: {
+ required: false
+ },
showCancelButton: {
type: Boolean,
default: false
@@ -51,6 +60,8 @@ export default Vue.extend({
data() {
return {
+ inputValue: this.input && this.input.default ? this.input.default : null,
+ userInputValue: null,
selectedValue: null
};
},
@@ -94,10 +105,21 @@ export default Vue.extend({
},
methods: {
- ok() {
- const result = this.select ? this.selectedValue : true;
- this.$emit('ok', result);
- this.close();
+ async ok() {
+ if (this.user) {
+ const user = await this.$root.api('users/show', parseAcct(this.userInputValue));
+ if (user) {
+ this.$emit('ok', user);
+ this.close();
+ }
+ } else {
+ const result =
+ this.input ? this.inputValue :
+ this.select ? this.selectedValue :
+ true;
+ this.$emit('ok', result);
+ this.close();
+ }
},
cancel() {
@@ -127,6 +149,14 @@ export default Vue.extend({
onBgClick() {
this.cancel();
+ },
+
+ onInputKeydown(e) {
+ if (e.which == 13) { // Enter
+ e.preventDefault();
+ e.stopPropagation();
+ this.ok();
+ }
}
}
});
diff --git a/src/client/app/common/views/components/games/reversi/reversi.index.vue b/src/client/app/common/views/components/games/reversi/reversi.index.vue
index b82a60a360..07472998de 100644
--- a/src/client/app/common/views/components/games/reversi/reversi.index.vue
+++ b/src/client/app/common/views/components/games/reversi/reversi.index.vue
@@ -99,23 +99,22 @@ export default Vue.extend({
this.$emit('go', game);
},
- match() {
- this.$input({
- title: this.$t('enter-username')
- }).then(username => {
- this.$root.api('users/show', {
- username
- }).then(user => {
- this.$root.api('games/reversi/match', {
- userId: user.id
- }).then(res => {
- if (res == null) {
- this.$emit('matching', user);
- } else {
- this.$emit('go', res);
- }
- });
- });
+ async match() {
+ const { result: user } = await this.$root.dialog({
+ title: this.$t('enter-username'),
+ user: {
+ local: true
+ }
+ });
+ if (user == null) return;
+ this.$root.api('games/reversi/match', {
+ userId: user.id
+ }).then(res => {
+ if (res == null) {
+ this.$emit('matching', user);
+ } else {
+ this.$emit('go', res);
+ }
});
},
diff --git a/src/client/app/common/views/components/note-menu.vue b/src/client/app/common/views/components/note-menu.vue
index c4b1a02fee..b8f34beb0c 100644
--- a/src/client/app/common/views/components/note-menu.vue
+++ b/src/client/app/common/views/components/note-menu.vue
@@ -99,8 +99,8 @@ export default Vue.extend({
type: 'warning',
text: this.$t('delete-confirm'),
showCancelButton: true
- }).then(res => {
- if (!res) return;
+ }).then(({ canceled }) => {
+ if (canceled) return;
this.$root.api('notes/delete', {
noteId: this.note.id
diff --git a/src/client/app/common/views/components/password-settings.vue b/src/client/app/common/views/components/password-settings.vue
index d41b5a5bd1..bcea32576f 100644
--- a/src/client/app/common/views/components/password-settings.vue
+++ b/src/client/app/common/views/components/password-settings.vue
@@ -11,34 +11,43 @@ import i18n from '../../../i18n';
export default Vue.extend({
i18n: i18n('common/views/components/password-settings.vue'),
methods: {
- reset() {
- this.$input({
+ async reset() {
+ const { canceled: canceled1, result: currentPassword } = await this.$root.dialog({
title: this.$t('enter-current-password'),
- type: 'password'
- }).then(currentPassword => {
- this.$input({
- title: this.$t('enter-new-password'),
+ input: {
type: 'password'
- }).then(newPassword => {
- this.$input({
- title: this.$t('enter-new-password-again'),
- type: 'password'
- }).then(newPassword2 => {
- if (newPassword !== newPassword2) {
- this.$root.dialog({
- title: null,
- text: this.$t('not-match')
- });
- return;
- }
- this.$root.api('i/change_password', {
- currentPasword: currentPassword,
- newPassword: newPassword
- }).then(() => {
- this.$notify(this.$t('changed'));
- });
- });
+ }
+ });
+ if (canceled1) return;
+
+ const { canceled: canceled2, result: newPassword } = await this.$root.dialog({
+ title: this.$t('enter-new-password'),
+ input: {
+ type: 'password'
+ }
+ });
+ if (canceled2) return;
+
+ const { canceled: canceled3, result: newPassword2 } = await this.$root.dialog({
+ title: this.$t('enter-new-password-again'),
+ input: {
+ type: 'password'
+ }
+ });
+ if (canceled3) return;
+
+ if (newPassword !== newPassword2) {
+ this.$root.dialog({
+ title: null,
+ text: this.$t('not-match')
});
+ return;
+ }
+ this.$root.api('i/change_password', {
+ currentPasword: currentPassword,
+ newPassword: newPassword
+ }).then(() => {
+ this.$notify(this.$t('changed'));
});
}
}
diff --git a/src/client/app/common/views/components/profile-editor.vue b/src/client/app/common/views/components/profile-editor.vue
index 80c322fa9e..b402f046b1 100644
--- a/src/client/app/common/views/components/profile-editor.vue
+++ b/src/client/app/common/views/components/profile-editor.vue
@@ -222,10 +222,13 @@ export default Vue.extend({
},
updateEmail() {
- this.$input({
+ this.$root.dialog({
title: this.$t('@.enter-password'),
- type: 'password'
- }).then(password => {
+ input: {
+ type: 'password'
+ }
+ }).then(({ canceled, result: password }) => {
+ if (canceled) return;
this.$root.api('i/update_email', {
password: password,
email: this.email == '' ? null : this.email
diff --git a/src/client/app/common/views/components/ui/input.vue b/src/client/app/common/views/components/ui/input.vue
index 4d77810b47..d735cc1c2f 100644
--- a/src/client/app/common/views/components/ui/input.vue
+++ b/src/client/app/common/views/components/ui/input.vue
@@ -14,17 +14,19 @@
:disabled="disabled"
:required="required"
:readonly="readonly"
+ :placeholder="placeholder"
:pattern="pattern"
:autocomplete="autocomplete"
:spellcheck="spellcheck"
@focus="focused = true"
@blur="focused = false"
+ @keydown="$emit('keydown', $event)"
>
@@ -74,6 +76,15 @@ export default Vue.extend({
type: String,
required: false
},
+ placeholder: {
+ type: String,
+ required: false
+ },
+ autofocus: {
+ type: Boolean,
+ required: false,
+ default: false
+ },
autocomplete: {
required: false
},
@@ -109,7 +120,7 @@ export default Vue.extend({
filled(): boolean {
return this.v != '' && this.v != null;
},
- placeholder(): string {
+ filePlaceholder(): string {
if (this.type != 'file') return null;
if (this.v == null) return null;
@@ -142,6 +153,12 @@ export default Vue.extend({
}
},
mounted() {
+ if (this.autofocus) {
+ this.$nextTick(() => {
+ this.$refs.input.focus();
+ });
+ }
+
this.$nextTick(() => {
if (this.$refs.prefix) {
this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px';
diff --git a/src/client/app/desktop/script.ts b/src/client/app/desktop/script.ts
index cb23613164..dd4cad68c9 100644
--- a/src/client/app/desktop/script.ts
+++ b/src/client/app/desktop/script.ts
@@ -34,7 +34,6 @@ 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 InputDialog from './views/components/input-dialog.vue';
import Notification from './views/components/ui-notification.vue';
import { url } from '../config';
@@ -113,22 +112,6 @@ init(async (launch) => {
});
},
- $input(opts) {
- return new Promise((res, rej) => {
- const o = opts || {};
- const d = this.$root.new(InputDialog, {
- title: o.title,
- placeholder: o.placeholder,
- default: o.default,
- type: o.type || 'text',
- allowEmpty: o.allowEmpty
- });
- d.$once('done', text => {
- res(text);
- });
- });
- },
-
$notify(message) {
this.$root.new(Notification, {
message
diff --git a/src/client/app/desktop/views/components/drive.file.vue b/src/client/app/desktop/views/components/drive.file.vue
index 3a7181bf06..1e49f3cb47 100644
--- a/src/client/app/desktop/views/components/drive.file.vue
+++ b/src/client/app/desktop/views/components/drive.file.vue
@@ -148,12 +148,15 @@ export default Vue.extend({
},
rename() {
- this.$input({
+ this.$root.dialog({
title: this.$t('contextmenu.rename-file'),
- placeholder: this.$t('contextmenu.input-new-file-name'),
- default: this.file.name,
- allowEmpty: false
- }).then(name => {
+ input: {
+ placeholder: this.$t('contextmenu.input-new-file-name'),
+ default: this.file.name,
+ allowEmpty: false
+ }
+ }).then(({ canceled, result: name }) => {
+ if (canceled) return;
this.$root.api('drive/files/update', {
fileId: this.file.id,
name: name
diff --git a/src/client/app/desktop/views/components/drive.folder.vue b/src/client/app/desktop/views/components/drive.folder.vue
index 783c9f1519..20d962015d 100644
--- a/src/client/app/desktop/views/components/drive.folder.vue
+++ b/src/client/app/desktop/views/components/drive.folder.vue
@@ -192,11 +192,14 @@ export default Vue.extend({
},
rename() {
- this.$input({
+ this.$root.dialog({
title: this.$t('contextmenu.rename-folder'),
- placeholder: this.$t('contextmenu.input-new-folder-name'),
- default: this.folder.name
- }).then(name => {
+ input: {
+ placeholder: this.$t('contextmenu.input-new-folder-name'),
+ default: this.folder.name
+ }
+ }).then(({ canceled, result: name }) => {
+ if (canceled) return;
this.$root.api('drive/folders/update', {
folderId: this.folder.id,
name: name
diff --git a/src/client/app/desktop/views/components/drive.vue b/src/client/app/desktop/views/components/drive.vue
index 52b84fc0c8..068d8a8449 100644
--- a/src/client/app/desktop/views/components/drive.vue
+++ b/src/client/app/desktop/views/components/drive.vue
@@ -331,10 +331,13 @@ export default Vue.extend({
},
urlUpload() {
- this.$input({
+ this.$root.dialog({
title: this.$t('url-upload'),
- placeholder: this.$t('url-of-file')
- }).then(url => {
+ input: {
+ placeholder: this.$t('url-of-file')
+ }
+ }).then(({ canceled, result: url }) => {
+ if (canceled) return;
this.$root.api('drive/files/upload_from_url', {
url: url,
folderId: this.folder ? this.folder.id : undefined
@@ -348,10 +351,13 @@ export default Vue.extend({
},
createFolder() {
- this.$input({
+ this.$root.dialog({
title: this.$t('create-folder'),
- placeholder: this.$t('folder-name')
- }).then(name => {
+ input: {
+ placeholder: this.$t('folder-name')
+ }
+ }).then(({ canceled, result: name }) => {
+ if (canceled) return;
this.$root.api('drive/folders/create', {
name: name,
parentId: this.folder ? this.folder.id : undefined
diff --git a/src/client/app/desktop/views/components/input-dialog.vue b/src/client/app/desktop/views/components/input-dialog.vue
deleted file mode 100644
index d08410e36d..0000000000
--- a/src/client/app/desktop/views/components/input-dialog.vue
+++ /dev/null
@@ -1,180 +0,0 @@
-
-
-
- {{ title }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/client/app/desktop/views/components/post-form.vue b/src/client/app/desktop/views/components/post-form.vue
index 3c1b53e146..3099112846 100644
--- a/src/client/app/desktop/views/components/post-form.vue
+++ b/src/client/app/desktop/views/components/post-form.vue
@@ -384,13 +384,12 @@ export default Vue.extend({
},
addVisibleUser() {
- this.$input({
- title: this.$t('enter-username')
- }).then(acct => {
- if (acct.startsWith('@')) acct = acct.substr(1);
- this.$root.api('users/show', parseAcct(acct)).then(user => {
- this.visibleUsers.push(user);
- });
+ this.$root.dialog({
+ title: this.$t('enter-username'),
+ user: true
+ }).then(({ canceled, result: user }) => {
+ if (canceled) return;
+ this.visibleUsers.push(user);
});
},
diff --git a/src/client/app/desktop/views/components/settings.2fa.vue b/src/client/app/desktop/views/components/settings.2fa.vue
index e106038f03..dae07778f2 100644
--- a/src/client/app/desktop/views/components/settings.2fa.vue
+++ b/src/client/app/desktop/views/components/settings.2fa.vue
@@ -35,10 +35,13 @@ export default Vue.extend({
},
methods: {
register() {
- this.$input({
+ this.$root.dialog({
title: this.$t('enter-password'),
- type: 'password'
- }).then(password => {
+ input: {
+ type: 'password'
+ }
+ }).then(({ canceled, result: password }) => {
+ if (canceled) return;
this.$root.api('i/2fa/register', {
password: password
}).then(data => {
@@ -48,10 +51,13 @@ export default Vue.extend({
},
unregister() {
- this.$input({
+ this.$root.dialog({
title: this.$t('enter-password'),
- type: 'password'
- }).then(password => {
+ input: {
+ type: 'password'
+ }
+ }).then(({ canceled, result: password }) => {
+ if (canceled) return;
this.$root.api('i/2fa/unregister', {
password: password
}).then(() => {
diff --git a/src/client/app/desktop/views/components/timeline.vue b/src/client/app/desktop/views/components/timeline.vue
index 410b4e25f7..b3405fa371 100644
--- a/src/client/app/desktop/views/components/timeline.vue
+++ b/src/client/app/desktop/views/components/timeline.vue
@@ -109,9 +109,11 @@ export default Vue.extend({
icon: 'plus',
text: this.$t('add-list'),
action: () => {
- this.$input({
+ this.$root.dialog({
title: this.$t('list-name'),
- }).then(async title => {
+ input: true
+ }).then(async ({ canceled, result: title }) => {
+ if (canceled) return;
const list = await this.$root.api('users/lists/create', {
title
});
diff --git a/src/client/app/desktop/views/components/user-lists-window.vue b/src/client/app/desktop/views/components/user-lists-window.vue
index 0677bbe742..89a0d7b9e3 100644
--- a/src/client/app/desktop/views/components/user-lists-window.vue
+++ b/src/client/app/desktop/views/components/user-lists-window.vue
@@ -29,9 +29,11 @@ export default Vue.extend({
},
methods: {
add() {
- this.$input({
+ this.$root.dialog({
title: this.$t('list-name'),
- }).then(async title => {
+ input: true
+ }).then(async ({ canceled, result: title }) => {
+ if (canceled) return;
const list = await this.$root.api('users/lists/create', {
title
});
diff --git a/src/client/app/desktop/views/pages/deck/deck.column.vue b/src/client/app/desktop/views/pages/deck/deck.column.vue
index ead5ee2bdb..bb3f0d8c18 100644
--- a/src/client/app/desktop/views/pages/deck/deck.column.vue
+++ b/src/client/app/desktop/views/pages/deck/deck.column.vue
@@ -167,11 +167,14 @@ export default Vue.extend({
icon: 'pencil-alt',
text: this.$t('rename'),
action: () => {
- this.$input({
+ this.$root.dialog({
title: this.$t('rename'),
- default: this.name,
- allowEmpty: false
- }).then(name => {
+ input: {
+ default: this.name,
+ allowEmpty: false
+ }
+ }).then(({ canceled, result: name }) => {
+ if (canceled) return;
this.$store.dispatch('settings/renameDeckColumn', { id: this.column.id, name });
});
}
diff --git a/src/client/app/desktop/views/pages/deck/deck.vue b/src/client/app/desktop/views/pages/deck/deck.vue
index 533cec8130..885f72a044 100644
--- a/src/client/app/desktop/views/pages/deck/deck.vue
+++ b/src/client/app/desktop/views/pages/deck/deck.vue
@@ -252,9 +252,11 @@ export default Vue.extend({
icon: 'hashtag',
text: this.$t('@deck.hashtag'),
action: () => {
- this.$input({
- title: this.$t('enter-hashtag-tl-title')
- }).then(title => {
+ this.$root.dialog({
+ title: this.$t('enter-hashtag-tl-title'),
+ input: true
+ }).then(({ canceled, result: title }) => {
+ if (canceled) return;
this.$store.dispatch('settings/addDeckColumn', {
id: uuid(),
type: 'hashtag',
diff --git a/src/client/app/desktop/views/pages/user/user.profile.vue b/src/client/app/desktop/views/pages/user/user.profile.vue
index 974297cb03..58afed4001 100644
--- a/src/client/app/desktop/views/pages/user/user.profile.vue
+++ b/src/client/app/desktop/views/pages/user/user.profile.vue
@@ -77,8 +77,8 @@ export default Vue.extend({
type: 'warning',
text: this.$t('block-confirm'),
showCancelButton: true
- }).then(res => {
- if (!res) return;
+ }).then(({ canceled }) => {
+ if (canceled) return;
this.$root.api('blocking/create', {
userId: this.user.id
diff --git a/src/client/app/init.ts b/src/client/app/init.ts
index ee68485992..ae6e2f48ba 100644
--- a/src/client/app/init.ts
+++ b/src/client/app/init.ts
@@ -460,8 +460,8 @@ export default (callback: (launch: (router: VueRouter) => [Vue, MiOS]) => void,
dialog(opts) {
return new Promise((res) => {
const vm = this.new(Dialog, opts);
- vm.$once('ok', result => res(result));
- vm.$once('cancel', () => res(false));
+ vm.$once('ok', result => res({ canceled: false, result }));
+ vm.$once('cancel', () => res({ canceled: true }));
});
}
},
diff --git a/src/client/app/mobile/script.ts b/src/client/app/mobile/script.ts
index a51e87c6aa..7fe3ab05d9 100644
--- a/src/client/app/mobile/script.ts
+++ b/src/client/app/mobile/script.ts
@@ -95,15 +95,6 @@ init((launch) => {
});
},
- $input(opts) {
- return new Promise((res, rej) => {
- const x = window.prompt(opts.title);
- if (x) {
- res(x);
- }
- });
- },
-
$notify(message) {
alert(message);
}
diff --git a/src/client/app/mobile/views/pages/notifications.vue b/src/client/app/mobile/views/pages/notifications.vue
index a7271162d1..69f7b902c8 100644
--- a/src/client/app/mobile/views/pages/notifications.vue
+++ b/src/client/app/mobile/views/pages/notifications.vue
@@ -27,8 +27,8 @@ export default Vue.extend({
type: 'warning',
text: this.$t('read-all'),
showCancelButton: true
- }).then(res => {
- if (!res) return;
+ }).then(({ canceled }) => {
+ if (canceled) return;
this.$root.api('notifications/mark_all_as_read');
});
diff --git a/src/client/app/mobile/views/pages/user-lists.vue b/src/client/app/mobile/views/pages/user-lists.vue
index 2222a22487..dc9d47de3c 100644
--- a/src/client/app/mobile/views/pages/user-lists.vue
+++ b/src/client/app/mobile/views/pages/user-lists.vue
@@ -38,9 +38,11 @@ export default Vue.extend({
},
methods: {
fn() {
- this.$input({
+ this.$root.dialog({
title: this.$t('enter-list-name'),
- }).then(async title => {
+ input: true
+ }).then(async ({ canceled, result: title }) => {
+ if (canceled) return;
const list = await this.$root.api('users/lists/create', {
title
});
diff --git a/src/client/app/mobile/views/pages/user.vue b/src/client/app/mobile/views/pages/user.vue
index afef398acf..15c5fbb9ad 100644
--- a/src/client/app/mobile/views/pages/user.vue
+++ b/src/client/app/mobile/views/pages/user.vue
@@ -120,7 +120,7 @@ export default Vue.extend({
text: this.$t('push-to-list'),
action: async () => {
const lists = await this.$root.api('users/lists/list');
- const listId = await this.$root.dialog({
+ const { canceled, result: listId } = await this.$root.dialog({
type: null,
title: this.$t('select-list'),
select: {
@@ -130,7 +130,7 @@ export default Vue.extend({
},
showCancelButton: true
});
- if (!listId) return;
+ if (canceled) return;
await this.$root.api('users/lists/push', {
listId: listId,
userId: this.user.id