mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-10 14:33:08 +02:00
Improve input dialog
This commit is contained in:
parent
3a2dc95850
commit
1653977392
26 changed files with 201 additions and 318 deletions
|
@ -52,8 +52,8 @@ export default Vue.extend({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
text: this.$t('_remove.are-you-sure').replace('$1', this.announcements.find((_, j) => j == i).title),
|
text: this.$t('_remove.are-you-sure').replace('$1', this.announcements.find((_, j) => j == i).title),
|
||||||
showCancelButton: true
|
showCancelButton: true
|
||||||
}).then(res => {
|
}).then(({ canceled }) => {
|
||||||
if (!res) return;
|
if (canceled) return;
|
||||||
this.announcements = this.announcements.filter((_, j) => j !== i);
|
this.announcements = this.announcements.filter((_, j) => j !== i);
|
||||||
this.save(true);
|
this.save(true);
|
||||||
this.$root.dialog({
|
this.$root.dialog({
|
||||||
|
|
|
@ -120,8 +120,8 @@ export default Vue.extend({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
text: this.$t('remove-emoji.are-you-sure').replace('$1', emoji.name),
|
text: this.$t('remove-emoji.are-you-sure').replace('$1', emoji.name),
|
||||||
showCancelButton: true
|
showCancelButton: true
|
||||||
}).then(res => {
|
}).then(({ canceled }) => {
|
||||||
if (!res) return;
|
if (canceled) return;
|
||||||
|
|
||||||
this.$root.api('admin/emoji/remove', {
|
this.$root.api('admin/emoji/remove', {
|
||||||
id: emoji.id
|
id: emoji.id
|
||||||
|
|
|
@ -50,10 +50,13 @@ export default Vue.extend({
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
regenerateToken() {
|
regenerateToken() {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('enter-password'),
|
title: this.$t('enter-password'),
|
||||||
type: 'password'
|
input: {
|
||||||
}).then(password => {
|
type: 'password'
|
||||||
|
}
|
||||||
|
}).then(({ canceled, result: password }) => {
|
||||||
|
if (canceled) return;
|
||||||
this.$root.api('i/regenerate_token', {
|
this.$root.api('i/regenerate_token', {
|
||||||
password: password
|
password: password
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,15 +2,17 @@
|
||||||
<div class="felqjxyj" :class="{ splash }">
|
<div class="felqjxyj" :class="{ splash }">
|
||||||
<div class="bg" ref="bg" @click="onBgClick"></div>
|
<div class="bg" ref="bg" @click="onBgClick"></div>
|
||||||
<div class="main" ref="main">
|
<div class="main" ref="main">
|
||||||
<div class="icon" v-if="type" :class="type"><fa :icon="icon"/></div>
|
<div class="icon" v-if="!input && !select && !user" :class="type"><fa :icon="icon"/></div>
|
||||||
<header v-if="title" v-html="title"></header>
|
<header v-if="title" v-html="title"></header>
|
||||||
<div class="body" v-if="text" v-html="text"></div>
|
<div class="body" v-if="text" v-html="text"></div>
|
||||||
|
<ui-input v-if="input" v-model="inputValue" autofocus :type="input.type || 'text'" :placeholder="input.placeholder" @keydown="onInputKeydown"></ui-input>
|
||||||
|
<ui-input v-if="user" v-model="userInputValue" autofocus @keydown="onInputKeydown"><span slot="prefix">@</span></ui-input>
|
||||||
<ui-select v-if="select" v-model="selectedValue">
|
<ui-select v-if="select" v-model="selectedValue">
|
||||||
<option v-for="item in select.items" :value="item.value">{{ item.text }}</option>
|
<option v-for="item in select.items" :value="item.value">{{ item.text }}</option>
|
||||||
</ui-select>
|
</ui-select>
|
||||||
<ui-horizon-group no-grow class="buttons fit-bottom" v-if="!splash">
|
<ui-horizon-group no-grow class="buttons fit-bottom" v-if="!splash">
|
||||||
<ui-button @click="ok" primary autofocus>OK</ui-button>
|
<ui-button @click="ok" primary :autofocus="!input && !select && !user">OK</ui-button>
|
||||||
<ui-button @click="cancel" v-if="showCancelButton">Cancel</ui-button>
|
<ui-button @click="cancel" v-if="showCancelButton || input || select || user">Cancel</ui-button>
|
||||||
</ui-horizon-group>
|
</ui-horizon-group>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,6 +22,7 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import * as anime from 'animejs';
|
import * as anime from 'animejs';
|
||||||
import { faTimesCircle, faQuestionCircle } from '@fortawesome/free-regular-svg-icons';
|
import { faTimesCircle, faQuestionCircle } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
import parseAcct from "../../../../../misc/acct/parse";
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: {
|
props: {
|
||||||
|
@ -36,9 +39,15 @@ export default Vue.extend({
|
||||||
type: String,
|
type: String,
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
|
input: {
|
||||||
|
required: false
|
||||||
|
},
|
||||||
select: {
|
select: {
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
|
user: {
|
||||||
|
required: false
|
||||||
|
},
|
||||||
showCancelButton: {
|
showCancelButton: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
@ -51,6 +60,8 @@ export default Vue.extend({
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
inputValue: this.input && this.input.default ? this.input.default : null,
|
||||||
|
userInputValue: null,
|
||||||
selectedValue: null
|
selectedValue: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -94,10 +105,21 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
ok() {
|
async ok() {
|
||||||
const result = this.select ? this.selectedValue : true;
|
if (this.user) {
|
||||||
this.$emit('ok', result);
|
const user = await this.$root.api('users/show', parseAcct(this.userInputValue));
|
||||||
this.close();
|
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() {
|
cancel() {
|
||||||
|
@ -127,6 +149,14 @@ export default Vue.extend({
|
||||||
|
|
||||||
onBgClick() {
|
onBgClick() {
|
||||||
this.cancel();
|
this.cancel();
|
||||||
|
},
|
||||||
|
|
||||||
|
onInputKeydown(e) {
|
||||||
|
if (e.which == 13) { // Enter
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
this.ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -99,23 +99,22 @@ export default Vue.extend({
|
||||||
this.$emit('go', game);
|
this.$emit('go', game);
|
||||||
},
|
},
|
||||||
|
|
||||||
match() {
|
async match() {
|
||||||
this.$input({
|
const { result: user } = await this.$root.dialog({
|
||||||
title: this.$t('enter-username')
|
title: this.$t('enter-username'),
|
||||||
}).then(username => {
|
user: {
|
||||||
this.$root.api('users/show', {
|
local: true
|
||||||
username
|
}
|
||||||
}).then(user => {
|
});
|
||||||
this.$root.api('games/reversi/match', {
|
if (user == null) return;
|
||||||
userId: user.id
|
this.$root.api('games/reversi/match', {
|
||||||
}).then(res => {
|
userId: user.id
|
||||||
if (res == null) {
|
}).then(res => {
|
||||||
this.$emit('matching', user);
|
if (res == null) {
|
||||||
} else {
|
this.$emit('matching', user);
|
||||||
this.$emit('go', res);
|
} else {
|
||||||
}
|
this.$emit('go', res);
|
||||||
});
|
}
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,8 @@ export default Vue.extend({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
text: this.$t('delete-confirm'),
|
text: this.$t('delete-confirm'),
|
||||||
showCancelButton: true
|
showCancelButton: true
|
||||||
}).then(res => {
|
}).then(({ canceled }) => {
|
||||||
if (!res) return;
|
if (canceled) return;
|
||||||
|
|
||||||
this.$root.api('notes/delete', {
|
this.$root.api('notes/delete', {
|
||||||
noteId: this.note.id
|
noteId: this.note.id
|
||||||
|
|
|
@ -11,34 +11,43 @@ import i18n from '../../../i18n';
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
i18n: i18n('common/views/components/password-settings.vue'),
|
i18n: i18n('common/views/components/password-settings.vue'),
|
||||||
methods: {
|
methods: {
|
||||||
reset() {
|
async reset() {
|
||||||
this.$input({
|
const { canceled: canceled1, result: currentPassword } = await this.$root.dialog({
|
||||||
title: this.$t('enter-current-password'),
|
title: this.$t('enter-current-password'),
|
||||||
type: 'password'
|
input: {
|
||||||
}).then(currentPassword => {
|
|
||||||
this.$input({
|
|
||||||
title: this.$t('enter-new-password'),
|
|
||||||
type: 'password'
|
type: 'password'
|
||||||
}).then(newPassword => {
|
}
|
||||||
this.$input({
|
});
|
||||||
title: this.$t('enter-new-password-again'),
|
if (canceled1) return;
|
||||||
type: 'password'
|
|
||||||
}).then(newPassword2 => {
|
const { canceled: canceled2, result: newPassword } = await this.$root.dialog({
|
||||||
if (newPassword !== newPassword2) {
|
title: this.$t('enter-new-password'),
|
||||||
this.$root.dialog({
|
input: {
|
||||||
title: null,
|
type: 'password'
|
||||||
text: this.$t('not-match')
|
}
|
||||||
});
|
});
|
||||||
return;
|
if (canceled2) return;
|
||||||
}
|
|
||||||
this.$root.api('i/change_password', {
|
const { canceled: canceled3, result: newPassword2 } = await this.$root.dialog({
|
||||||
currentPasword: currentPassword,
|
title: this.$t('enter-new-password-again'),
|
||||||
newPassword: newPassword
|
input: {
|
||||||
}).then(() => {
|
type: 'password'
|
||||||
this.$notify(this.$t('changed'));
|
}
|
||||||
});
|
});
|
||||||
});
|
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'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,10 +222,13 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
updateEmail() {
|
updateEmail() {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('@.enter-password'),
|
title: this.$t('@.enter-password'),
|
||||||
type: 'password'
|
input: {
|
||||||
}).then(password => {
|
type: 'password'
|
||||||
|
}
|
||||||
|
}).then(({ canceled, result: password }) => {
|
||||||
|
if (canceled) return;
|
||||||
this.$root.api('i/update_email', {
|
this.$root.api('i/update_email', {
|
||||||
password: password,
|
password: password,
|
||||||
email: this.email == '' ? null : this.email
|
email: this.email == '' ? null : this.email
|
||||||
|
|
|
@ -14,17 +14,19 @@
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:required="required"
|
:required="required"
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
|
:placeholder="placeholder"
|
||||||
:pattern="pattern"
|
:pattern="pattern"
|
||||||
:autocomplete="autocomplete"
|
:autocomplete="autocomplete"
|
||||||
:spellcheck="spellcheck"
|
:spellcheck="spellcheck"
|
||||||
@focus="focused = true"
|
@focus="focused = true"
|
||||||
@blur="focused = false"
|
@blur="focused = false"
|
||||||
|
@keydown="$emit('keydown', $event)"
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<input ref="input"
|
<input ref="input"
|
||||||
type="text"
|
type="text"
|
||||||
:value="placeholder"
|
:value="filePlaceholder"
|
||||||
readonly
|
readonly
|
||||||
@click="chooseFile"
|
@click="chooseFile"
|
||||||
>
|
>
|
||||||
|
@ -74,6 +76,15 @@ export default Vue.extend({
|
||||||
type: String,
|
type: String,
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
autofocus: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
autocomplete: {
|
autocomplete: {
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
|
@ -109,7 +120,7 @@ export default Vue.extend({
|
||||||
filled(): boolean {
|
filled(): boolean {
|
||||||
return this.v != '' && this.v != null;
|
return this.v != '' && this.v != null;
|
||||||
},
|
},
|
||||||
placeholder(): string {
|
filePlaceholder(): string {
|
||||||
if (this.type != 'file') return null;
|
if (this.type != 'file') return null;
|
||||||
if (this.v == null) return null;
|
if (this.v == null) return null;
|
||||||
|
|
||||||
|
@ -142,6 +153,12 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
if (this.autofocus) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.input.focus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (this.$refs.prefix) {
|
if (this.$refs.prefix) {
|
||||||
this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px';
|
this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px';
|
||||||
|
|
|
@ -34,7 +34,6 @@ import PostFormWindow from './views/components/post-form-window.vue';
|
||||||
import RenoteFormWindow from './views/components/renote-form-window.vue';
|
import RenoteFormWindow from './views/components/renote-form-window.vue';
|
||||||
import MkChooseFileFromDriveWindow from './views/components/choose-file-from-drive-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 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 Notification from './views/components/ui-notification.vue';
|
||||||
|
|
||||||
import { url } from '../config';
|
import { url } from '../config';
|
||||||
|
@ -113,22 +112,6 @@ init(async (launch) => {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
$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) {
|
$notify(message) {
|
||||||
this.$root.new(Notification, {
|
this.$root.new(Notification, {
|
||||||
message
|
message
|
||||||
|
|
|
@ -148,12 +148,15 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
rename() {
|
rename() {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('contextmenu.rename-file'),
|
title: this.$t('contextmenu.rename-file'),
|
||||||
placeholder: this.$t('contextmenu.input-new-file-name'),
|
input: {
|
||||||
default: this.file.name,
|
placeholder: this.$t('contextmenu.input-new-file-name'),
|
||||||
allowEmpty: false
|
default: this.file.name,
|
||||||
}).then(name => {
|
allowEmpty: false
|
||||||
|
}
|
||||||
|
}).then(({ canceled, result: name }) => {
|
||||||
|
if (canceled) return;
|
||||||
this.$root.api('drive/files/update', {
|
this.$root.api('drive/files/update', {
|
||||||
fileId: this.file.id,
|
fileId: this.file.id,
|
||||||
name: name
|
name: name
|
||||||
|
|
|
@ -192,11 +192,14 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
rename() {
|
rename() {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('contextmenu.rename-folder'),
|
title: this.$t('contextmenu.rename-folder'),
|
||||||
placeholder: this.$t('contextmenu.input-new-folder-name'),
|
input: {
|
||||||
default: this.folder.name
|
placeholder: this.$t('contextmenu.input-new-folder-name'),
|
||||||
}).then(name => {
|
default: this.folder.name
|
||||||
|
}
|
||||||
|
}).then(({ canceled, result: name }) => {
|
||||||
|
if (canceled) return;
|
||||||
this.$root.api('drive/folders/update', {
|
this.$root.api('drive/folders/update', {
|
||||||
folderId: this.folder.id,
|
folderId: this.folder.id,
|
||||||
name: name
|
name: name
|
||||||
|
|
|
@ -331,10 +331,13 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
urlUpload() {
|
urlUpload() {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('url-upload'),
|
title: this.$t('url-upload'),
|
||||||
placeholder: this.$t('url-of-file')
|
input: {
|
||||||
}).then(url => {
|
placeholder: this.$t('url-of-file')
|
||||||
|
}
|
||||||
|
}).then(({ canceled, result: url }) => {
|
||||||
|
if (canceled) return;
|
||||||
this.$root.api('drive/files/upload_from_url', {
|
this.$root.api('drive/files/upload_from_url', {
|
||||||
url: url,
|
url: url,
|
||||||
folderId: this.folder ? this.folder.id : undefined
|
folderId: this.folder ? this.folder.id : undefined
|
||||||
|
@ -348,10 +351,13 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
createFolder() {
|
createFolder() {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('create-folder'),
|
title: this.$t('create-folder'),
|
||||||
placeholder: this.$t('folder-name')
|
input: {
|
||||||
}).then(name => {
|
placeholder: this.$t('folder-name')
|
||||||
|
}
|
||||||
|
}).then(({ canceled, result: name }) => {
|
||||||
|
if (canceled) return;
|
||||||
this.$root.api('drive/folders/create', {
|
this.$root.api('drive/folders/create', {
|
||||||
name: name,
|
name: name,
|
||||||
parentId: this.folder ? this.folder.id : undefined
|
parentId: this.folder ? this.folder.id : undefined
|
||||||
|
|
|
@ -1,180 +0,0 @@
|
||||||
<template>
|
|
||||||
<mk-window ref="window" is-modal width="500px" @before-close="beforeClose" @closed="destroyDom">
|
|
||||||
<span slot="header" :class="$style.header">
|
|
||||||
<fa icon="i-cursor"/>{{ title }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div :class="$style.body">
|
|
||||||
<input ref="text" v-model="text" :type="type" @keydown="onKeydown" :placeholder="placeholder"/>
|
|
||||||
</div>
|
|
||||||
<div :class="$style.actions">
|
|
||||||
<button :class="$style.cancel" @click="cancel">{{ $t('cancel') }}</button>
|
|
||||||
<button :class="$style.ok" :disabled="!allowEmpty && text.length == 0" @click="ok">{{ $t('ok') }}</button>
|
|
||||||
</div>
|
|
||||||
</mk-window>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import Vue from 'vue';
|
|
||||||
import i18n from '../../../i18n';
|
|
||||||
export default Vue.extend({
|
|
||||||
i18n: i18n('desktop/views/input-dialog.vue'),
|
|
||||||
props: {
|
|
||||||
title: {
|
|
||||||
type: String
|
|
||||||
},
|
|
||||||
placeholder: {
|
|
||||||
type: String
|
|
||||||
},
|
|
||||||
default: {
|
|
||||||
type: String
|
|
||||||
},
|
|
||||||
allowEmpty: {
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
default: 'text'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
done: false,
|
|
||||||
text: ''
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
if (this.default) this.text = this.default;
|
|
||||||
this.$nextTick(() => {
|
|
||||||
(this.$refs.text as any).focus();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
ok() {
|
|
||||||
if (!this.allowEmpty && this.text == '') return;
|
|
||||||
this.done = true;
|
|
||||||
(this.$refs.window as any).close();
|
|
||||||
},
|
|
||||||
cancel() {
|
|
||||||
this.done = false;
|
|
||||||
(this.$refs.window as any).close();
|
|
||||||
},
|
|
||||||
beforeClose() {
|
|
||||||
if (this.done) {
|
|
||||||
this.$emit('done', this.text);
|
|
||||||
} else {
|
|
||||||
this.$emit('canceled');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onKeydown(e) {
|
|
||||||
if (e.which == 13) { // Enter
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
this.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<style lang="stylus" module>
|
|
||||||
.header
|
|
||||||
> [data-icon]
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
.body
|
|
||||||
padding 16px
|
|
||||||
|
|
||||||
> input
|
|
||||||
display block
|
|
||||||
padding 8px
|
|
||||||
margin 0
|
|
||||||
width 100%
|
|
||||||
max-width 100%
|
|
||||||
min-width 100%
|
|
||||||
font-size 1em
|
|
||||||
color #333
|
|
||||||
background #fff
|
|
||||||
outline none
|
|
||||||
border solid 1px var(--primaryAlpha01)
|
|
||||||
border-radius 4px
|
|
||||||
transition border-color .3s ease
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
border-color var(--primaryAlpha02)
|
|
||||||
transition border-color .1s ease
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
color var(--primary)
|
|
||||||
border-color var(--primaryAlpha05)
|
|
||||||
transition border-color 0s ease
|
|
||||||
|
|
||||||
&::-webkit-input-placeholder
|
|
||||||
color var(--primaryAlpha03)
|
|
||||||
|
|
||||||
.actions
|
|
||||||
height 72px
|
|
||||||
background var(--primaryLighten95)
|
|
||||||
|
|
||||||
.ok
|
|
||||||
.cancel
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
bottom 16px
|
|
||||||
cursor pointer
|
|
||||||
padding 0
|
|
||||||
margin 0
|
|
||||||
width 120px
|
|
||||||
height 40px
|
|
||||||
font-size 1em
|
|
||||||
outline none
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
position absolute
|
|
||||||
top -5px
|
|
||||||
right -5px
|
|
||||||
bottom -5px
|
|
||||||
left -5px
|
|
||||||
border 2px solid var(--primaryAlpha03)
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
&:disabled
|
|
||||||
opacity 0.7
|
|
||||||
cursor default
|
|
||||||
|
|
||||||
.ok
|
|
||||||
right 16px
|
|
||||||
color var(--primaryForeground)
|
|
||||||
background linear-gradient(to bottom, var(--primaryLighten25) 0%, var(--primaryLighten10) 100%)
|
|
||||||
border solid 1px var(--primaryLighten15)
|
|
||||||
|
|
||||||
&:not(:disabled)
|
|
||||||
font-weight bold
|
|
||||||
|
|
||||||
&:hover:not(:disabled)
|
|
||||||
background linear-gradient(to bottom, var(--primaryLighten8) 0%, var(--primaryDarken8) 100%)
|
|
||||||
border-color var(--primary)
|
|
||||||
|
|
||||||
&:active:not(:disabled)
|
|
||||||
background var(--primary)
|
|
||||||
border-color var(--primary)
|
|
||||||
|
|
||||||
.cancel
|
|
||||||
right 148px
|
|
||||||
color #888
|
|
||||||
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
|
|
||||||
border solid 1px #e2e2e2
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
|
|
||||||
border-color #dcdcdc
|
|
||||||
|
|
||||||
&:active
|
|
||||||
background #ececec
|
|
||||||
border-color #dcdcdc
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -384,13 +384,12 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
addVisibleUser() {
|
addVisibleUser() {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('enter-username')
|
title: this.$t('enter-username'),
|
||||||
}).then(acct => {
|
user: true
|
||||||
if (acct.startsWith('@')) acct = acct.substr(1);
|
}).then(({ canceled, result: user }) => {
|
||||||
this.$root.api('users/show', parseAcct(acct)).then(user => {
|
if (canceled) return;
|
||||||
this.visibleUsers.push(user);
|
this.visibleUsers.push(user);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,13 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
register() {
|
register() {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('enter-password'),
|
title: this.$t('enter-password'),
|
||||||
type: 'password'
|
input: {
|
||||||
}).then(password => {
|
type: 'password'
|
||||||
|
}
|
||||||
|
}).then(({ canceled, result: password }) => {
|
||||||
|
if (canceled) return;
|
||||||
this.$root.api('i/2fa/register', {
|
this.$root.api('i/2fa/register', {
|
||||||
password: password
|
password: password
|
||||||
}).then(data => {
|
}).then(data => {
|
||||||
|
@ -48,10 +51,13 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
unregister() {
|
unregister() {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('enter-password'),
|
title: this.$t('enter-password'),
|
||||||
type: 'password'
|
input: {
|
||||||
}).then(password => {
|
type: 'password'
|
||||||
|
}
|
||||||
|
}).then(({ canceled, result: password }) => {
|
||||||
|
if (canceled) return;
|
||||||
this.$root.api('i/2fa/unregister', {
|
this.$root.api('i/2fa/unregister', {
|
||||||
password: password
|
password: password
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
|
|
@ -109,9 +109,11 @@ export default Vue.extend({
|
||||||
icon: 'plus',
|
icon: 'plus',
|
||||||
text: this.$t('add-list'),
|
text: this.$t('add-list'),
|
||||||
action: () => {
|
action: () => {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('list-name'),
|
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', {
|
const list = await this.$root.api('users/lists/create', {
|
||||||
title
|
title
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,9 +29,11 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
add() {
|
add() {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('list-name'),
|
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', {
|
const list = await this.$root.api('users/lists/create', {
|
||||||
title
|
title
|
||||||
});
|
});
|
||||||
|
|
|
@ -167,11 +167,14 @@ export default Vue.extend({
|
||||||
icon: 'pencil-alt',
|
icon: 'pencil-alt',
|
||||||
text: this.$t('rename'),
|
text: this.$t('rename'),
|
||||||
action: () => {
|
action: () => {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('rename'),
|
title: this.$t('rename'),
|
||||||
default: this.name,
|
input: {
|
||||||
allowEmpty: false
|
default: this.name,
|
||||||
}).then(name => {
|
allowEmpty: false
|
||||||
|
}
|
||||||
|
}).then(({ canceled, result: name }) => {
|
||||||
|
if (canceled) return;
|
||||||
this.$store.dispatch('settings/renameDeckColumn', { id: this.column.id, name });
|
this.$store.dispatch('settings/renameDeckColumn', { id: this.column.id, name });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,9 +252,11 @@ export default Vue.extend({
|
||||||
icon: 'hashtag',
|
icon: 'hashtag',
|
||||||
text: this.$t('@deck.hashtag'),
|
text: this.$t('@deck.hashtag'),
|
||||||
action: () => {
|
action: () => {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('enter-hashtag-tl-title')
|
title: this.$t('enter-hashtag-tl-title'),
|
||||||
}).then(title => {
|
input: true
|
||||||
|
}).then(({ canceled, result: title }) => {
|
||||||
|
if (canceled) return;
|
||||||
this.$store.dispatch('settings/addDeckColumn', {
|
this.$store.dispatch('settings/addDeckColumn', {
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
type: 'hashtag',
|
type: 'hashtag',
|
||||||
|
|
|
@ -77,8 +77,8 @@ export default Vue.extend({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
text: this.$t('block-confirm'),
|
text: this.$t('block-confirm'),
|
||||||
showCancelButton: true
|
showCancelButton: true
|
||||||
}).then(res => {
|
}).then(({ canceled }) => {
|
||||||
if (!res) return;
|
if (canceled) return;
|
||||||
|
|
||||||
this.$root.api('blocking/create', {
|
this.$root.api('blocking/create', {
|
||||||
userId: this.user.id
|
userId: this.user.id
|
||||||
|
|
|
@ -460,8 +460,8 @@ export default (callback: (launch: (router: VueRouter) => [Vue, MiOS]) => void,
|
||||||
dialog(opts) {
|
dialog(opts) {
|
||||||
return new Promise((res) => {
|
return new Promise((res) => {
|
||||||
const vm = this.new(Dialog, opts);
|
const vm = this.new(Dialog, opts);
|
||||||
vm.$once('ok', result => res(result));
|
vm.$once('ok', result => res({ canceled: false, result }));
|
||||||
vm.$once('cancel', () => res(false));
|
vm.$once('cancel', () => res({ canceled: true }));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -95,15 +95,6 @@ init((launch) => {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
$input(opts) {
|
|
||||||
return new Promise<string>((res, rej) => {
|
|
||||||
const x = window.prompt(opts.title);
|
|
||||||
if (x) {
|
|
||||||
res(x);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
$notify(message) {
|
$notify(message) {
|
||||||
alert(message);
|
alert(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,8 @@ export default Vue.extend({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
text: this.$t('read-all'),
|
text: this.$t('read-all'),
|
||||||
showCancelButton: true
|
showCancelButton: true
|
||||||
}).then(res => {
|
}).then(({ canceled }) => {
|
||||||
if (!res) return;
|
if (canceled) return;
|
||||||
|
|
||||||
this.$root.api('notifications/mark_all_as_read');
|
this.$root.api('notifications/mark_all_as_read');
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,9 +38,11 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fn() {
|
fn() {
|
||||||
this.$input({
|
this.$root.dialog({
|
||||||
title: this.$t('enter-list-name'),
|
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', {
|
const list = await this.$root.api('users/lists/create', {
|
||||||
title
|
title
|
||||||
});
|
});
|
||||||
|
|
|
@ -120,7 +120,7 @@ export default Vue.extend({
|
||||||
text: this.$t('push-to-list'),
|
text: this.$t('push-to-list'),
|
||||||
action: async () => {
|
action: async () => {
|
||||||
const lists = await this.$root.api('users/lists/list');
|
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,
|
type: null,
|
||||||
title: this.$t('select-list'),
|
title: this.$t('select-list'),
|
||||||
select: {
|
select: {
|
||||||
|
@ -130,7 +130,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
showCancelButton: true
|
showCancelButton: true
|
||||||
});
|
});
|
||||||
if (!listId) return;
|
if (canceled) return;
|
||||||
await this.$root.api('users/lists/push', {
|
await this.$root.api('users/lists/push', {
|
||||||
listId: listId,
|
listId: listId,
|
||||||
userId: this.user.id
|
userId: this.user.id
|
||||||
|
|
Loading…
Reference in a new issue