feat: admin/mod emoji import contextMenu

This commit is contained in:
sim1222 2022-11-11 23:00:53 +09:00
parent 45688dfafd
commit 9f409e3ae0
No known key found for this signature in database
GPG Key ID: 04EF48D01BEB0298
2 changed files with 120 additions and 0 deletions

View File

@ -6,6 +6,7 @@
class="hkzvhatu _button" class="hkzvhatu _button"
:class="{ reacted: note.myReaction == reaction, canToggle }" :class="{ reacted: note.myReaction == reaction, canToggle }"
@click="toggleReaction()" @click="toggleReaction()"
@contextmenu.stop="onContextmenu"
> >
<XReactionIcon class="icon" :reaction="reaction" :custom-emojis="note.emojis"/> <XReactionIcon class="icon" :reaction="reaction" :custom-emojis="note.emojis"/>
<span class="count">{{ count }}</span> <span class="count">{{ count }}</span>
@ -20,6 +21,7 @@ import XReactionIcon from '@/components/reaction-icon.vue';
import * as os from '@/os'; import * as os from '@/os';
import { useTooltip } from '@/scripts/use-tooltip'; import { useTooltip } from '@/scripts/use-tooltip';
import { $i } from '@/account'; import { $i } from '@/account';
import { openReactionImportMenu } from '@/scripts/reactionImportMenu';
const props = defineProps<{ const props = defineProps<{
reaction: string; reaction: string;
@ -88,6 +90,11 @@ useTooltip(buttonRef, async (showing) => {
targetElement: buttonRef.value, targetElement: buttonRef.value,
}, {}, 'closed'); }, {}, 'closed');
}, 100); }, 100);
const onContextmenu = (e: MouseEvent) => {
e.preventDefault();
openReactionImportMenu(e, props.reaction);
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -0,0 +1,113 @@
import { defineAsyncComponent } from 'vue';
import { $i } from '@/account';
import { i18n } from '@/i18n';
import * as os from '@/os';
import copyToClipboard from '@/scripts/copy-to-clipboard';
import { MenuItem } from '@/types/menu';
export async function openReactionImportMenu(ev: MouseEvent, reaction: string): Promise<void> {
if (!reaction) return;
const host = reaction.match(/(?<=@).*\.*(?=:)/g)?.[0];
const name = reaction.match(/(?<=:).*(?=@.*\.*(?=:))/g)?.[0];
const isLocal = (host === null || host === '.');
const isCustom = reaction.startsWith(':');
const getEmojiObject = (emojiId): Promise<Record<string, any> | null> => new Promise<Record<string, any> | null>(async resolve => {
const sinceId = await os.api('admin/emoji/list', {
limit: 1,
untilId: emojiId.id,
});
if (!sinceId || !sinceId[0] || !sinceId[0].id) {
resolve(null);
return;
}
const id = await os.api('admin/emoji/list', {
limit: 1,
sinceId: sinceId[0].id,
});
if (!id || !id[0]) {
resolve(null);
return;
}
resolve(id[0]);
});
const getEmojiId = async (): Promise<string | null> => {
if (isLocal) return null;
if (!host || !name) return null;
const resList: Record<string, any>[] = await os.api('admin/emoji/list-remote', {
host,
query: name,
limit: 100,
});
const emojiId = await resList.find(emoji => emoji.name === name && emoji.host === host)?.id;
return emojiId;
};
const importEmoji = async (): Promise<void> => {
const emojiId = await getEmojiId();
if (!await emojiId) return;
os.api('admin/emoji/copy', {
emojiId: emojiId,
}).then(async emoji => os.popup(defineAsyncComponent(() => import('@/pages/admin/emoji-edit-dialog.vue')), {
emoji: await getEmojiObject(emoji),
}));
};
const menuItems: MenuItem[] = [{
type: 'label',
text: reaction,
}, {
type: 'button',
icon: 'fas fa-copy',
text: i18n.ts.copy,
action: (): void => {
copyToClipboard(isCustom ? `:${name}:` : reaction);
},
}];
const emojiId = await getEmojiId() ? await getEmojiId() : reaction;
if (
isCustom &&
emojiId &&
($i?.isAdmin || $i?.isModerator) &&
!isLocal
) {
menuItems.push({
type: 'button',
icon: 'fas fa-download',
text: i18n.ts.import,
action: async () => {
const duplication: boolean = await os.api('meta').then(meta => {
const emojis = meta.emojis;
return emojis.some((emoji) => {
return (emoji.name === name);
});
});
if (await duplication) {
os.confirm({
type: 'warning',
text: i18n.ts.duplicateEmoji,
}).then(res => {
if (res.canceled) return;
importEmoji();
});
} else {
importEmoji();
}
},
});
}
os.contextMenu(menuItems, ev);
}