diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue index e03faeaf55..ad5e7c5e11 100644 --- a/packages/frontend/src/components/MkPostForm.vue +++ b/packages/frontend/src/components/MkPostForm.vue @@ -803,17 +803,24 @@ async function post(ev?: MouseEvent) { miLocalStorage.setItem('hashtags', JSON.stringify(unique(hashtags_.concat(history)))); } posting.value = false; - postAccount.value = null; - incNotesCount(); - if (notesCount === 1) { - claimAchievement('notes1'); + const isMe = postAccount.value?.id === $i.id; + + if (isMe) { + incNotesCount(); + if (notesCount === 1) { + claimAchievement('notes1'); + } + } else if ((postAccount.value?.notesCount ?? 0) <= 0) { + claimAchievement('notes1', token); } + postAccount.value = null; + const text = postData.text ?? ''; const lowerCase = text.toLowerCase(); if ((lowerCase.includes('love') || lowerCase.includes('❤')) && lowerCase.includes('misskey')) { - claimAchievement('iLoveMisskey'); + claimAchievement('iLoveMisskey', token); } if ([ 'https://youtu.be/Efrlqw8ytg4', @@ -829,11 +836,11 @@ async function post(ev?: MouseEvent) { 'https://open.spotify.com/track/5Odr16TvEN4my22K9nbH7l', 'https://open.spotify.com/album/5bOlxyl4igOrp2DwVQxBco', ].some(url => text.includes(url))) { - claimAchievement('brainDiver'); + claimAchievement('brainDiver', token); } if (props.renote && (props.renote.userId === $i.id) && text.length > 0) { - claimAchievement('selfQuote'); + claimAchievement('selfQuote', token); } const date = new Date(); @@ -841,10 +848,10 @@ async function post(ev?: MouseEvent) { const m = date.getMinutes(); const s = date.getSeconds(); if (h >= 0 && h <= 3) { - claimAchievement('postedAtLateNight'); + claimAchievement('postedAtLateNight', token); } if (m === 0 && s === 0) { - claimAchievement('postedAt0min0sec'); + claimAchievement('postedAt0min0sec', token); } }); }).catch(err => { diff --git a/packages/frontend/src/scripts/achievements.ts b/packages/frontend/src/scripts/achievements.ts index f5d0ab559f..4ae3fe9085 100644 --- a/packages/frontend/src/scripts/achievements.ts +++ b/packages/frontend/src/scripts/achievements.ts @@ -487,21 +487,32 @@ export const ACHIEVEMENT_BADGES = { */ } as const; -export const claimedAchievements: typeof ACHIEVEMENT_TYPES[number][] = ($i && $i.achievements) ? $i.achievements.map(x => x.name) : []; +export const claimedAchievements: typeof ACHIEVEMENT_TYPES[number][] = ($i && $i.achievements) ? $i.achievements.map(x => x.name as typeof ACHIEVEMENT_TYPES[number]) : []; -const claimingQueue = new Set(); +const claimingQueue = new Set<{ + name: typeof ACHIEVEMENT_TYPES[number]; + token?: string; +}>(); -export async function claimAchievement(type: typeof ACHIEVEMENT_TYPES[number]) { +export async function claimAchievement(type: typeof ACHIEVEMENT_TYPES[number], token?: string) { if ($i == null) return; if ($i.movedTo) return; if (claimedAchievements.includes(type)) return; - claimingQueue.add(type); - claimedAchievements.push(type); + claimingQueue.add({ + name: type, + token, + }); + if (!token || $i.token !== token) { + claimedAchievements.push(type); + } await new Promise(resolve => setTimeout(resolve, (claimingQueue.size - 1) * 500)); window.setTimeout(() => { - claimingQueue.delete(type); + claimingQueue.delete({ + name: type, + token, + }); }, 500); - misskeyApi('i/claim-achievement', { name: type }); + misskeyApi('i/claim-achievement', { name: type }, token); } if (_DEV_) {