wip
This commit is contained in:
parent
02701d852d
commit
cd79314f69
|
@ -376,7 +376,7 @@ export default defineComponent({
|
||||||
|
|
||||||
chooseUser() {
|
chooseUser() {
|
||||||
this.close();
|
this.close();
|
||||||
const vm = os.popup(MkUserSelect, {});
|
const vm = os.modal(MkUserSelect, {});
|
||||||
vm.$once('selected', user => {
|
vm.$once('selected', user => {
|
||||||
this.complete('user', user);
|
this.complete('user', user);
|
||||||
});
|
});
|
||||||
|
|
|
@ -43,7 +43,7 @@ export default defineComponent({
|
||||||
icon: faCog,
|
icon: faCog,
|
||||||
text: this.$t('notificationSetting'),
|
text: this.$t('notificationSetting'),
|
||||||
action: async () => {
|
action: async () => {
|
||||||
os.popup(await import('../notification-setting-window.vue'), {
|
os.modal(await import('../notification-setting-window.vue'), {
|
||||||
includingTypes: this.column.includingTypes,
|
includingTypes: this.column.includingTypes,
|
||||||
}).$on('ok', async ({ includingTypes }) => {
|
}).$on('ok', async ({ includingTypes }) => {
|
||||||
this.$set(this.column, 'includingTypes', includingTypes);
|
this.$set(this.column, 'includingTypes', includingTypes);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<x-modal @closed="$emit('closed')" @click="onBgClick" :showing="showing">
|
<div class="mk-dialog" :class="{ iconOnly }">
|
||||||
<div class="mk-dialog" :class="{ iconOnly }">
|
|
||||||
<template v-if="type == 'signin'">
|
<template v-if="type == 'signin'">
|
||||||
<mk-signin/>
|
<mk-signin/>
|
||||||
</template>
|
</template>
|
||||||
|
@ -39,8 +38,7 @@
|
||||||
<mk-button v-for="action in actions" inline @click="() => { action.callback(); close(); }" :primary="action.primary" :key="action.text">{{ action.text }}</mk-button>
|
<mk-button v-for="action in actions" inline @click="() => { action.callback(); close(); }" :primary="action.primary" :key="action.text">{{ action.text }}</mk-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</x-modal>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -52,12 +50,10 @@ import MkInput from './ui/input.vue';
|
||||||
import MkSelect from './ui/select.vue';
|
import MkSelect from './ui/select.vue';
|
||||||
import MkSignin from './signin.vue';
|
import MkSignin from './signin.vue';
|
||||||
import parseAcct from '../../misc/acct/parse';
|
import parseAcct from '../../misc/acct/parse';
|
||||||
import XModal from './modal.vue';
|
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
XModal,
|
|
||||||
MkButton,
|
MkButton,
|
||||||
MkInput,
|
MkInput,
|
||||||
MkSelect,
|
MkSelect,
|
||||||
|
@ -65,9 +61,6 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
showing: {
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
|
@ -118,7 +111,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
emits: ['done', 'closed'],
|
emits: ['done'],
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -72,7 +72,7 @@ export default defineComponent({
|
||||||
if (this.$store.state.device.imageNewTab) {
|
if (this.$store.state.device.imageNewTab) {
|
||||||
window.open(this.image.url, '_blank');
|
window.open(this.image.url, '_blank');
|
||||||
} else {
|
} else {
|
||||||
const viewer = os.popup(ImageViewer, {
|
const viewer = os.modal(ImageViewer, {
|
||||||
image: this.image
|
image: this.image
|
||||||
});
|
});
|
||||||
this.$once('hook:beforeDestroy', () => {
|
this.$once('hook:beforeDestroy', () => {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<x-modal :source="source" :no-center="noCenter" @click="close()" @closed="$emit('closed')" :showing="showing">
|
<div class="rrevdjwt" :class="{ left: align === 'left' }" ref="items" :style="{ width: width + 'px' }">
|
||||||
<div class="rrevdjwt" :class="{ left: align === 'left' }" ref="items" :style="{ width: width + 'px' }">
|
|
||||||
<template v-for="(item, i) in items.filter(item => item !== undefined)">
|
<template v-for="(item, i) in items.filter(item => item !== undefined)">
|
||||||
<div v-if="item === null" class="divider" :key="i"></div>
|
<div v-if="item === null" class="divider" :key="i"></div>
|
||||||
<span v-else-if="item.type === 'label'" class="label item" :key="i">
|
<span v-else-if="item.type === 'label'" class="label item" :key="i">
|
||||||
|
@ -28,28 +27,17 @@
|
||||||
<i v-if="item.indicate"><fa :icon="faCircle"/></i>
|
<i v-if="item.indicate"><fa :icon="faCircle"/></i>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</x-modal>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { faCircle } from '@fortawesome/free-solid-svg-icons';
|
import { faCircle } from '@fortawesome/free-solid-svg-icons';
|
||||||
import XModal from './modal.vue';
|
|
||||||
import { focusPrev, focusNext } from '@/scripts/focus';
|
import { focusPrev, focusNext } from '@/scripts/focus';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
|
||||||
XModal
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
showing: {
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
source: {
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
items: {
|
items: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true
|
required: true
|
||||||
|
|
|
@ -18,6 +18,9 @@ import * as os from '@/os';
|
||||||
// memo: 旧popup.vueのfixedプロパティに相当するものはsource要素の祖先を辿るなどして自動で判定できるのでは
|
// memo: 旧popup.vueのfixedプロパティに相当するものはsource要素の祖先を辿るなどして自動で判定できるのでは
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
provide: {
|
||||||
|
modal: true
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
showing: {
|
showing: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -59,6 +62,7 @@ export default defineComponent({
|
||||||
|
|
||||||
const popover = this.$refs.content as any;
|
const popover = this.$refs.content as any;
|
||||||
|
|
||||||
|
new ResizeObserver((entries, observer) => {
|
||||||
const rect = this.source.getBoundingClientRect();
|
const rect = this.source.getBoundingClientRect();
|
||||||
const width = popover.offsetWidth;
|
const width = popover.offsetWidth;
|
||||||
const height = popover.offsetHeight;
|
const height = popover.offsetHeight;
|
||||||
|
@ -111,6 +115,7 @@ export default defineComponent({
|
||||||
|
|
||||||
popover.style.left = left + 'px';
|
popover.style.left = left + 'px';
|
||||||
popover.style.top = top + 'px';
|
popover.style.top = top + 'px';
|
||||||
|
}).observe(popover);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -96,7 +96,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||||
import { faSatelliteDish, faBolt, faTimes, faBullhorn, faStar, faLink, faExternalLinkSquareAlt, faPlus, faMinus, faRetweet, faReply, faReplyAll, faEllipsisH, faHome, faUnlock, faEnvelope, faThumbtack, faBan, faQuoteRight, faInfoCircle, faBiohazard, faPlug } from '@fortawesome/free-solid-svg-icons';
|
import { faSatelliteDish, faBolt, faTimes, faBullhorn, faStar, faLink, faExternalLinkSquareAlt, faPlus, faMinus, faRetweet, faReply, faReplyAll, faEllipsisH, faHome, faUnlock, faEnvelope, faThumbtack, faBan, faQuoteRight, faInfoCircle, faBiohazard, faPlug } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { faCopy, faTrashAlt, faEdit, faEye, faEyeSlash } from '@fortawesome/free-regular-svg-icons';
|
import { faCopy, faTrashAlt, faEdit, faEye, faEyeSlash } from '@fortawesome/free-regular-svg-icons';
|
||||||
import { parse } from '../../mfm/parse';
|
import { parse } from '../../mfm/parse';
|
||||||
|
@ -108,8 +108,6 @@ import XReactionsViewer from './reactions-viewer.vue';
|
||||||
import XMediaList from './media-list.vue';
|
import XMediaList from './media-list.vue';
|
||||||
import XCwButton from './cw-button.vue';
|
import XCwButton from './cw-button.vue';
|
||||||
import XPoll from './poll.vue';
|
import XPoll from './poll.vue';
|
||||||
import MkUrlPreview from './url-preview.vue';
|
|
||||||
import MkReactionPicker from './reaction-picker.vue';
|
|
||||||
import { pleaseLogin } from '@/scripts/please-login';
|
import { pleaseLogin } from '@/scripts/please-login';
|
||||||
import { focusPrev, focusNext } from '@/scripts/focus';
|
import { focusPrev, focusNext } from '@/scripts/focus';
|
||||||
import { url } from '@/config';
|
import { url } from '@/config';
|
||||||
|
@ -133,7 +131,7 @@ export default defineComponent({
|
||||||
XMediaList,
|
XMediaList,
|
||||||
XCwButton,
|
XCwButton,
|
||||||
XPoll,
|
XPoll,
|
||||||
MkUrlPreview,
|
MkUrlPreview: defineAsyncComponent(() => import('@/components/url-preview.vue')),
|
||||||
},
|
},
|
||||||
|
|
||||||
inject: {
|
inject: {
|
||||||
|
@ -485,17 +483,17 @@ export default defineComponent({
|
||||||
react(viaKeyboard = false) {
|
react(viaKeyboard = false) {
|
||||||
pleaseLogin();
|
pleaseLogin();
|
||||||
this.blur();
|
this.blur();
|
||||||
const close = os.popup(MkReactionPicker, {
|
os.modal(defineAsyncComponent(() => import('@/components/reaction-picker.vue')), {
|
||||||
source: this.$refs.reactButton,
|
|
||||||
showFocus: viaKeyboard,
|
showFocus: viaKeyboard,
|
||||||
}, reaction => {
|
}, reaction => {
|
||||||
os.api('notes/reactions/create', {
|
os.api('notes/reactions/create', {
|
||||||
noteId: this.appearNote.id,
|
noteId: this.appearNote.id,
|
||||||
reaction: reaction
|
reaction: reaction
|
||||||
}).then(() => {
|
|
||||||
close();
|
|
||||||
});
|
});
|
||||||
}, this.focus);
|
this.focus();
|
||||||
|
}, {
|
||||||
|
source: this.$refs.reactButton
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
reactDirectly(reaction) {
|
reactDirectly(reaction) {
|
||||||
|
|
|
@ -32,12 +32,11 @@ import { defineComponent } from 'vue';
|
||||||
import paging from '@/scripts/paging';
|
import paging from '@/scripts/paging';
|
||||||
import XNote from './note.vue';
|
import XNote from './note.vue';
|
||||||
import XList from './date-separated-list.vue';
|
import XList from './date-separated-list.vue';
|
||||||
import MkButton from './ui/button.vue';
|
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
XNote, XList, MkButton
|
XNote, XList,
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [
|
mixins: [
|
||||||
|
@ -83,9 +82,9 @@ export default defineComponent({
|
||||||
updated(oldValue, newValue) {
|
updated(oldValue, newValue) {
|
||||||
const i = this.notes.findIndex(n => n === oldValue);
|
const i = this.notes.findIndex(n => n === oldValue);
|
||||||
if (this.prop) {
|
if (this.prop) {
|
||||||
Vue.set(this.items[i], this.prop, newValue);
|
this.items[i][this.prop] = newValue;
|
||||||
} else {
|
} else {
|
||||||
Vue.set(this.items, i, newValue);
|
this.items[i] = newValue;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -57,9 +57,6 @@ import * as os from '@/os';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
destroy: {
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
x: {
|
x: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true
|
required: true
|
||||||
|
@ -94,7 +91,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.destroy();
|
this.$emit('closed');
|
||||||
}, 1100);
|
}, 1100);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,94 +0,0 @@
|
||||||
<template>
|
|
||||||
<x-modal @closed="$emit('closed')" @click="onBgClick" :showing="showing">
|
|
||||||
<x-post-form ref="form" class="ulveipgl"
|
|
||||||
:reply="reply"
|
|
||||||
:renote="renote"
|
|
||||||
:mention="mention"
|
|
||||||
:specified="specified"
|
|
||||||
:initial-text="initialText"
|
|
||||||
:initial-note="initialNote"
|
|
||||||
:instant="instant"
|
|
||||||
@posted="onPosted"
|
|
||||||
@cancel="onCanceled"
|
|
||||||
/>
|
|
||||||
</x-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
import XModal from './modal.vue';
|
|
||||||
import XPostForm from './post-form.vue';
|
|
||||||
import * as os from '@/os';
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
components: {
|
|
||||||
XModal,
|
|
||||||
XPostForm,
|
|
||||||
},
|
|
||||||
|
|
||||||
props: {
|
|
||||||
showing: {
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
reply: {
|
|
||||||
type: Object,
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
renote: {
|
|
||||||
type: Object,
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
mention: {
|
|
||||||
type: Object,
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
specified: {
|
|
||||||
type: Object,
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
initialText: {
|
|
||||||
type: String,
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
initialNote: {
|
|
||||||
type: Object,
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
instant: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
focus() {
|
|
||||||
this.$refs.form.focus();
|
|
||||||
},
|
|
||||||
|
|
||||||
onPosted() {
|
|
||||||
this.$emit('done', 'posted');
|
|
||||||
},
|
|
||||||
|
|
||||||
onCanceled() {
|
|
||||||
this.$emit('done', 'canceled');
|
|
||||||
},
|
|
||||||
|
|
||||||
onKeydown(e) {
|
|
||||||
if (e.which === 27) { // Esc
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
this.$emit('done', 'canceled');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.ulveipgl {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 500px;
|
|
||||||
border-radius: var(--radius);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="gafaadew"
|
<div class="gafaadew" :class="{ modal }"
|
||||||
@dragover.stop="onDragover"
|
@dragover.stop="onDragover"
|
||||||
@dragenter="onDragenter"
|
@dragenter="onDragenter"
|
||||||
@dragleave="onDragleave"
|
@dragleave="onDragleave"
|
||||||
|
@ -80,6 +80,8 @@ export default defineComponent({
|
||||||
XPollEditor: defineAsyncComponent(() => import('./poll-editor.vue'))
|
XPollEditor: defineAsyncComponent(() => import('./poll-editor.vue'))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
inject: ['modal'],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
reply: {
|
reply: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -417,7 +419,7 @@ export default defineComponent({
|
||||||
// TODO: information dialog
|
// TODO: information dialog
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const w = os.popup(MkVisibilityChooser, {
|
const w = os.modal(MkVisibilityChooser, {
|
||||||
source: this.$refs.visibilityButton,
|
source: this.$refs.visibilityButton,
|
||||||
currentVisibility: this.visibility,
|
currentVisibility: this.visibility,
|
||||||
currentLocalOnly: this.localOnly
|
currentLocalOnly: this.localOnly
|
||||||
|
@ -433,7 +435,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
addVisibleUser() {
|
addVisibleUser() {
|
||||||
const vm = os.popup(MkUserSelect, {});
|
const vm = os.modal(MkUserSelect, {});
|
||||||
vm.$once('selected', user => {
|
vm.$once('selected', user => {
|
||||||
this.visibleUsers.push(user);
|
this.visibleUsers.push(user);
|
||||||
});
|
});
|
||||||
|
@ -593,18 +595,18 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
this.$emit('cancel');
|
this.$emit('done');
|
||||||
},
|
},
|
||||||
|
|
||||||
insertMention() {
|
insertMention() {
|
||||||
const vm = os.popup(MkUserSelect, {});
|
const vm = os.modal(MkUserSelect, {});
|
||||||
vm.$once('selected', user => {
|
vm.$once('selected', user => {
|
||||||
insertTextAtCursor(this.$refs.text, getAcct(user) + ' ');
|
insertTextAtCursor(this.$refs.text, getAcct(user) + ' ');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async insertEmoji(ev) {
|
async insertEmoji(ev) {
|
||||||
const vm = os.popup(await import('./emoji-picker.vue'), {
|
const vm = os.modal(await import('./emoji-picker.vue'), {
|
||||||
source: ev.currentTarget || ev.target
|
source: ev.currentTarget || ev.target
|
||||||
}).$once('chosen', emoji => {
|
}).$once('chosen', emoji => {
|
||||||
insertTextAtCursor(this.$refs.text, emoji);
|
insertTextAtCursor(this.$refs.text, emoji);
|
||||||
|
@ -636,6 +638,12 @@ export default defineComponent({
|
||||||
position: relative;
|
position: relative;
|
||||||
background: var(--panel);
|
background: var(--panel);
|
||||||
|
|
||||||
|
&.modal {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
}
|
||||||
|
|
||||||
> header {
|
> header {
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
height: 66px;
|
height: 66px;
|
||||||
|
|
|
@ -1,36 +1,24 @@
|
||||||
<template>
|
<template>
|
||||||
<XModal :source="source" @closed="$emit('closed')" :showing="showing" @click="close" v-hotkey.global="keymap">
|
<div class="rdfaahpb">
|
||||||
<div class="rdfaahpb">
|
|
||||||
<div class="buttons" ref="buttons" :class="{ showFocus }">
|
<div class="buttons" ref="buttons" :class="{ showFocus }">
|
||||||
<button class="_button" v-for="(reaction, i) in rs" :key="reaction" @click="react(reaction)" :tabindex="i + 1" :title="reaction" v-particle><x-reaction-icon :reaction="reaction"/></button>
|
<button class="_button" v-for="(reaction, i) in rs" :key="reaction" @click="react(reaction)" :tabindex="i + 1" :title="reaction" v-particle><x-reaction-icon :reaction="reaction"/></button>
|
||||||
</div>
|
</div>
|
||||||
<input class="text" v-model.trim="text" :placeholder="$t('enterEmoji')" @keyup.enter="reactText" @input="tryReactText" v-autocomplete="{ model: 'text' }">
|
<input class="text" v-model.trim="text" :placeholder="$t('enterEmoji')" @keyup.enter="reactText" @input="tryReactText" v-autocomplete="{ model: 'text' }">
|
||||||
</div>
|
</div>
|
||||||
</XModal>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { emojiRegex } from '../../misc/emoji-regex';
|
import { emojiRegex } from '../../misc/emoji-regex';
|
||||||
import XReactionIcon from './reaction-icon.vue';
|
import XReactionIcon from './reaction-icon.vue';
|
||||||
import XModal from './modal.vue';
|
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
XModal,
|
|
||||||
XReactionIcon,
|
XReactionIcon,
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
showing: {
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
|
|
||||||
source: {
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
|
|
||||||
reactions: {
|
reactions: {
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
|
|
|
@ -111,7 +111,7 @@ export default defineComponent({
|
||||||
|
|
||||||
this.closeDetails();
|
this.closeDetails();
|
||||||
if (!this.isHovering) return;
|
if (!this.isHovering) return;
|
||||||
this.details = os.popup(XDetails, {
|
this.details = os.modal(XDetails, {
|
||||||
reaction: this.reaction,
|
reaction: this.reaction,
|
||||||
users,
|
users,
|
||||||
count: this.count,
|
count: this.count,
|
||||||
|
|
|
@ -276,7 +276,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
async addAcount() {
|
async addAcount() {
|
||||||
os.popup(await import('./signin-dialog.vue')).$once('login', res => {
|
os.modal(await import('./signin-dialog.vue')).$once('login', res => {
|
||||||
this.$store.dispatch('addAcount', res);
|
this.$store.dispatch('addAcount', res);
|
||||||
os.dialog({
|
os.dialog({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
|
@ -286,7 +286,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
async createAccount() {
|
async createAccount() {
|
||||||
os.popup(await import('./signup-dialog.vue')).$once('signup', res => {
|
os.modal(await import('./signup-dialog.vue')).$once('signup', res => {
|
||||||
this.$store.dispatch('addAcount', res);
|
this.$store.dispatch('addAcount', res);
|
||||||
this.switchAccountWithToken(res.i);
|
this.switchAccountWithToken(res.i);
|
||||||
});
|
});
|
||||||
|
|
|
@ -166,7 +166,7 @@ export default defineComponent({
|
||||||
id: notification.id
|
id: notification.id
|
||||||
});
|
});
|
||||||
|
|
||||||
os.popup(await import('@/components/toast.vue'), {
|
os.modal(await import('@/components/toast.vue'), {
|
||||||
notification
|
notification
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -335,7 +335,7 @@ export default defineComponent({
|
||||||
id: notification.id
|
id: notification.id
|
||||||
});
|
});
|
||||||
|
|
||||||
os.popup(await import('@/components/toast.vue'), {
|
os.modal(await import('@/components/toast.vue'), {
|
||||||
notification
|
notification
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, defineAsyncComponent, ref } from 'vue';
|
import { Component, defineAsyncComponent, markRaw, ref } from 'vue';
|
||||||
import Stream from '@/scripts/stream';
|
import Stream from '@/scripts/stream';
|
||||||
import { store } from '@/store';
|
import { store } from '@/store';
|
||||||
import { apiUrl } from '@/config';
|
import { apiUrl } from '@/config';
|
||||||
|
@ -44,46 +44,81 @@ export function api(endpoint: string, data: Record<string, any> = {}, token?: st
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function popup(component: Component, props: Record<string, any>, callback?: Function) {
|
export function popup(component: Component, props: Record<string, any>, callback?: Function, option?) {
|
||||||
|
markRaw(component);
|
||||||
const id = Math.random().toString(); // TODO: uuidとか使う
|
const id = Math.random().toString(); // TODO: uuidとか使う
|
||||||
const showing = ref(true);
|
const showing = ref(true);
|
||||||
const popup = {
|
const close = (...args) => {
|
||||||
component,
|
|
||||||
props: {
|
|
||||||
...props,
|
|
||||||
showing
|
|
||||||
},
|
|
||||||
showing,
|
|
||||||
done: (...args) => {
|
|
||||||
if (callback) callback(...args);
|
if (callback) callback(...args);
|
||||||
showing.value = false;
|
showing.value = false;
|
||||||
},
|
};
|
||||||
|
const modal = {
|
||||||
|
type: 'popup',
|
||||||
|
component,
|
||||||
|
props,
|
||||||
|
showing,
|
||||||
|
source: option?.source,
|
||||||
|
done: close,
|
||||||
|
bgClick: () => close(),
|
||||||
closed: () => {
|
closed: () => {
|
||||||
store.commit('removePopup', id);
|
store.commit('removePopup', id);
|
||||||
},
|
},
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
store.commit('addPopup', popup);
|
store.commit('addPopup', modal);
|
||||||
return () => {
|
return close;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function modal(component: Component, props: Record<string, any>, callback?: Function, option?) {
|
||||||
|
markRaw(component);
|
||||||
|
const id = Math.random().toString(); // TODO: uuidとか使う
|
||||||
|
const showing = ref(true);
|
||||||
|
const close = (...args) => {
|
||||||
|
if (callback) callback(...args);
|
||||||
showing.value = false;
|
showing.value = false;
|
||||||
};
|
};
|
||||||
|
const modal = {
|
||||||
|
type: 'modal',
|
||||||
|
component,
|
||||||
|
props,
|
||||||
|
showing,
|
||||||
|
source: option?.source,
|
||||||
|
done: close,
|
||||||
|
bgClick: () => close(),
|
||||||
|
closed: () => {
|
||||||
|
store.commit('removePopup', id);
|
||||||
|
},
|
||||||
|
id,
|
||||||
|
};
|
||||||
|
store.commit('addPopup', modal);
|
||||||
|
return close;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function dialog(props: Record<string, any>) {
|
export function dialog(props: Record<string, any>) {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
popup(defineAsyncComponent(() => import('@/components/dialog.vue')), props, res);
|
modal(defineAsyncComponent(() => import('@/components/dialog.vue')), props, result => {
|
||||||
|
if (result) {
|
||||||
|
res(result);
|
||||||
|
} else {
|
||||||
|
res({ canceled: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function menu(props: Record<string, any>) {
|
export function menu(props: Record<string, any>) {
|
||||||
|
const source = props.source; // TODO: sourceはpropsの外に出して追加の引数として受け取るようにする
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
popup(defineAsyncComponent(() => import('@/components/menu.vue')), props, res);
|
modal(defineAsyncComponent(() => import('@/components/menu.vue')), props, res, {
|
||||||
|
position: 'source',
|
||||||
|
source
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function post(props: Record<string, any>) {
|
export function post(props: Record<string, any>) {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
popup(defineAsyncComponent(() => import('@/components/post-form-dialog.vue')), props, res);
|
modal(defineAsyncComponent(() => import('@/components/post-form.vue')), props, res);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,13 +54,13 @@ export default defineComponent({
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
signin() {
|
signin() {
|
||||||
os.popup(XSigninDialog, {
|
os.modal(XSigninDialog, {
|
||||||
autoSet: true
|
autoSet: true
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
signup() {
|
signup() {
|
||||||
os.popup(XSignupDialog, {
|
os.modal(XSignupDialog, {
|
||||||
autoSet: true
|
autoSet: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
info(instance) {
|
info(instance) {
|
||||||
os.popup(MkInstanceInfo, {
|
os.modal(MkInstanceInfo, {
|
||||||
instance: instance
|
instance: instance
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -550,7 +550,7 @@ export default defineComponent({
|
||||||
host: q
|
host: q
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
os.popup(MkInstanceInfo, {
|
os.modal(MkInstanceInfo, {
|
||||||
instance: instance
|
instance: instance
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -439,7 +439,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
showFollowing() {
|
showFollowing() {
|
||||||
os.popup(MkUsersDialog, {
|
os.modal(MkUsersDialog, {
|
||||||
title: this.$t('instanceFollowing'),
|
title: this.$t('instanceFollowing'),
|
||||||
pagination: {
|
pagination: {
|
||||||
endpoint: 'federation/following',
|
endpoint: 'federation/following',
|
||||||
|
@ -453,7 +453,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
showFollowers() {
|
showFollowers() {
|
||||||
os.popup(MkUsersDialog, {
|
os.modal(MkUsersDialog, {
|
||||||
title: this.$t('instanceFollowers'),
|
title: this.$t('instanceFollowers'),
|
||||||
pagination: {
|
pagination: {
|
||||||
endpoint: 'federation/followers',
|
endpoint: 'federation/followers',
|
||||||
|
@ -467,7 +467,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
showUsers() {
|
showUsers() {
|
||||||
os.popup(MkUsersDialog, {
|
os.modal(MkUsersDialog, {
|
||||||
title: this.$t('instanceUsers'),
|
title: this.$t('instanceUsers'),
|
||||||
pagination: {
|
pagination: {
|
||||||
endpoint: 'federation/users',
|
endpoint: 'federation/users',
|
||||||
|
|
|
@ -452,7 +452,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
addPinUser() {
|
addPinUser() {
|
||||||
os.popup(MkUserSelect, {}).$once('selected', user => {
|
os.modal(MkUserSelect, {}).$once('selected', user => {
|
||||||
this.pinnedUsers = this.pinnedUsers.trim();
|
this.pinnedUsers = this.pinnedUsers.trim();
|
||||||
this.pinnedUsers += '\n@' + getAcct(user);
|
this.pinnedUsers += '\n@' + getAcct(user);
|
||||||
this.pinnedUsers = this.pinnedUsers.trim();
|
this.pinnedUsers = this.pinnedUsers.trim();
|
||||||
|
@ -460,7 +460,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
chooseProxyAccount() {
|
chooseProxyAccount() {
|
||||||
os.popup(MkUserSelect, {}).$once('selected', user => {
|
os.modal(MkUserSelect, {}).$once('selected', user => {
|
||||||
this.proxyAccount = user;
|
this.proxyAccount = user;
|
||||||
this.proxyAccountId = user.id;
|
this.proxyAccountId = user.id;
|
||||||
this.save(true);
|
this.save(true);
|
||||||
|
|
|
@ -180,7 +180,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
searchUser() {
|
searchUser() {
|
||||||
os.popup(MkUserSelect, {}).$once('selected', user => {
|
os.modal(MkUserSelect, {}).$once('selected', user => {
|
||||||
this.show(user);
|
this.show(user);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -132,7 +132,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
async startUser() {
|
async startUser() {
|
||||||
os.popup(MkUserSelect, {}).$once('selected', user => {
|
os.modal(MkUserSelect, {}).$once('selected', user => {
|
||||||
this.$router.push(`/my/messaging/${getAcct(user)}`);
|
this.$router.push(`/my/messaging/${getAcct(user)}`);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -220,7 +220,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
async insertEmoji(ev) {
|
async insertEmoji(ev) {
|
||||||
const vm = os.popup(await import('@/components/emoji-picker.vue'), {
|
const vm = os.modal(await import('@/components/emoji-picker.vue'), {
|
||||||
source: ev.currentTarget || ev.target
|
source: ev.currentTarget || ev.target
|
||||||
}).$once('chosen', emoji => {
|
}).$once('chosen', emoji => {
|
||||||
insertTextAtCursor(this.$refs.text, emoji);
|
insertTextAtCursor(this.$refs.text, emoji);
|
||||||
|
|
|
@ -177,7 +177,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
addUser() {
|
addUser() {
|
||||||
os.popup(MkUserSelect, {}).$once('selected', user => {
|
os.modal(MkUserSelect, {}).$once('selected', user => {
|
||||||
this.users = this.users.trim();
|
this.users = this.users.trim();
|
||||||
this.users += '\n@' + getAcct(user);
|
this.users += '\n@' + getAcct(user);
|
||||||
this.users = this.users.trim();
|
this.users = this.users.trim();
|
||||||
|
|
|
@ -89,7 +89,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
invite() {
|
invite() {
|
||||||
os.popup(MkUserSelect, {}).$once('selected', user => {
|
os.modal(MkUserSelect, {}).$once('selected', user => {
|
||||||
os.api('users/groups/invite', {
|
os.api('users/groups/invite', {
|
||||||
groupId: this.group.id,
|
groupId: this.group.id,
|
||||||
userId: user.id
|
userId: user.id
|
||||||
|
@ -134,7 +134,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
transfer() {
|
transfer() {
|
||||||
os.popup(MkUserSelect, {}).$once('selected', user => {
|
os.modal(MkUserSelect, {}).$once('selected', user => {
|
||||||
os.api('users/groups/transfer', {
|
os.api('users/groups/transfer', {
|
||||||
groupId: this.group.id,
|
groupId: this.group.id,
|
||||||
userId: user.id
|
userId: user.id
|
||||||
|
|
|
@ -88,7 +88,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
addUser() {
|
addUser() {
|
||||||
os.popup(MkUserSelect, {}).$once('selected', user => {
|
os.modal(MkUserSelect, {}).$once('selected', user => {
|
||||||
os.api('users/lists/push', {
|
os.api('users/lists/push', {
|
||||||
listId: this.list.id,
|
listId: this.list.id,
|
||||||
userId: user.id
|
userId: user.id
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async generateToken() {
|
async generateToken() {
|
||||||
os.popup(await import('@/components/token-generate-window.vue'), {
|
os.modal(await import('@/components/token-generate-window.vue'), {
|
||||||
}).$on('ok', async ({ name, permissions }) => {
|
}).$on('ok', async ({ name, permissions }) => {
|
||||||
const { token } = await os.api('miauth/gen-token', {
|
const { token } = await os.api('miauth/gen-token', {
|
||||||
session: null,
|
session: null,
|
||||||
|
|
|
@ -114,7 +114,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
async configure() {
|
async configure() {
|
||||||
os.popup(await import('@/components/notification-setting-window.vue'), {
|
os.modal(await import('@/components/notification-setting-window.vue'), {
|
||||||
includingTypes: this.$store.state.i.includingNotificationTypes,
|
includingTypes: this.$store.state.i.includingNotificationTypes,
|
||||||
showGlobalToggle: false,
|
showGlobalToggle: false,
|
||||||
}).$on('ok', async ({ includingTypes: value }: any) => {
|
}).$on('ok', async ({ includingTypes: value }: any) => {
|
||||||
|
|
|
@ -58,7 +58,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
preview(ev) {
|
preview(ev) {
|
||||||
const picker = os.popup(MkReactionPicker, {
|
const picker = os.modal(MkReactionPicker, {
|
||||||
source: ev.currentTarget || ev.target,
|
source: ev.currentTarget || ev.target,
|
||||||
reactions: this.splited,
|
reactions: this.splited,
|
||||||
showFocus: false,
|
showFocus: false,
|
||||||
|
@ -73,7 +73,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
async chooseEmoji(ev) {
|
async chooseEmoji(ev) {
|
||||||
const vm = os.popup(await import('@/components/emoji-picker.vue'), {
|
const vm = os.modal(await import('@/components/emoji-picker.vue'), {
|
||||||
source: ev.currentTarget || ev.target
|
source: ev.currentTarget || ev.target
|
||||||
}).$once('chosen', emoji => {
|
}).$once('chosen', emoji => {
|
||||||
this.reactions += emoji;
|
this.reactions += emoji;
|
||||||
|
|
|
@ -118,7 +118,7 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = permissions == null || permissions.length === 0 ? null : await new Promise(async (res, rej) => {
|
const token = permissions == null || permissions.length === 0 ? null : await new Promise(async (res, rej) => {
|
||||||
os.popup(await import('@/components/token-generate-window.vue'), {
|
os.modal(await import('@/components/token-generate-window.vue'), {
|
||||||
title: this.$t('tokenRequested'),
|
title: this.$t('tokenRequested'),
|
||||||
information: this.$t('pluginTokenRequestedDescription'),
|
information: this.$t('pluginTokenRequestedDescription'),
|
||||||
initialName: name,
|
initialName: name,
|
||||||
|
|
|
@ -60,7 +60,7 @@ export default defineComponent({
|
||||||
if (this.title) text += `【${this.title}】\n`;
|
if (this.title) text += `【${this.title}】\n`;
|
||||||
if (this.text) text += `${this.text}\n`;
|
if (this.text) text += `${this.text}\n`;
|
||||||
if (this.url) text += `${this.url}`;
|
if (this.url) text += `${this.url}`;
|
||||||
os.popup(PostFormDialog, {
|
os.modal(PostFormDialog, {
|
||||||
instant: true,
|
instant: true,
|
||||||
initialText: text.trim()
|
initialText: text.trim()
|
||||||
}).$once('posted', () => {
|
}).$once('posted', () => {
|
||||||
|
|
|
@ -189,7 +189,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
menu() {
|
menu() {
|
||||||
os.popup(XUserMenu, {
|
os.modal(XUserMenu, {
|
||||||
source: this.$refs.menu,
|
source: this.$refs.menu,
|
||||||
user: this.user
|
user: this.user
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,13 +2,17 @@
|
||||||
<DeckUI v-if="deckmode"/>
|
<DeckUI v-if="deckmode"/>
|
||||||
<DefaultUI v-else/>
|
<DefaultUI v-else/>
|
||||||
|
|
||||||
<component v-for="popup in $store.state.popups" :is="popup.component" v-bind="popup.props" :key="popup.id" @done="popup.done" @closed="popup.closed"/>
|
<XModal v-for="modal in $store.state.popups.filter(x => x.type === 'modal')" :key="modal.id" @closed="modal.closed" @click="modal.bgClick" :showing="modal.showing" :source="modal.source">
|
||||||
|
<component :is="modal.component" v-bind="modal.props" @done="modal.done"/>
|
||||||
|
</XModal>
|
||||||
|
|
||||||
|
<component v-for="popup in $store.state.popups.filter(x => x.type === 'popup')" :key="popup.id" :is="popup.component" v-bind="popup.props" @done="popup.done" @closed="popup.closed"/>
|
||||||
|
|
||||||
<div id="wait" v-if="$store.state.pendingApiRequestsCount > 0"></div>
|
<div id="wait" v-if="$store.state.pendingApiRequestsCount > 0"></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||||
import DefaultUI from './default.vue';
|
import DefaultUI from './default.vue';
|
||||||
import DeckUI from './deck.vue';
|
import DeckUI from './deck.vue';
|
||||||
import { instanceName, deckmode } from '@/config';
|
import { instanceName, deckmode } from '@/config';
|
||||||
|
@ -17,6 +21,7 @@ export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
DefaultUI,
|
DefaultUI,
|
||||||
DeckUI,
|
DeckUI,
|
||||||
|
XModal: defineAsyncComponent(() => import('@/components/modal.vue'))
|
||||||
},
|
},
|
||||||
|
|
||||||
metaInfo: {
|
metaInfo: {
|
||||||
|
|
|
@ -111,6 +111,7 @@ export const store = createStore({
|
||||||
popups: [] as {
|
popups: [] as {
|
||||||
id: any;
|
id: any;
|
||||||
component: any;
|
component: any;
|
||||||
|
type: 'popup' | 'modal',
|
||||||
props: Record<string, any>;
|
props: Record<string, any>;
|
||||||
}[],
|
}[],
|
||||||
fullView: false,
|
fullView: false,
|
||||||
|
|
|
@ -51,7 +51,7 @@ export default defineComponent({
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
async configure() {
|
async configure() {
|
||||||
os.popup(await import('@/components/notification-setting-window.vue'), {
|
os.modal(await import('@/components/notification-setting-window.vue'), {
|
||||||
includingTypes: this.props.includingTypes,
|
includingTypes: this.props.includingTypes,
|
||||||
}).$on('ok', async ({ includingTypes }) => {
|
}).$on('ok', async ({ includingTypes }) => {
|
||||||
this.props.includingTypes = includingTypes;
|
this.props.includingTypes = includingTypes;
|
||||||
|
|
|
@ -52,13 +52,13 @@ export default defineComponent({
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
signin() {
|
signin() {
|
||||||
os.popup(XSigninDialog, {
|
os.modal(XSigninDialog, {
|
||||||
autoSet: true
|
autoSet: true
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
signup() {
|
signup() {
|
||||||
os.popup(XSignupDialog, {
|
os.modal(XSignupDialog, {
|
||||||
autoSet: true
|
autoSet: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue