mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-01 23:15:47 +02:00
refactor
This commit is contained in:
@@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
[$style.iconFrame_platinum]: ACHIEVEMENT_BADGES[achievement.name].frame === 'platinum',
|
||||
}]"
|
||||
>
|
||||
<div :class="[$style.iconInner]" :style="{ background: ACHIEVEMENT_BADGES[achievement.name].bg }">
|
||||
<div :class="[$style.iconInner]" :style="{ background: ACHIEVEMENT_BADGES[achievement.name].bg ?? '' }">
|
||||
<img :class="$style.iconImg" :src="ACHIEVEMENT_BADGES[achievement.name].img">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -589,7 +589,10 @@ const fetchDriveFilesChart = async (): Promise<typeof chartData> => {
|
||||
};
|
||||
|
||||
const fetchInstanceRequestsChart = async (): Promise<typeof chartData> => {
|
||||
const raw = await misskeyApiGet('charts/instance', { host: props.args?.host, limit: props.limit, span: props.span });
|
||||
const host = props.args?.host;
|
||||
if (host == null) return { series: [] };
|
||||
|
||||
const raw = await misskeyApiGet('charts/instance', { host: host, limit: props.limit, span: props.span });
|
||||
return {
|
||||
series: [{
|
||||
name: 'In',
|
||||
@@ -611,7 +614,10 @@ const fetchInstanceRequestsChart = async (): Promise<typeof chartData> => {
|
||||
};
|
||||
|
||||
const fetchInstanceUsersChart = async (total: boolean): Promise<typeof chartData> => {
|
||||
const raw = await misskeyApiGet('charts/instance', { host: props.args?.host, limit: props.limit, span: props.span });
|
||||
const host = props.args?.host;
|
||||
if (host == null) return { series: [] };
|
||||
|
||||
const raw = await misskeyApiGet('charts/instance', { host: host, limit: props.limit, span: props.span });
|
||||
return {
|
||||
series: [{
|
||||
name: 'Users',
|
||||
@@ -626,7 +632,10 @@ const fetchInstanceUsersChart = async (total: boolean): Promise<typeof chartData
|
||||
};
|
||||
|
||||
const fetchInstanceNotesChart = async (total: boolean): Promise<typeof chartData> => {
|
||||
const raw = await misskeyApiGet('charts/instance', { host: props.args?.host, limit: props.limit, span: props.span });
|
||||
const host = props.args?.host;
|
||||
if (host == null) return { series: [] };
|
||||
|
||||
const raw = await misskeyApiGet('charts/instance', { host: host, limit: props.limit, span: props.span });
|
||||
return {
|
||||
series: [{
|
||||
name: 'Notes',
|
||||
@@ -641,7 +650,10 @@ const fetchInstanceNotesChart = async (total: boolean): Promise<typeof chartData
|
||||
};
|
||||
|
||||
const fetchInstanceFfChart = async (total: boolean): Promise<typeof chartData> => {
|
||||
const raw = await misskeyApiGet('charts/instance', { host: props.args?.host, limit: props.limit, span: props.span });
|
||||
const host = props.args?.host;
|
||||
if (host == null) return { series: [] };
|
||||
|
||||
const raw = await misskeyApiGet('charts/instance', { host: host, limit: props.limit, span: props.span });
|
||||
return {
|
||||
series: [{
|
||||
name: 'Following',
|
||||
@@ -664,7 +676,10 @@ const fetchInstanceFfChart = async (total: boolean): Promise<typeof chartData> =
|
||||
};
|
||||
|
||||
const fetchInstanceDriveUsageChart = async (total: boolean): Promise<typeof chartData> => {
|
||||
const raw = await misskeyApiGet('charts/instance', { host: props.args?.host, limit: props.limit, span: props.span });
|
||||
const host = props.args?.host;
|
||||
if (host == null) return { series: [] };
|
||||
|
||||
const raw = await misskeyApiGet('charts/instance', { host: host, limit: props.limit, span: props.span });
|
||||
return {
|
||||
bytes: true,
|
||||
series: [{
|
||||
@@ -680,7 +695,10 @@ const fetchInstanceDriveUsageChart = async (total: boolean): Promise<typeof char
|
||||
};
|
||||
|
||||
const fetchInstanceDriveFilesChart = async (total: boolean): Promise<typeof chartData> => {
|
||||
const raw = await misskeyApiGet('charts/instance', { host: props.args?.host, limit: props.limit, span: props.span });
|
||||
const host = props.args?.host;
|
||||
if (host == null) return { series: [] };
|
||||
|
||||
const raw = await misskeyApiGet('charts/instance', { host: host, limit: props.limit, span: props.span });
|
||||
return {
|
||||
series: [{
|
||||
name: 'Drive files',
|
||||
@@ -695,7 +713,10 @@ const fetchInstanceDriveFilesChart = async (total: boolean): Promise<typeof char
|
||||
};
|
||||
|
||||
const fetchPerUserNotesChart = async (): Promise<typeof chartData> => {
|
||||
const raw = await misskeyApiGet('charts/user/notes', { userId: props.args?.user?.id, limit: props.limit, span: props.span });
|
||||
const userId = props.args?.user?.id;
|
||||
if (userId == null) return { series: [] };
|
||||
|
||||
const raw = await misskeyApiGet('charts/user/notes', { userId: userId, limit: props.limit, span: props.span });
|
||||
return {
|
||||
series: [...(props.args?.withoutAll ? [] : [{
|
||||
name: 'All',
|
||||
@@ -727,7 +748,10 @@ const fetchPerUserNotesChart = async (): Promise<typeof chartData> => {
|
||||
};
|
||||
|
||||
const fetchPerUserPvChart = async (): Promise<typeof chartData> => {
|
||||
const raw = await misskeyApiGet('charts/user/pv', { userId: props.args?.user?.id, limit: props.limit, span: props.span });
|
||||
const userId = props.args?.user?.id;
|
||||
if (userId == null) return { series: [] };
|
||||
|
||||
const raw = await misskeyApiGet('charts/user/pv', { userId: userId, limit: props.limit, span: props.span });
|
||||
return {
|
||||
series: [{
|
||||
name: 'Unique PV (user)',
|
||||
@@ -754,7 +778,10 @@ const fetchPerUserPvChart = async (): Promise<typeof chartData> => {
|
||||
};
|
||||
|
||||
const fetchPerUserFollowingChart = async (): Promise<typeof chartData> => {
|
||||
const raw = await misskeyApiGet('charts/user/following', { userId: props.args?.user?.id, limit: props.limit, span: props.span });
|
||||
const userId = props.args?.user?.id;
|
||||
if (userId == null) return { series: [] };
|
||||
|
||||
const raw = await misskeyApiGet('charts/user/following', { userId: userId, limit: props.limit, span: props.span });
|
||||
return {
|
||||
series: [{
|
||||
name: 'Local',
|
||||
@@ -769,7 +796,10 @@ const fetchPerUserFollowingChart = async (): Promise<typeof chartData> => {
|
||||
};
|
||||
|
||||
const fetchPerUserFollowersChart = async (): Promise<typeof chartData> => {
|
||||
const raw = await misskeyApiGet('charts/user/following', { userId: props.args?.user?.id, limit: props.limit, span: props.span });
|
||||
const userId = props.args?.user?.id;
|
||||
if (userId == null) return { series: [] };
|
||||
|
||||
const raw = await misskeyApiGet('charts/user/following', { userId: userId, limit: props.limit, span: props.span });
|
||||
return {
|
||||
series: [{
|
||||
name: 'Local',
|
||||
@@ -784,7 +814,10 @@ const fetchPerUserFollowersChart = async (): Promise<typeof chartData> => {
|
||||
};
|
||||
|
||||
const fetchPerUserDriveChart = async (): Promise<typeof chartData> => {
|
||||
const raw = await misskeyApiGet('charts/user/drive', { userId: props.args?.user?.id, limit: props.limit, span: props.span });
|
||||
const userId = props.args?.user?.id;
|
||||
if (userId == null) return { series: [] };
|
||||
|
||||
const raw = await misskeyApiGet('charts/user/drive', { userId: userId, limit: props.limit, span: props.span });
|
||||
return {
|
||||
bytes: true,
|
||||
series: [{
|
||||
|
||||
@@ -29,7 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, useTemplateRef, ref } from 'vue';
|
||||
import { onMounted, useTemplateRef, ref, onUnmounted } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import Cropper from 'cropperjs';
|
||||
import tinycolor from 'tinycolor2';
|
||||
@@ -55,17 +55,19 @@ const imgEl = useTemplateRef('imgEl');
|
||||
let cropper: Cropper | null = null;
|
||||
const loading = ref(true);
|
||||
|
||||
const ok = async () => {
|
||||
const promise = new Promise<Misskey.entities.DriveFile>(async (res) => {
|
||||
const croppedImage = await cropper?.getCropperImage();
|
||||
const croppedSection = await cropper?.getCropperSelection();
|
||||
async function ok() {
|
||||
const promise = new Promise<Blob>(async (res) => {
|
||||
if (cropper == null) throw new Error('Cropper is not initialized');
|
||||
|
||||
const croppedImage = await cropper.getCropperImage()!;
|
||||
const croppedSection = await cropper.getCropperSelection()!;
|
||||
|
||||
// 拡大率を計算し、(ほぼ)元の大きさに戻す
|
||||
const zoomedRate = croppedImage.getBoundingClientRect().width / croppedImage.clientWidth;
|
||||
const widthToRender = croppedSection.getBoundingClientRect().width / zoomedRate;
|
||||
|
||||
const croppedCanvas = await croppedSection?.$toCanvas({ width: widthToRender });
|
||||
croppedCanvas?.toBlob(blob => {
|
||||
const croppedCanvas = await croppedSection.$toCanvas({ width: widthToRender });
|
||||
croppedCanvas.toBlob(blob => {
|
||||
if (!blob) return;
|
||||
res(blob);
|
||||
});
|
||||
@@ -74,25 +76,27 @@ const ok = async () => {
|
||||
const f = await promise;
|
||||
|
||||
emit('ok', f);
|
||||
dialogEl.value!.close();
|
||||
};
|
||||
if (dialogEl.value != null) dialogEl.value.close();
|
||||
}
|
||||
|
||||
const cancel = () => {
|
||||
function cancel() {
|
||||
emit('cancel');
|
||||
dialogEl.value!.close();
|
||||
};
|
||||
if (dialogEl.value != null) dialogEl.value.close();
|
||||
}
|
||||
|
||||
const onImageLoad = () => {
|
||||
function onImageLoad() {
|
||||
loading.value = false;
|
||||
|
||||
if (cropper) {
|
||||
cropper.getCropperImage()!.$center('contain');
|
||||
cropper.getCropperSelection()!.$center();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
cropper = new Cropper(imgEl.value!, {
|
||||
if (imgEl.value == null) return; // TSを黙らすため
|
||||
|
||||
cropper = new Cropper(imgEl.value, {
|
||||
});
|
||||
|
||||
const computedStyle = getComputedStyle(window.document.documentElement);
|
||||
@@ -104,16 +108,22 @@ onMounted(() => {
|
||||
selection.outlined = true;
|
||||
|
||||
window.setTimeout(() => {
|
||||
cropper!.getCropperImage()!.$center('contain');
|
||||
if (cropper == null) return;
|
||||
cropper.getCropperImage()!.$center('contain');
|
||||
selection.$center();
|
||||
}, 100);
|
||||
|
||||
// モーダルオープンアニメーションが終わったあとで再度調整
|
||||
window.setTimeout(() => {
|
||||
cropper!.getCropperImage()!.$center('contain');
|
||||
if (cropper == null) return;
|
||||
cropper.getCropperImage()!.$center('contain');
|
||||
selection.$center();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
URL.revokeObjectURL(imgUrl);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -152,7 +152,7 @@ const props = withDefaults(defineProps<{
|
||||
asDrawer?: boolean;
|
||||
asWindow?: boolean;
|
||||
asReactionPicker?: boolean; // 今は使われてないが将来的に使いそう
|
||||
targetNote?: Misskey.entities.Note;
|
||||
targetNote?: Misskey.entities.Note | null;
|
||||
}>(), {
|
||||
showPinned: true,
|
||||
});
|
||||
|
||||
@@ -44,11 +44,11 @@ import { prefer } from '@/preferences.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
manualShowing?: boolean | null;
|
||||
anchorElement?: HTMLElement;
|
||||
anchorElement?: HTMLElement | null;
|
||||
showPinned?: boolean;
|
||||
pinnedEmojis?: string[],
|
||||
asReactionPicker?: boolean;
|
||||
targetNote?: Misskey.entities.Note;
|
||||
targetNote?: Misskey.entities.Note | null;
|
||||
choseAndClose?: boolean;
|
||||
}>(), {
|
||||
manualShowing: null,
|
||||
|
||||
@@ -91,7 +91,7 @@ const emit = defineEmits<{
|
||||
(ev: 'opened'): void;
|
||||
(ev: 'click'): void;
|
||||
(ev: 'esc'): void;
|
||||
(ev: 'close'): void;
|
||||
(ev: 'close'): void; // TODO: (refactor) closing に改名する
|
||||
(ev: 'closed'): void;
|
||||
}>();
|
||||
|
||||
@@ -148,7 +148,6 @@ function close(opts: { useSendAnimation?: boolean } = {}) {
|
||||
useSendAnime.value = true;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line vue/no-mutating-props
|
||||
if (props.anchorElement) props.anchorElement.style.pointerEvents = 'auto';
|
||||
showing.value = false;
|
||||
emit('close');
|
||||
@@ -319,7 +318,6 @@ const alignObserver = new ResizeObserver((entries, observer) => {
|
||||
onMounted(() => {
|
||||
watch(() => props.anchorElement, async () => {
|
||||
if (props.anchorElement) {
|
||||
// eslint-disable-next-line vue/no-mutating-props
|
||||
props.anchorElement.style.pointerEvents = 'none';
|
||||
}
|
||||
fixed.value = (type.value === 'drawer') || (getFixedContainer(props.anchorElement) != null);
|
||||
|
||||
@@ -58,18 +58,22 @@ const emit = defineEmits<{
|
||||
const buttonEl = useTemplateRef('buttonEl');
|
||||
|
||||
const emojiName = computed(() => props.reaction.replace(/:/g, '').replace(/@\./, ''));
|
||||
const emoji = computed(() => customEmojisMap.get(emojiName.value) ?? getUnicodeEmoji(props.reaction));
|
||||
|
||||
const canToggle = computed(() => {
|
||||
const emoji = customEmojisMap.get(emojiName.value) ?? getUnicodeEmoji(props.reaction);
|
||||
|
||||
// TODO
|
||||
//return !props.reaction.match(/@\w/) && $i && emoji.value && checkReactionPermissions($i, props.note, emoji.value);
|
||||
return !props.reaction.match(/@\w/) && $i && emoji.value;
|
||||
//return !props.reaction.match(/@\w/) && $i && emoji && checkReactionPermissions($i, props.note, emoji);
|
||||
return !props.reaction.match(/@\w/) && $i && emoji;
|
||||
});
|
||||
const canGetInfo = computed(() => !props.reaction.match(/@\w/) && props.reaction.includes(':'));
|
||||
const isLocalCustomEmoji = props.reaction[0] === ':' && props.reaction.includes('@.');
|
||||
|
||||
async function toggleReaction() {
|
||||
if (!canToggle.value) return;
|
||||
if ($i == null) return;
|
||||
|
||||
const me = $i;
|
||||
|
||||
const oldReaction = props.myReaction;
|
||||
if (oldReaction) {
|
||||
@@ -93,7 +97,7 @@ async function toggleReaction() {
|
||||
noteId: props.noteId,
|
||||
}).then(() => {
|
||||
noteEvents.emit(`unreacted:${props.noteId}`, {
|
||||
userId: $i!.id,
|
||||
userId: me.id,
|
||||
reaction: oldReaction,
|
||||
});
|
||||
if (oldReaction !== props.reaction) {
|
||||
@@ -101,10 +105,12 @@ async function toggleReaction() {
|
||||
noteId: props.noteId,
|
||||
reaction: props.reaction,
|
||||
}).then(() => {
|
||||
const emoji = customEmojisMap.get(emojiName.value);
|
||||
if (emoji == null) return;
|
||||
noteEvents.emit(`reacted:${props.noteId}`, {
|
||||
userId: $i!.id,
|
||||
userId: me.id,
|
||||
reaction: props.reaction,
|
||||
emoji: emoji.value,
|
||||
emoji: emoji,
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -131,10 +137,13 @@ async function toggleReaction() {
|
||||
noteId: props.noteId,
|
||||
reaction: props.reaction,
|
||||
}).then(() => {
|
||||
const emoji = customEmojisMap.get(emojiName.value);
|
||||
if (emoji == null) return;
|
||||
|
||||
noteEvents.emit(`reacted:${props.noteId}`, {
|
||||
userId: $i!.id,
|
||||
userId: me.id,
|
||||
reaction: props.reaction,
|
||||
emoji: emoji.value,
|
||||
emoji: emoji,
|
||||
});
|
||||
});
|
||||
// TODO: 上位コンポーネントでやる
|
||||
@@ -217,6 +226,8 @@ onMounted(() => {
|
||||
|
||||
if (!mock) {
|
||||
useTooltip(buttonEl, async (showing) => {
|
||||
if (buttonEl.value == null) return;
|
||||
|
||||
const reactions = await misskeyApiGet('notes/reactions', {
|
||||
noteId: props.noteId,
|
||||
type: props.reaction,
|
||||
|
||||
@@ -59,7 +59,7 @@ import { prefer } from '@/preferences.js';
|
||||
const props = withDefaults(defineProps<{
|
||||
tabs?: Tab[];
|
||||
tab?: string;
|
||||
rootEl?: HTMLElement;
|
||||
rootEl?: HTMLElement | null;
|
||||
}>(), {
|
||||
tabs: () => ([] as Tab[]),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user