-
+
+
-
diff --git a/packages/frontend/src/components/MkPoll.vue b/packages/frontend/src/components/MkPoll.vue
index 2d3ec45bca..359ee08812 100644
--- a/packages/frontend/src/components/MkPoll.vue
+++ b/packages/frontend/src/components/MkPoll.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- -
+
-
@@ -40,7 +40,9 @@ import { i18n } from '@/i18n.js';
const props = defineProps<{
noteId: string;
- poll: NonNullable;
+ multiple: NonNullable['multiple'];
+ expiresAt: NonNullable['expiresAt'];
+ choices: NonNullable['choices'];
readOnly?: boolean;
emojiUrls?: Record;
author?: Misskey.entities.UserLite;
@@ -48,9 +50,9 @@ const props = defineProps<{
const remaining = ref(-1);
-const total = computed(() => sum(props.poll.choices.map(x => x.votes)));
+const total = computed(() => sum(props.choices.map(x => x.votes)));
const closed = computed(() => remaining.value === 0);
-const isVoted = computed(() => !props.poll.multiple && props.poll.choices.some(c => c.isVoted));
+const isVoted = computed(() => !props.multiple && props.choices.some(c => c.isVoted));
const timer = computed(() => i18n.tsx._poll[
remaining.value >= 86400 ? 'remainingDays' :
remaining.value >= 3600 ? 'remainingHours' :
@@ -70,9 +72,9 @@ const pleaseLoginContext = computed(() => ({
}));
// 期限付きアンケート
-if (props.poll.expiresAt) {
+if (props.expiresAt) {
const tick = () => {
- remaining.value = Math.floor(Math.max(new Date(props.poll.expiresAt!).getTime() - Date.now(), 0) / 1000);
+ remaining.value = Math.floor(Math.max(new Date(props.expiresAt!).getTime() - Date.now(), 0) / 1000);
if (remaining.value === 0) {
showResult.value = true;
}
@@ -91,7 +93,7 @@ const vote = async (id) => {
const { canceled } = await os.confirm({
type: 'question',
- text: i18n.tsx.voteConfirm({ choice: props.poll.choices[id].text }),
+ text: i18n.tsx.voteConfirm({ choice: props.choices[id].text }),
});
if (canceled) return;
@@ -99,7 +101,7 @@ const vote = async (id) => {
noteId: props.noteId,
choice: id,
});
- if (!showResult.value) showResult.value = !props.poll.multiple;
+ if (!showResult.value) showResult.value = !props.multiple;
};
diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue
index c4857b7f65..5114e98494 100644
--- a/packages/frontend/src/components/MkPostForm.vue
+++ b/packages/frontend/src/components/MkPostForm.vue
@@ -137,6 +137,7 @@ import { mfmFunctionPicker } from '@/utility/mfm-function-picker.js';
import { prefer } from '@/preferences.js';
import { getPluginHandlers } from '@/plugin.js';
import { DI } from '@/di.js';
+import { globalEvents } from '@/events.js';
const $i = ensureSignin();
@@ -883,12 +884,15 @@ async function post(ev?: MouseEvent) {
}
posting.value = true;
- misskeyApi('notes/create', postData, token).then(() => {
+ misskeyApi('notes/create', postData, token).then((res) => {
if (props.freezeAfterPosted) {
posted.value = true;
} else {
clear();
}
+
+ globalEvents.emit('notePosted', res.createdNote);
+
nextTick(() => {
deleteDraft();
emit('posted');
diff --git a/packages/frontend/src/components/MkRange.vue b/packages/frontend/src/components/MkRange.vue
index 4b2e6910db..f36e68b687 100644
--- a/packages/frontend/src/components/MkRange.vue
+++ b/packages/frontend/src/components/MkRange.vue
@@ -9,6 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
+
@@ -25,6 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@touchstart="onMousedown"
>
+
@@ -224,12 +226,17 @@ function onMousedown(ev: MouseEvent | TouchEvent) {
$thumbWidth: 20px;
> .body {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
padding: 7px 12px;
background: var(--MI_THEME-panel);
border: solid 1px var(--MI_THEME-panel);
border-radius: 6px;
> .container {
+ flex: 1;
position: relative;
height: $thumbHeight;
diff --git a/packages/frontend/src/components/MkReactionsViewer.reaction.vue b/packages/frontend/src/components/MkReactionsViewer.reaction.vue
index 951447f15a..9027ffd0ae 100644
--- a/packages/frontend/src/components/MkReactionsViewer.reaction.vue
+++ b/packages/frontend/src/components/MkReactionsViewer.reaction.vue
@@ -8,11 +8,11 @@ SPDX-License-Identifier: AGPL-3.0-only
ref="buttonEl"
v-ripple="canToggle"
class="_button"
- :class="[$style.root, { [$style.reacted]: note.myReaction == reaction, [$style.canToggle]: canToggle, [$style.small]: prefer.s.reactionsDisplaySize === 'small', [$style.large]: prefer.s.reactionsDisplaySize === 'large' }]"
+ :class="[$style.root, { [$style.reacted]: myReaction == reaction, [$style.canToggle]: canToggle, [$style.small]: prefer.s.reactionsDisplaySize === 'small', [$style.large]: prefer.s.reactionsDisplaySize === 'large' }]"
@click="toggleReaction()"
@contextmenu.prevent.stop="menu"
>
-
+
{{ count }}
@@ -29,19 +29,21 @@ import { misskeyApi, misskeyApiGet } from '@/utility/misskey-api.js';
import { useTooltip } from '@/use/use-tooltip.js';
import { $i } from '@/i.js';
import MkReactionEffect from '@/components/MkReactionEffect.vue';
-import { claimAchievement } from '@/utility/achievements.js';
import { i18n } from '@/i18n.js';
import * as sound from '@/utility/sound.js';
import { checkReactionPermissions } from '@/utility/check-reaction-permissions.js';
import { customEmojisMap } from '@/custom-emojis.js';
import { prefer } from '@/preferences.js';
import { DI } from '@/di.js';
+import { noteEvents } from '@/use/use-note-capture.js';
const props = defineProps<{
+ noteId: Misskey.entities.Note['id'];
reaction: string;
+ reactionEmojis: Misskey.entities.Note['reactionEmojis'];
+ myReaction: Misskey.entities.Note['myReaction'];
count: number;
isInitial: boolean;
- note: Misskey.entities.Note;
}>();
const mock = inject(DI.mock, false);
@@ -56,14 +58,16 @@ const emojiName = computed(() => props.reaction.replace(/:/g, '').replace(/@\./,
const emoji = computed(() => customEmojisMap.get(emojiName.value) ?? getUnicodeEmoji(props.reaction));
const canToggle = computed(() => {
- return !props.reaction.match(/@\w/) && $i && emoji.value && checkReactionPermissions($i, props.note, emoji.value);
+ // TODO
+ //return !props.reaction.match(/@\w/) && $i && emoji.value && checkReactionPermissions($i, props.note, emoji.value);
+ return !props.reaction.match(/@\w/) && $i && emoji.value;
});
const canGetInfo = computed(() => !props.reaction.match(/@\w/) && props.reaction.includes(':'));
async function toggleReaction() {
if (!canToggle.value) return;
- const oldReaction = props.note.myReaction;
+ const oldReaction = props.myReaction;
if (oldReaction) {
const confirm = await os.confirm({
type: 'warning',
@@ -81,12 +85,23 @@ async function toggleReaction() {
}
misskeyApi('notes/reactions/delete', {
- noteId: props.note.id,
+ noteId: props.noteId,
}).then(() => {
+ noteEvents.emit(`unreacted:${props.noteId}`, {
+ userId: $i!.id,
+ reaction: props.reaction,
+ emoji: emoji.value,
+ });
if (oldReaction !== props.reaction) {
misskeyApi('notes/reactions/create', {
- noteId: props.note.id,
+ noteId: props.noteId,
reaction: props.reaction,
+ }).then(() => {
+ noteEvents.emit(`reacted:${props.noteId}`, {
+ userId: $i!.id,
+ reaction: props.reaction,
+ emoji: emoji.value,
+ });
});
}
});
@@ -108,12 +123,19 @@ async function toggleReaction() {
}
misskeyApi('notes/reactions/create', {
- noteId: props.note.id,
+ noteId: props.noteId,
reaction: props.reaction,
+ }).then(() => {
+ noteEvents.emit(`reacted:${props.noteId}`, {
+ userId: $i!.id,
+ reaction: props.reaction,
+ emoji: emoji.value,
+ });
});
- if (props.note.text && props.note.text.length > 100 && (Date.now() - new Date(props.note.createdAt).getTime() < 1000 * 3)) {
- claimAchievement('reactWithoutRead');
- }
+ // TODO: 上位コンポーネントでやる
+ //if (props.note.text && props.note.text.length > 100 && (Date.now() - new Date(props.note.createdAt).getTime() < 1000 * 3)) {
+ // claimAchievement('reactWithoutRead');
+ //}
}
}
@@ -157,7 +179,7 @@ onMounted(() => {
if (!mock) {
useTooltip(buttonEl, async (showing) => {
const reactions = await misskeyApiGet('notes/reactions', {
- noteId: props.note.id,
+ noteId: props.noteId,
type: props.reaction,
limit: 10,
_cacheKey_: props.count,
diff --git a/packages/frontend/src/components/MkReactionsViewer.vue b/packages/frontend/src/components/MkReactionsViewer.vue
index e8cf6c36db..725978179e 100644
--- a/packages/frontend/src/components/MkReactionsViewer.vue
+++ b/packages/frontend/src/components/MkReactionsViewer.vue
@@ -13,7 +13,17 @@ SPDX-License-Identifier: AGPL-3.0-only
:moveClass="$style.transition_x_move"
tag="div" :class="$style.root"
>
-
+
@@ -27,7 +37,10 @@ import { prefer } from '@/preferences.js';
import { DI } from '@/di.js';
const props = withDefaults(defineProps<{
- note: Misskey.entities.Note;
+ noteId: Misskey.entities.Note['id'];
+ reactions: Misskey.entities.Note['reactions'];
+ reactionEmojis: Misskey.entities.Note['reactionEmojis'];
+ myReaction: Misskey.entities.Note['myReaction'];
maxNumber?: number;
}>(), {
maxNumber: Infinity,
@@ -39,33 +52,33 @@ const emit = defineEmits<{
(ev: 'mockUpdateMyReaction', emoji: string, delta: number): void;
}>();
-const initialReactions = new Set(Object.keys(props.note.reactions));
+const initialReactions = new Set(Object.keys(props.reactions));
-const reactions = ref<[string, number][]>([]);
+const _reactions = ref<[string, number][]>([]);
const hasMoreReactions = ref(false);
-if (props.note.myReaction && !Object.keys(reactions.value).includes(props.note.myReaction)) {
- reactions.value[props.note.myReaction] = props.note.reactions[props.note.myReaction];
+if (props.myReaction && !Object.keys(_reactions.value).includes(props.myReaction)) {
+ _reactions.value[props.myReaction] = props.reactions[props.myReaction];
}
function onMockToggleReaction(emoji: string, count: number) {
if (!mock) return;
- const i = reactions.value.findIndex((item) => item[0] === emoji);
+ const i = _reactions.value.findIndex((item) => item[0] === emoji);
if (i < 0) return;
- emit('mockUpdateMyReaction', emoji, (count - reactions.value[i][1]));
+ emit('mockUpdateMyReaction', emoji, (count - _reactions.value[i][1]));
}
-watch([() => props.note.reactions, () => props.maxNumber], ([newSource, maxNumber]) => {
+watch([() => props.reactions, () => props.maxNumber], ([newSource, maxNumber]) => {
let newReactions: [string, number][] = [];
hasMoreReactions.value = Object.keys(newSource).length > maxNumber;
- for (let i = 0; i < reactions.value.length; i++) {
- const reaction = reactions.value[i][0];
+ for (let i = 0; i < _reactions.value.length; i++) {
+ const reaction = _reactions.value[i][0];
if (reaction in newSource && newSource[reaction] !== 0) {
- reactions.value[i][1] = newSource[reaction];
- newReactions.push(reactions.value[i]);
+ _reactions.value[i][1] = newSource[reaction];
+ newReactions.push(_reactions.value[i]);
}
}
@@ -79,11 +92,11 @@ watch([() => props.note.reactions, () => props.maxNumber], ([newSource, maxNumbe
newReactions = newReactions.slice(0, props.maxNumber);
- if (props.note.myReaction && !newReactions.map(([x]) => x).includes(props.note.myReaction)) {
- newReactions.push([props.note.myReaction, newSource[props.note.myReaction]]);
+ if (props.myReaction && !newReactions.map(([x]) => x).includes(props.myReaction)) {
+ newReactions.push([props.myReaction, newSource[props.myReaction]]);
}
- reactions.value = newReactions;
+ _reactions.value = newReactions;
}, { immediate: true, deep: true });
diff --git a/packages/frontend/src/components/MkRemoteEmojiEditDialog.vue b/packages/frontend/src/components/MkRemoteEmojiEditDialog.vue
index cb50df1743..abe6466971 100644
--- a/packages/frontend/src/components/MkRemoteEmojiEditDialog.vue
+++ b/packages/frontend/src/components/MkRemoteEmojiEditDialog.vue
@@ -56,7 +56,7 @@ SPDX-License-Identifier: AGPL-3.0-only
+
+
diff --git a/packages/frontend/src/components/MkTutorialDialog.Note.vue b/packages/frontend/src/components/MkTutorialDialog.Note.vue
index 59e1b096ae..95f53e7635 100644
--- a/packages/frontend/src/components/MkTutorialDialog.Note.vue
+++ b/packages/frontend/src/components/MkTutorialDialog.Note.vue
@@ -76,8 +76,6 @@ const onceReacted = ref(false);
function addReaction(emoji) {
onceReacted.value = true;
emit('reacted');
- exampleNote.reactions[emoji] = 1;
- exampleNote.myReaction = emoji;
doNotification(emoji);
}
diff --git a/packages/frontend/src/components/MkUserAnnouncementEditDialog.vue b/packages/frontend/src/components/MkUserAnnouncementEditDialog.vue
index aaefa5036a..8ec48dcc3f 100644
--- a/packages/frontend/src/components/MkUserAnnouncementEditDialog.vue
+++ b/packages/frontend/src/components/MkUserAnnouncementEditDialog.vue
@@ -50,7 +50,7 @@ SPDX-License-Identifier: AGPL-3.0-only
diff --git a/packages/frontend/src/pages/welcome.timeline.note.vue b/packages/frontend/src/pages/welcome.timeline.note.vue
index 680fe08c14..62a220d2f1 100644
--- a/packages/frontend/src/pages/welcome.timeline.note.vue
+++ b/packages/frontend/src/pages/welcome.timeline.note.vue
@@ -27,7 +27,8 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
+