v12 (#5712)
Co-authored-by: MeiMei <30769358+mei23@users.noreply.github.com> Co-authored-by: Satsuki Yanagi <17376330+u1-liquid@users.noreply.github.com>
This commit is contained in:
188
src/client/components/user-menu.vue
Normal file
188
src/client/components/user-menu.vue
Normal file
@@ -0,0 +1,188 @@
|
||||
<template>
|
||||
<x-menu :source="source" :items="items" @closed="$emit('closed')"/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { faAt, faListUl, faEye, faEyeSlash, faBan, faPencilAlt, faComments } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faSnowflake, faEnvelope } from '@fortawesome/free-regular-svg-icons';
|
||||
import i18n from '../i18n';
|
||||
import XMenu from './menu.vue';
|
||||
import copyToClipboard from '../scripts/copy-to-clipboard';
|
||||
import { host } from '../config';
|
||||
import getAcct from '../../misc/acct/render';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n,
|
||||
|
||||
components: {
|
||||
XMenu
|
||||
},
|
||||
|
||||
props: ['user', 'source'],
|
||||
|
||||
data() {
|
||||
let menu = [{
|
||||
icon: faAt,
|
||||
text: this.$t('copyUsername'),
|
||||
action: () => {
|
||||
copyToClipboard(`@${this.user.username}@${this.user.host || host}`);
|
||||
}
|
||||
}, {
|
||||
icon: faEnvelope,
|
||||
text: this.$t('sendMessage'),
|
||||
action: () => {
|
||||
this.$root.post({ specified: this.user });
|
||||
}
|
||||
}, this.$store.state.i.id != this.user.id ? {
|
||||
type: 'link',
|
||||
to: `/my/messaging/${getAcct(this.user)}`,
|
||||
icon: faComments,
|
||||
text: this.$t('startMessaging'),
|
||||
} : undefined, null, {
|
||||
icon: faListUl,
|
||||
text: this.$t('addToList'),
|
||||
action: this.pushList
|
||||
}] as any;
|
||||
|
||||
if (this.$store.getters.isSignedIn && this.$store.state.i.id != this.user.id) {
|
||||
menu = menu.concat([null, {
|
||||
icon: this.user.isMuted ? faEye : faEyeSlash,
|
||||
text: this.user.isMuted ? this.$t('unmute') : this.$t('mute'),
|
||||
action: this.toggleMute
|
||||
}, {
|
||||
icon: faBan,
|
||||
text: this.user.isBlocking ? this.$t('unblock') : this.$t('block'),
|
||||
action: this.toggleBlock
|
||||
}]);
|
||||
|
||||
if (this.$store.state.i.isAdmin) {
|
||||
menu = menu.concat([null, {
|
||||
icon: faSnowflake,
|
||||
text: this.user.isSuspended ? this.$t('unsuspend') : this.$t('suspend'),
|
||||
action: this.toggleSuspend
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.$store.getters.isSignedIn && this.$store.state.i.id === this.user.id) {
|
||||
menu = menu.concat([null, {
|
||||
icon: faPencilAlt,
|
||||
text: this.$t('editProfile'),
|
||||
action: () => {
|
||||
this.$router.push('/my/settings');
|
||||
}
|
||||
}]);
|
||||
}
|
||||
|
||||
return {
|
||||
items: menu
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
async pushList() {
|
||||
const t = this.$t('selectList'); // なぜか後で参照すると null になるので最初にメモリに確保しておく
|
||||
const lists = await this.$root.api('users/lists/list');
|
||||
if (lists.length === 0) {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: this.$t('youHaveNoLists')
|
||||
});
|
||||
return;
|
||||
}
|
||||
const { canceled, result: listId } = await this.$root.dialog({
|
||||
type: null,
|
||||
title: t,
|
||||
select: {
|
||||
items: lists.map(list => ({
|
||||
value: list.id, text: list.name
|
||||
}))
|
||||
},
|
||||
showCancelButton: true
|
||||
});
|
||||
if (canceled) return;
|
||||
this.$root.api('users/lists/push', {
|
||||
listId: listId,
|
||||
userId: this.user.id
|
||||
}).then(() => {
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
iconOnly: true, autoClose: true
|
||||
});
|
||||
}).catch(e => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
async toggleMute() {
|
||||
this.$root.api(this.user.isMuted ? 'mute/delete' : 'mute/create', {
|
||||
userId: this.user.id
|
||||
}).then(() => {
|
||||
this.user.isMuted = !this.user.isMuted;
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
iconOnly: true, autoClose: true
|
||||
});
|
||||
}, e => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
async toggleBlock() {
|
||||
if (!await this.getConfirmed(this.user.isBlocking ? this.$t('unblockConfirm') : this.$t('blockConfirm'))) return;
|
||||
|
||||
this.$root.api(this.user.isBlocking ? 'blocking/delete' : 'blocking/create', {
|
||||
userId: this.user.id
|
||||
}).then(() => {
|
||||
this.user.isBlocking = !this.user.isBlocking;
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
iconOnly: true, autoClose: true
|
||||
});
|
||||
}, e => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
async toggleSuspend() {
|
||||
if (!await this.getConfirmed(this.$t(this.user.isSuspended ? 'unsuspendConfirm' : 'suspendConfirm'))) return;
|
||||
|
||||
this.$root.api(this.user.isSuspended ? 'admin/unsuspend-user' : 'admin/suspend-user', {
|
||||
userId: this.user.id
|
||||
}).then(() => {
|
||||
this.user.isSuspended = !this.user.isSuspended;
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
iconOnly: true, autoClose: true
|
||||
});
|
||||
}, e => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
async getConfirmed(text: string): Promise<Boolean> {
|
||||
const confirm = await this.$root.dialog({
|
||||
type: 'warning',
|
||||
showCancelButton: true,
|
||||
title: 'confirm',
|
||||
text,
|
||||
});
|
||||
|
||||
return !confirm.canceled;
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
Reference in New Issue
Block a user