Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(frontend): ノート投稿に関する実績が投稿したアカウントで解除されるように #13511

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- Fix: デッキのタイムラインカラムで「センシティブなファイルを含むノートを表示」設定が使用できなかった問題を修正
- Fix: Encode RSS urls with escape sequences before fetching allowing query parameters to be used
- Fix: リンク切れを修正
- Fix: 別アカウントを指定してノートを投稿した場合でも自分のアカウントの実績が解除されてしまう問題を修正

### Server
- Enhance: 起動前の疎通チェックで、DBとメイン以外のRedisの疎通確認も行うように
Expand Down
25 changes: 16 additions & 9 deletions packages/frontend/src/components/MkPostForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -835,17 +835,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',
Expand All @@ -861,22 +868,22 @@ 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();
const h = date.getHours();
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 => {
Expand Down
29 changes: 21 additions & 8 deletions packages/frontend/src/scripts/achievements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -487,21 +487,34 @@ 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<string>();
const claimingQueue = new Set<{
name: typeof ACHIEVEMENT_TYPES[number];
token?: string;
}>();
Comment on lines +492 to +495
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SetにObject入れても期待した結果にならないわね(別のものとして扱われる)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

別アカウントの実績だけ即時獲得にするか

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mapにするか


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);
// バックエンドにも実績を獲ったかどうかのチェックがあるのでtoken指定時は常に実績獲得を送信する
if ((!token || token === $i.token) && claimedAchievements.includes(type)) return;

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_) {
Expand Down
Loading