diff --git a/.config/LICENSE b/.config/LICENSE index ed7bfbda4..2e3e984ec 100644 --- a/.config/LICENSE +++ b/.config/LICENSE @@ -1,4 +1,3 @@ -Copyright 2024 The TrashPoss contributors Copyright 2023 The Iceshrimp contributors Copyright 2023 The Firefish contributors diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index b6f18cdab..0023c0f5b 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -984,222 +984,6 @@ showWithSparkles: "タイトルをキラキラさせる" youHaveUnreadAnnouncements: "未読のお知らせがあります" neverShow: "今後表示しない" remindMeLater: "また後で" -achievements: "実績" - -_achievements: - earnedAt: "獲得日時" - _types: - _notes1: - title: "just setting up my msky" - description: "初めてノートを投稿した" - flavor: "良いMisskeyライフを!" - _notes10: - title: "いくつかのノート" - description: "ノートを10回投稿した" - _notes100: - title: "たくさんのノート" - description: "ノートを100回投稿した" - _notes500: - title: "ノートまみれ" - description: "ノートを500回投稿した" - _notes1000: - title: "ノートの山" - description: "ノートを1,000回投稿した" - _notes5000: - title: "湧き出るノート" - description: "ノートを5,000回投稿した" - _notes10000: - title: "スーパーノート" - description: "ノートを10,000回投稿した" - _notes20000: - title: "ニードモアノート" - description: "ノートを20,000回投稿した" - _notes30000: - title: "ノートノートノート" - description: "ノートを30,000回投稿した" - _notes40000: - title: "ノート工場" - description: "ノートを40,000回投稿した" - _notes50000: - title: "ノートの惑星" - description: "ノートを50,000回投稿した" - _notes60000: - title: "ノートクエーサー" - description: "ノートを60,000回投稿した" - _notes70000: - title: "ブラックノートホール" - description: "ノートを70,000回投稿した" - _notes80000: - title: "ノートギャラクシー" - description: "ノートを80,000回投稿した" - _notes90000: - title: "ノートバース" - description: "ノートを90,000回投稿した" - _notes100000: - title: "ALL YOUR NOTE ARE BELONG TO US" - description: "ノートを100,000回投稿した" - flavor: "そんなに書くことある?" - _login3: - title: "ビギナーⅠ" - description: "通算ログイン日数が3日" - flavor: "今日からね僕は ミスキストってことで" - _login7: - title: "ビギナーⅡ" - description: "通算ログイン日数が7日" - flavor: "慣れてきましたか?" - _login15: - title: "ビギナーⅢ" - description: "通算ログイン日数が15日" - _login30: - title: "ミスキストⅠ" - description: "通算ログイン日数が30日" - _login60: - title: "ミスキストⅡ" - description: "通算ログイン日数が60日" - _login100: - title: "ミスキストⅢ" - description: "通算ログイン日数が100日" - flavor: "そのユーザー、ミスキストにつき" - _login200: - title: "常連Ⅰ" - description: "通算ログイン日数が200日" - _login300: - title: "常連Ⅱ" - description: "通算ログイン日数が300日" - _login400: - title: "常連Ⅲ" - description: "通算ログイン日数が400日" - _login500: - title: "ベテランⅠ" - description: "通算ログイン日数が500日" - flavor: "諸君、私はノートが好きだ" - _login600: - title: "ベテランⅡ" - description: "通算ログイン日数が600日" - _login700: - title: "ベテランⅢ" - description: "通算ログイン日数が700日" - _login800: - title: "ノートマスターⅠ" - description: "通算ログイン日数が800日" - _login900: - title: "ノートマスターⅡ" - description: "通算ログイン日数が900日" - _login1000: - title: "ノートマスターⅢ" - description: "通算ログイン日数が1,000日" - flavor: "Misskeyを使ってくれてありがとう!" - _noteClipped1: - title: "クリップせずにはいられないな" - description: "初めてノートをクリップした" - _noteFavorited1: - title: "星をみるひと" - description: "初めてノートをお気に入りに登録した" - _profileFilled: - title: "準備万端" - description: "プロフィール設定を行った" - _markedAsCat: - title: "吾輩は猫である" - description: "アカウントをCatとして設定した" - flavor: "名前はまだない。" - _following1: - title: "はじめてのフォロー" - description: "初めてフォローした" - _following10: - title: "ついてく、ついてく" - description: "フォローが10人を超した" - _following50: - title: "友達たくさん" - description: "フォローが50人を超した" - _following100: - title: "友達100人" - description: "フォローが100人を超した" - _following300: - title: "友達過多" - description: "フォローが300人を超した" - _followers1: - title: "はじめてのフォロワー" - description: "初めてフォローされた" - _followers10: - title: "フォローミー!" - description: "フォロワーが10人を超した" - _followers50: - title: "ぞろぞろ" - description: "フォロワーが50人を超した" - _followers100: - title: "人気者" - description: "フォロワーが100人を超した" - _followers300: - title: "一列でお並びください" - description: "フォロワーが300人を超した" - _followers500: - title: "基地局" - description: "フォロワーが500人を超した" - _followers1000: - title: "インフルエンサー" - description: "フォロワーが1,000人を超した" - _collectAchievements30: - title: "実績コレクター" - description: "実績を30個以上獲得した" - _iLoveMisskey: - title: "I Love Misskey" - description: "\"I ❤ #Misskey\"を投稿した" - flavor: "Misskeyを使ってくださりありがとうございます! by 開発チーム" - _client30min: - title: "ひとやすみ" - description: "クライアントを起動してから30分以上経過した" - _noteDeletedWithin1min: - title: "いまのなし" - description: "投稿してから1分以内にその投稿を削除した" - _postedAtLateNight: - title: "夜行性" - description: "深夜にノートを投稿した" - flavor: "そろそろ寝よう。" - _postedAt0min0sec: - title: "時報" - description: "0分0秒にノートを投稿した" - flavor: "ポッ ポッ ポッ ピーン" - _selfQuote: - title: "自己言及" - description: "自分のノートを引用した" - _htl20npm: - title: "流れるTL" - description: "ホームタイムラインの流速が20npmを越す" - _driveFolderCircularReference: - title: "循環参照" - description: "ドライブのフォルダを再帰的な入れ子にしようとした" - _reactWithoutRead: - title: "ちゃんと読んだ?" - description: "100文字以上のテキストを含むノートに投稿されてから3秒以内にリアクションした" - _clickedClickHere: - title: "ここをクリック" - description: "ここをクリックした" - _justPlainLucky: - title: "単なるラッキー" - description: "10秒ごとに0.01%の確率で獲得" - _setNameToSyuilo: - title: "神様コンプレックス" - description: "名前を syuilo に設定した" - _passedSinceAccountCreated1: - title: "一周年" - description: "アカウント作成から1年経過した" - _passedSinceAccountCreated2: - title: "二周年" - description: "アカウント作成から2年経過した" - _passedSinceAccountCreated3: - title: "三周年" - description: "アカウント作成から3年経過した" - _loggedInOnBirthday: - title: "ハッピーバースデー" - description: "誕生日にログインした" - _cookieClicked: - title: "クッキーをクリックするゲーム" - description: "クッキーをクリックした" - flavor: "ソフト間違ってない?" - _brainDiver: - title: "Brain Diver" - description: "Brain Diverへのリンクを投稿した" - flavor: "Misskey-Misskey La-Tu-Ma" _sensitiveMediaDetection: description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てられます。サーバーの負荷が少し増えます。" @@ -2060,7 +1844,6 @@ _notification: youWereInvitedToGroup: "{userName}があなたをグループに招待しました" pollEnded: "アンケートの結果が出ました" emptyPushNotificationMessage: "プッシュ通知の更新をしました" - achievementEarned: "実績を獲得" _types: all: "すべて" follow: "フォロー" diff --git a/packages/backend/src/migration/1674118260469-achievement.js b/packages/backend/src/migration/1674118260469-achievement.js deleted file mode 100644 index 131ab96f8..000000000 --- a/packages/backend/src/migration/1674118260469-achievement.js +++ /dev/null @@ -1,33 +0,0 @@ -export class achievement1674118260469 { - name = 'achievement1674118260469' - - async up(queryRunner) { - await queryRunner.query(`ALTER TABLE "notification" ADD "achievement" character varying(128)`); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "achievements" jsonb NOT NULL DEFAULT '[]'`); - await queryRunner.query(`ALTER TYPE "public"."notification_type_enum" RENAME TO "notification_type_enum_old"`); - await queryRunner.query(`CREATE TYPE "public"."notification_type_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'achievementEarned', 'app')`); - await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "public"."notification_type_enum" USING "type"::"text"::"public"."notification_type_enum"`); - await queryRunner.query(`DROP TYPE "public"."notification_type_enum_old"`); - await queryRunner.query(`ALTER TYPE "public"."user_profile_mutingnotificationtypes_enum" RENAME TO "user_profile_mutingnotificationtypes_enum_old"`); - await queryRunner.query(`CREATE TYPE "public"."user_profile_mutingnotificationtypes_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'achievementEarned', 'app')`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" TYPE "public"."user_profile_mutingnotificationtypes_enum"[] USING "mutingNotificationTypes"::"text"::"public"."user_profile_mutingnotificationtypes_enum"[]`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" SET DEFAULT '{}'`); - await queryRunner.query(`DROP TYPE "public"."user_profile_mutingnotificationtypes_enum_old"`); - } - - async down(queryRunner) { - await queryRunner.query(`CREATE TYPE "public"."user_profile_mutingnotificationtypes_enum_old" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app', 'pollEnded')`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" TYPE "public"."user_profile_mutingnotificationtypes_enum_old"[] USING "mutingNotificationTypes"::"text"::"public"."user_profile_mutingnotificationtypes_enum_old"[]`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" SET DEFAULT '{}'`); - await queryRunner.query(`DROP TYPE "public"."user_profile_mutingnotificationtypes_enum"`); - await queryRunner.query(`ALTER TYPE "public"."user_profile_mutingnotificationtypes_enum_old" RENAME TO "user_profile_mutingnotificationtypes_enum"`); - await queryRunner.query(`CREATE TYPE "public"."notification_type_enum_old" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app')`); - await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "public"."notification_type_enum_old" USING "type"::"text"::"public"."notification_type_enum_old"`); - await queryRunner.query(`DROP TYPE "public"."notification_type_enum"`); - await queryRunner.query(`ALTER TYPE "public"."notification_type_enum_old" RENAME TO "notification_type_enum"`); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "achievements"`); - await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "achievement"`); - } -} diff --git a/packages/backend/src/migration/1674255666603-loggedInDates.js b/packages/backend/src/migration/1674255666603-loggedInDates.js deleted file mode 100644 index 6d75ab643..000000000 --- a/packages/backend/src/migration/1674255666603-loggedInDates.js +++ /dev/null @@ -1,11 +0,0 @@ -export class loggedInDates1674255666603 { - name = 'loggedInDates1674255666603' - - async up(queryRunner) { - await queryRunner.query(`ALTER TABLE "user_profile" ADD "loggedInDates" character varying(32) array NOT NULL DEFAULT '{}'`); - } - - async down(queryRunner) { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "loggedInDates"`); - } -} diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index cd2ed9359..2204d2ff0 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -12,7 +12,6 @@ export const notificationTypes = [ "groupInvited", "app", "bite", - "achievementEarned", ] as const; export const noteVisibilities = [ diff --git a/packages/client/src/account.ts b/packages/client/src/account.ts index 08436de8d..c51ef8a2e 100644 --- a/packages/client/src/account.ts +++ b/packages/client/src/account.ts @@ -20,11 +20,6 @@ export const $i = accountData export const iAmModerator = $i != null && ($i.isAdmin || $i.isModerator); export const iAmAdmin = $i?.isAdmin; -export let notesCount = $i == null ? 0 : $i.notesCount; -export function incNotesCount() { - notesCount++; -} - export async function signout() { waiting(); localStorage.removeItem("account"); diff --git a/packages/client/src/components/MkAchievements.vue b/packages/client/src/components/MkAchievements.vue deleted file mode 100644 index 8e9d25274..000000000 --- a/packages/client/src/components/MkAchievements.vue +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - - - - - - - - - {{ i18n.ts._achievements._types['_' + achievement.name].title }} - - {{ new Date(achievement.unlockedAt).getFullYear() }}/{{ new Date(achievement.unlockedAt).getMonth() + 1 }}/{{ new Date(achievement.unlockedAt).getDate() }} - - - {{ i18n.ts._achievements._types['_' + achievement.name].description }} - {{ i18n.ts._achievements._types['_' + achievement.name].flavor }} - - - - {}"> - - - - - ??? - - ??? - - - - - - - - - - - - - diff --git a/packages/client/src/components/MkDrive.folder.vue b/packages/client/src/components/MkDrive.folder.vue index 60e635e62..1bcb9aa26 100644 --- a/packages/client/src/components/MkDrive.folder.vue +++ b/packages/client/src/components/MkDrive.folder.vue @@ -42,7 +42,6 @@ import * as Misskey from "iceshrimp-js"; import * as os from "@/os"; import { i18n } from "@/i18n"; import { defaultStore } from "@/store"; -import { claimAchievement } from '@/scripts/achievements'; const props = withDefaults( defineProps<{ @@ -161,11 +160,9 @@ function onDrop(ev: DragEvent) { // noop }) .catch((err) => { - switch (err.code) { - case 'RECURSIVE_NESTING': - claimAchievement('driveFolderCircularReference'); + switch (err) { + case "detected-circular-definition": os.alert({ - type: 'error', title: i18n.ts.unableToProcess, text: i18n.ts.circularReferenceFolder, }); diff --git a/packages/client/src/components/MkDrive.vue b/packages/client/src/components/MkDrive.vue index 91067048a..fdeafb2be 100644 --- a/packages/client/src/components/MkDrive.vue +++ b/packages/client/src/components/MkDrive.vue @@ -150,7 +150,6 @@ import { stream } from "@/stream"; import { defaultStore } from "@/store"; import { i18n } from "@/i18n"; import { uploadFile, uploads } from "@/scripts/upload"; -import { claimAchievement } from '@/scripts/achievements'; const props = withDefaults( defineProps<{ @@ -326,11 +325,9 @@ function onDrop(ev: DragEvent): any { // noop }) .catch((err) => { - switch (err.code) { - case 'RECURSIVE_NESTING': - claimAchievement('driveFolderCircularReference'); + switch (err) { + case "detected-circular-definition": os.alert({ - type: 'error', title: i18n.ts.unableToProcess, text: i18n.ts.circularReferenceFolder, }); diff --git a/packages/client/src/components/MkFollowButton.vue b/packages/client/src/components/MkFollowButton.vue index a205e69e2..ec75fcab9 100644 --- a/packages/client/src/components/MkFollowButton.vue +++ b/packages/client/src/components/MkFollowButton.vue @@ -66,7 +66,6 @@ import type * as Misskey from "iceshrimp-js"; import * as os from "@/os"; import { stream } from "@/stream"; import { i18n } from "@/i18n"; -import { claimAchievement } from '@/scripts/achievements'; import { $i } from "@/account"; import { getUserMenu } from "@/scripts/get-user-menu"; import { useRouter } from "@/router"; @@ -155,21 +154,6 @@ async function onClick() { userId: props.user.id, }); hasPendingFollowRequestFromYou = true; - - claimAchievement('following1'); - - if ($i.followingCount >= 10) { - claimAchievement('following10'); - } - if ($i.followingCount >= 50) { - claimAchievement('following50'); - } - if ($i.followingCount >= 100) { - claimAchievement('following100'); - } - if ($i.followingCount >= 300) { - claimAchievement('following300'); - } } } } catch (err) { diff --git a/packages/client/src/components/MkNote.vue b/packages/client/src/components/MkNote.vue index f85db3b9c..02c0f5647 100644 --- a/packages/client/src/components/MkNote.vue +++ b/packages/client/src/components/MkNote.vue @@ -291,7 +291,6 @@ import { getNoteMenu } from "@/scripts/get-note-menu"; import { useNoteCapture } from "@/scripts/use-note-capture"; import { notePage } from "@/filters/note"; import { deepClone } from "@/scripts/clone"; -import { claimAchievement } from '@/scripts/achievements'; import { getNoteSummary } from "@/scripts/get-note-summary"; const router = useRouter(); @@ -395,9 +394,6 @@ function react(viaKeyboard = false): void { noteId: appearNote.id, reaction: reaction, }); - if (appearNote.text && appearNote.text.length > 100 && (Date.now() - new Date(appearNote.createdAt).getTime() < 1000 * 3)) { - claimAchievement('reactWithoutRead'); - } }, () => { focus(); diff --git a/packages/client/src/components/MkNoteDetailed.vue b/packages/client/src/components/MkNoteDetailed.vue index d237b11f5..d3cbf19a1 100644 --- a/packages/client/src/components/MkNoteDetailed.vue +++ b/packages/client/src/components/MkNoteDetailed.vue @@ -184,7 +184,6 @@ import { i18n } from "@/i18n"; import { getNoteMenu } from "@/scripts/get-note-menu"; import { useNoteCapture } from "@/scripts/use-note-capture"; import { deepClone } from "@/scripts/clone"; -import { claimAchievement } from '@/scripts/achievements'; import { stream } from "@/stream"; import { NoteUpdatedEvent } from "iceshrimp-js/src/streaming.types"; import appear from "@/directives/appear"; @@ -278,9 +277,6 @@ function react(viaKeyboard = false): void { noteId: note.id, reaction: reaction, }); - if (appearNote.text && appearNote.text.length > 100 && (Date.now() - new Date(appearNote.createdAt).getTime() < 1000 * 3)) { - claimAchievement('reactWithoutRead'); - } }, () => { focus(); diff --git a/packages/client/src/components/MkNotification.vue b/packages/client/src/components/MkNotification.vue index b99239e76..cec021b7a 100644 --- a/packages/client/src/components/MkNotification.vue +++ b/packages/client/src/components/MkNotification.vue @@ -11,11 +11,6 @@ class="icon" :user="notification.note.user" /> - - {{ i18n.ts._notification.pollEnded }} - {{ - i18n.ts._notification.achievementEarned - }} - - {{ i18n.ts._achievements._types['_' + notification.achievement].title }} - { pointer-events: none; } - &.mention { - padding: 3px; - background: #88a6b7; - pointer-events: none; - } - &.pollVote { padding: 3px; background: #908caa; diff --git a/packages/client/src/components/MkPostForm.vue b/packages/client/src/components/MkPostForm.vue index 266e83827..a0a325fa6 100644 --- a/packages/client/src/components/MkPostForm.vue +++ b/packages/client/src/components/MkPostForm.vue @@ -259,8 +259,6 @@ import { i18n } from "@/i18n"; import { instance } from "@/instance"; import { $i, - notesCount, - incNotesCount, getAccounts, openAccountMenu as openAccountMenu_, } from "@/account"; @@ -905,34 +903,6 @@ async function post() { } posting = false; postAccount = null; - - incNotesCount(); - if (notesCount === 1) { - claimAchievement('notes1'); - } - - const text = postData.text?.toLowerCase() ?? ''; - if ((text.includes('love') || text.includes('❤')) && text.includes('misskey')) { - claimAchievement('iLoveMisskey'); - } - if (text.includes('Efrlqw8ytg4'.toLowerCase()) || text.includes('XVCwzwxdHuA'.toLowerCase())) { - claimAchievement('brainDiver'); - } - - if (props.renote && (props.renote.userId === $i.id) && text.length > 0) { - claimAchievement('selfQuote'); - } - - const date = new Date(); - const h = date.getHours(); - const m = date.getMinutes(); - const s = date.getSeconds(); - if (h >= 0 && h <= 3) { - claimAchievement('postedAtLateNight'); - } - if (m === 0 && s === 0) { - claimAchievement('postedAt0min0sec'); - } }); }) .catch((err) => { diff --git a/packages/client/src/components/MkReactionsViewer.reaction.vue b/packages/client/src/components/MkReactionsViewer.reaction.vue index 336e68c4c..1c63aa8b6 100644 --- a/packages/client/src/components/MkReactionsViewer.reaction.vue +++ b/packages/client/src/components/MkReactionsViewer.reaction.vue @@ -28,7 +28,6 @@ import XReactionIcon from "@/components/MkReactionIcon.vue"; import * as os from "@/os"; import { useTooltip } from "@/scripts/use-tooltip"; import { $i } from "@/account"; -import { claimAchievement } from '@/scripts/achievements'; const props = defineProps<{ reaction: string; @@ -65,9 +64,6 @@ const toggleReaction = () => { noteId: props.note.id, reaction: props.reaction, }); - if (props.note.text && props.note.text.length > 100 && (Date.now() - new Date(props.note.createdAt).getTime() < 1000 * 3)) { - claimAchievement('reactWithoutRead'); - } emit("reacted"); } }; diff --git a/packages/client/src/init.ts b/packages/client/src/init.ts index b929d2172..b244002a7 100644 --- a/packages/client/src/init.ts +++ b/packages/client/src/init.ts @@ -49,7 +49,6 @@ import { reloadChannel } from "@/scripts/unison-reload"; import { reactionPicker } from "@/scripts/reaction-picker"; import { getUrlWithoutLoginId } from "@/scripts/login-id"; import { getAccountFromId } from "@/scripts/get-account-from-id"; -import { claimAchievement, claimedAchievements } from './scripts/achievements'; function checkForSplash() { const splash = document.getElementById("splash"); @@ -441,82 +440,6 @@ function checkForSplash() { }); } - if ($i.birthday) { - const now = new Date(); - const m = now.getMonth() + 1; - const d = now.getDate(); - const bm = parseInt($i.birthday.split('-')[1]); - const bd = parseInt($i.birthday.split('-')[2]); - if (m === bm && d === bd) { - claimAchievement('loggedInOnBirthday'); - } - } - - if ($i.loggedInDays >= 3) claimAchievement('login3'); - if ($i.loggedInDays >= 7) claimAchievement('login7'); - if ($i.loggedInDays >= 15) claimAchievement('login15'); - if ($i.loggedInDays >= 30) claimAchievement('login30'); - if ($i.loggedInDays >= 60) claimAchievement('login60'); - if ($i.loggedInDays >= 100) claimAchievement('login100'); - if ($i.loggedInDays >= 200) claimAchievement('login200'); - if ($i.loggedInDays >= 300) claimAchievement('login300'); - if ($i.loggedInDays >= 400) claimAchievement('login400'); - if ($i.loggedInDays >= 500) claimAchievement('login500'); - if ($i.loggedInDays >= 600) claimAchievement('login600'); - if ($i.loggedInDays >= 700) claimAchievement('login700'); - if ($i.loggedInDays >= 800) claimAchievement('login800'); - if ($i.loggedInDays >= 900) claimAchievement('login900'); - if ($i.loggedInDays >= 1000) claimAchievement('login1000'); - - if ($i.notesCount > 0) claimAchievement('notes1'); - if ($i.notesCount >= 10) claimAchievement('notes10'); - if ($i.notesCount >= 100) claimAchievement('notes100'); - if ($i.notesCount >= 500) claimAchievement('notes500'); - if ($i.notesCount >= 1000) claimAchievement('notes1000'); - if ($i.notesCount >= 5000) claimAchievement('notes5000'); - if ($i.notesCount >= 10000) claimAchievement('notes10000'); - if ($i.notesCount >= 20000) claimAchievement('notes20000'); - if ($i.notesCount >= 30000) claimAchievement('notes30000'); - if ($i.notesCount >= 40000) claimAchievement('notes40000'); - if ($i.notesCount >= 50000) claimAchievement('notes50000'); - if ($i.notesCount >= 60000) claimAchievement('notes60000'); - if ($i.notesCount >= 70000) claimAchievement('notes70000'); - if ($i.notesCount >= 80000) claimAchievement('notes80000'); - if ($i.notesCount >= 90000) claimAchievement('notes90000'); - if ($i.notesCount >= 100000) claimAchievement('notes100000'); - - if ($i.followersCount > 0) claimAchievement('followers1'); - if ($i.followersCount >= 10) claimAchievement('followers10'); - if ($i.followersCount >= 50) claimAchievement('followers50'); - if ($i.followersCount >= 100) claimAchievement('followers100'); - if ($i.followersCount >= 300) claimAchievement('followers300'); - if ($i.followersCount >= 500) claimAchievement('followers500'); - if ($i.followersCount >= 1000) claimAchievement('followers1000'); - - if (Date.now() - new Date($i.createdAt).getTime() > 1000 * 60 * 60 * 24 * 365) { - claimAchievement('passedSinceAccountCreated1'); - } - if (Date.now() - new Date($i.createdAt).getTime() > 1000 * 60 * 60 * 24 * 365 * 2) { - claimAchievement('passedSinceAccountCreated2'); - } - if (Date.now() - new Date($i.createdAt).getTime() > 1000 * 60 * 60 * 24 * 365 * 3) { - claimAchievement('passedSinceAccountCreated3'); - } - - if (claimedAchievements.length >= 30) { - claimAchievement('collectAchievements30'); - } - - window.setInterval(() => { - if (Math.floor(Math.random() * 10000) === 0) { - claimAchievement('justPlainLucky'); - } - }, 1000 * 10); - - window.setTimeout(() => { - claimAchievement('client30min'); - }, 1000 * 60 * 30); - if ("Notification" in window) { // 許可を得ていなかったらリクエスト if (Notification.permission === "default") { diff --git a/packages/client/src/navbar.ts b/packages/client/src/navbar.ts index 3c4351f58..da6077cef 100644 --- a/packages/client/src/navbar.ts +++ b/packages/client/src/navbar.ts @@ -106,12 +106,6 @@ export const navbarItemDef = reactive({ icon: "ph-users-three ph-bold ph-lg", to: "/my/groups", }, - achievements: { - title: i18n.ts.achievements, - icon: 'ph-awards-military ph-bold', - show: computed(() => $i != null), - to: '/my/achievements', - }, ui: { title: "switchUi", icon: "ph-layout ph-bold ph-lg", diff --git a/packages/client/src/pages/achievements.vue b/packages/client/src/pages/achievements.vue deleted file mode 100644 index a721f934a..000000000 --- a/packages/client/src/pages/achievements.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - diff --git a/packages/client/src/pages/settings/profile.vue b/packages/client/src/pages/settings/profile.vue index 255bf1cac..3b94a8248 100644 --- a/packages/client/src/pages/settings/profile.vue +++ b/packages/client/src/pages/settings/profile.vue @@ -177,7 +177,6 @@ import { i18n } from "@/i18n"; import { $i } from "@/account"; import { langmap } from "@/scripts/langmap"; import { definePageMetadata } from "@/scripts/page-metadata"; -import { claimAchievement } from '@/scripts/achievements'; import { host } from "@/config"; const profile = reactive({ @@ -244,14 +243,6 @@ function save() { isCat: !!profile.isCat, speakAsCat: !!profile.speakAsCat, }); - claimAchievement('profileFilled'); - if (profile.name === 'syuilo' || profile.name === 'しゅいろ') { - claimAchievement('setNameToSyuilo'); - } - if (profile.isCat) { - claimAchievement('markedAsCat'); - } - } function changeAvatar(ev) { @@ -275,7 +266,6 @@ function changeAvatar(ev) { }); $i.avatarId = i.avatarId; $i.avatarUrl = i.avatarUrl; - claimAchievement('profileFilled'); }, ); } diff --git a/packages/client/src/router.ts b/packages/client/src/router.ts index d1e5bef46..ff224bba3 100644 --- a/packages/client/src/router.ts +++ b/packages/client/src/router.ts @@ -564,11 +564,6 @@ export const routes = [ component: page(() => import("./pages/favorites.vue")), loginRequired: true, }, - { - path: '/my/achievements', - component: page(() => import('./pages/achievements.vue')), - loginRequired: true, - }, { name: "messaging", path: "/my/messaging", diff --git a/packages/client/src/scripts/achievements.ts b/packages/client/src/scripts/achievements.ts deleted file mode 100644 index c8245ad3d..000000000 --- a/packages/client/src/scripts/achievements.ts +++ /dev/null @@ -1,425 +0,0 @@ -import * as os from '@/os'; -import { $i } from '@/account'; - -export const ACHIEVEMENT_TYPES = [ - 'notes1', - 'notes10', - 'notes100', - 'notes500', - 'notes1000', - 'notes5000', - 'notes10000', - 'notes20000', - 'notes30000', - 'notes40000', - 'notes50000', - 'notes60000', - 'notes70000', - 'notes80000', - 'notes90000', - 'notes100000', - 'login3', - 'login7', - 'login15', - 'login30', - 'login60', - 'login100', - 'login200', - 'login300', - 'login400', - 'login500', - 'login600', - 'login700', - 'login800', - 'login900', - 'login1000', - 'passedSinceAccountCreated1', - 'passedSinceAccountCreated2', - 'passedSinceAccountCreated3', - 'loggedInOnBirthday', - 'noteClipped1', - 'noteFavorited1', - 'profileFilled', - 'markedAsCat', - 'following1', - 'following10', - 'following50', - 'following100', - 'following300', - 'followers1', - 'followers10', - 'followers50', - 'followers100', - 'followers300', - 'followers500', - 'followers1000', - 'collectAchievements30', - 'iLoveMisskey', - 'client30min', - 'noteDeletedWithin1min', - 'postedAtLateNight', - 'postedAt0min0sec', - 'selfQuote', - 'htl20npm', - 'driveFolderCircularReference', - 'reactWithoutRead', - 'clickedClickHere', - 'justPlainLucky', - 'setNameToSyuilo', - 'cookieClicked', - 'brainDiver', -] as const; - -export const ACHIEVEMENT_BADGES = { - 'notes1': { - img: '/fluent-emoji/1f4dd.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'bronze', - }, - 'notes10': { - img: '/fluent-emoji/1f4d1.png', - bg: null, - frame: 'bronze', - }, - 'notes100': { - img: '/fluent-emoji/1f4d2.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'bronze', - }, - 'notes500': { - img: '/fluent-emoji/1f4da.png', - bg: null, - frame: 'bronze', - }, - 'notes1000': { - img: '/fluent-emoji/1f5c3.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'bronze', - }, - 'notes5000': { - img: '/fluent-emoji/1f304.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'bronze', - }, - 'notes10000': { - img: '/fluent-emoji/1f3d9.png', - bg: 'linear-gradient(0deg, rgb(220 223 225), rgb(172 192 207))', - frame: 'silver', - }, - 'notes20000': { - img: '/fluent-emoji/1f307.png', - bg: 'linear-gradient(0deg, rgb(220 223 225), rgb(172 192 207))', - frame: 'silver', - }, - 'notes30000': { - img: '/fluent-emoji/1f306.png', - bg: 'linear-gradient(0deg, rgb(144 224 255), rgb(255 168 252))', - frame: 'silver', - }, - 'notes40000': { - img: '/fluent-emoji/1f303.png', - bg: 'linear-gradient(0deg, rgb(197 69 192), rgb(2 112 155))', - frame: 'silver', - }, - 'notes50000': { - img: '/fluent-emoji/1fa90.png', - bg: 'linear-gradient(0deg, rgb(144 224 255), rgb(255 168 252))', - frame: 'gold', - }, - 'notes60000': { - img: '/fluent-emoji/2604.png', - bg: 'linear-gradient(0deg, rgb(197 69 192), rgb(2 112 155))', - frame: 'gold', - }, - 'notes70000': { - img: '/fluent-emoji/1f30c.png', - bg: 'linear-gradient(0deg, rgb(144 224 255), rgb(255 168 252))', - frame: 'gold', - }, - 'notes80000': { - img: '/fluent-emoji/1f30c.png', - bg: 'linear-gradient(0deg, rgb(197 69 192), rgb(2 112 155))', - frame: 'gold', - }, - 'notes90000': { - img: '/fluent-emoji/1f30c.png', - bg: 'linear-gradient(0deg, rgb(255 232 119), rgb(255 140 41))', - frame: 'gold', - }, - 'notes100000': { - img: '/fluent-emoji/267e.png', - bg: 'linear-gradient(0deg, rgb(255 232 119), rgb(255 140 41))', - frame: 'platinum', - }, - 'login3': { - img: '/fluent-emoji/1f331.png', - bg: null, - frame: 'bronze', - }, - 'login7': { - img: '/fluent-emoji/1f331.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'bronze', - }, - 'login15': { - img: '/fluent-emoji/1f331.png', - bg: 'linear-gradient(0deg, rgb(144, 224, 255), rgb(255, 168, 252))', - frame: 'bronze', - }, - 'login30': { - img: '/fluent-emoji/1fab4.png', - bg: null, - frame: 'bronze', - }, - 'login60': { - img: '/fluent-emoji/1fab4.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'bronze', - }, - 'login100': { - img: '/fluent-emoji/1fab4.png', - bg: 'linear-gradient(0deg, rgb(144, 224, 255), rgb(255, 168, 252))', - frame: 'silver', - }, - 'login200': { - img: '/fluent-emoji/1f333.png', - bg: null, - frame: 'silver', - }, - 'login300': { - img: '/fluent-emoji/1f333.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'silver', - }, - 'login400': { - img: '/fluent-emoji/1f333.png', - bg: 'linear-gradient(0deg, rgb(144, 224, 255), rgb(255, 168, 252))', - frame: 'silver', - }, - 'login500': { - img: '/fluent-emoji/1f304.png', - bg: null, - frame: 'silver', - }, - 'login600': { - img: '/fluent-emoji/1f304.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'gold', - }, - 'login700': { - img: '/fluent-emoji/1f304.png', - bg: 'linear-gradient(0deg, rgb(144, 224, 255), rgb(255, 168, 252))', - frame: 'gold', - }, - 'login800': { - img: '/fluent-emoji/1f307.png', - bg: null, - frame: 'gold', - }, - 'login900': { - img: '/fluent-emoji/1f307.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'gold', - }, - 'login1000': { - img: '/fluent-emoji/1f307.png', - bg: 'linear-gradient(0deg, rgb(144, 224, 255), rgb(255, 168, 252))', - frame: 'platinum', - }, - 'noteClipped1': { - img: '/fluent-emoji/1f587.png', - bg: null, - frame: 'bronze', - }, - 'noteFavorited1': { - img: '/fluent-emoji/1f31f.png', - bg: null, - frame: 'bronze', - }, - 'profileFilled': { - img: '/fluent-emoji/1f44c.png', - bg: 'linear-gradient(0deg, rgb(187 183 59), rgb(255 143 77))', - frame: 'bronze', - }, - 'markedAsCat': { - img: '/fluent-emoji/1f408.png', - bg: 'linear-gradient(0deg, rgb(187 183 59), rgb(255 143 77))', - frame: 'bronze', - }, - 'following1': { - img: '/fluent-emoji/2618.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'bronze', - }, - 'following10': { - img: '/fluent-emoji/1f6b8.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'bronze', - }, - 'following50': { - img: '/fluent-emoji/1f91d.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'bronze', - }, - 'following100': { - img: '/fluent-emoji/1f4af.png', - bg: 'linear-gradient(0deg, rgb(255 53 184), rgb(255 206 69))', - frame: 'silver', - }, - 'following300': { - img: '/fluent-emoji/1f970.png', - bg: 'linear-gradient(0deg, rgb(144 224 255), rgb(255 168 252))', - frame: 'silver', - }, - 'followers1': { - img: '/fluent-emoji/2618.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'bronze', - }, - 'followers10': { - img: '/fluent-emoji/1f44b.png', - bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))', - frame: 'bronze', - }, - 'followers50': { - img: '/fluent-emoji/1f411.png', - bg: 'linear-gradient(0deg, rgb(220 223 225), rgb(172 192 207))', - frame: 'bronze', - }, - 'followers100': { - img: '/fluent-emoji/1f396.png', - bg: 'linear-gradient(0deg, rgb(144 224 255), rgb(255 168 252))', - frame: 'silver', - }, - 'followers300': { - img: '/fluent-emoji/1f3c6.png', - bg: 'linear-gradient(0deg, rgb(144 224 255), rgb(255 168 252))', - frame: 'silver', - }, - 'followers500': { - img: '/fluent-emoji/1f4e1.png', - bg: 'linear-gradient(0deg, rgb(220 223 225), rgb(172 192 207))', - frame: 'gold', - }, - 'followers1000': { - img: '/fluent-emoji/1f451.png', - bg: 'linear-gradient(0deg, rgb(255 232 119), rgb(255 140 41))', - frame: 'platinum', - }, - 'collectAchievements30': { - img: '/fluent-emoji/1f3c5.png', - bg: 'linear-gradient(0deg, rgb(255 77 77), rgb(247 155 214))', - frame: 'silver', - }, - 'iLoveMisskey': { - img: '/fluent-emoji/2764.png', - bg: 'linear-gradient(0deg, rgb(255 77 77), rgb(247 155 214))', - frame: 'silver', - }, - 'client30min': { - img: '/fluent-emoji/1f552.png', - bg: 'linear-gradient(0deg, rgb(220 223 225), rgb(172 192 207))', - frame: 'bronze', - }, - 'noteDeletedWithin1min': { - img: '/fluent-emoji/1f5d1.png', - bg: 'linear-gradient(0deg, rgb(220 223 225), rgb(172 192 207))', - frame: 'bronze', - }, - 'postedAtLateNight': { - img: '/fluent-emoji/1f319.png', - bg: 'linear-gradient(0deg, rgb(197 69 192), rgb(2 112 155))', - frame: 'bronze', - }, - 'postedAt0min0sec': { - img: '/fluent-emoji/1f55b.png', - bg: 'linear-gradient(0deg, rgb(58 231 198), rgb(37 194 255))', - frame: 'bronze', - }, - 'selfQuote': { - img: '/fluent-emoji/1f4dd.png', - bg: null, - frame: 'bronze', - }, - 'htl20npm': { - img: '/fluent-emoji/1f30a.png', - bg: 'linear-gradient(0deg, rgb(220 223 225), rgb(172 192 207))', - frame: 'bronze', - }, - 'driveFolderCircularReference': { - img: '/fluent-emoji/1f4c2.png', - bg: 'linear-gradient(0deg, rgb(144 224 255), rgb(255 168 252))', - frame: 'bronze', - }, - 'reactWithoutRead': { - img: '/fluent-emoji/2753.png', - bg: 'linear-gradient(0deg, rgb(144 224 255), rgb(255 168 252))', - frame: 'bronze', - }, - 'clickedClickHere': { - img: '/fluent-emoji/2757.png', - bg: 'linear-gradient(0deg, rgb(144 224 255), rgb(255 168 252))', - frame: 'bronze', - }, - 'justPlainLucky': { - img: '/fluent-emoji/1f340.png', - bg: 'linear-gradient(0deg, rgb(187 183 59), rgb(255 143 77))', - frame: 'silver', - }, - 'setNameToSyuilo': { - img: '/fluent-emoji/1f36e.png', - bg: 'linear-gradient(0deg, rgb(187 183 59), rgb(255 143 77))', - frame: 'bronze', - }, - 'passedSinceAccountCreated1': { - img: '/fluent-emoji/0031-20e3.png', - bg: null, - frame: 'bronze', - }, - 'passedSinceAccountCreated2': { - img: '/fluent-emoji/0032-20e3.png', - bg: null, - frame: 'silver', - }, - 'passedSinceAccountCreated3': { - img: '/fluent-emoji/0033-20e3.png', - bg: null, - frame: 'gold', - }, - 'loggedInOnBirthday': { - img: '/fluent-emoji/1f382.png', - bg: 'linear-gradient(0deg, rgb(144 224 255), rgb(255 168 252))', - frame: 'silver', - }, - 'cookieClicked': { - img: '/fluent-emoji/1f36a.png', - bg: 'linear-gradient(0deg, rgb(187 183 59), rgb(255 143 77))', - frame: 'bronze', - }, - 'brainDiver': { - img: '/fluent-emoji/1f9e0.png', - bg: 'linear-gradient(0deg, rgb(144, 224, 255), rgb(255, 168, 252))', - frame: 'bronze', - }, -} as const satisfies Record; - -export const claimedAchievements = ($i && $i.achievements) ? $i.achievements.map(x => x.name) : []; - -export function claimAchievement(type: typeof ACHIEVEMENT_TYPES[number]) { - if (claimedAchievements.includes(type)) return; - os.api('i/claim-achievement', { name: type }); - claimedAchievements.push(type); -} - -if (_DEV_) { - (window as any).unlockAllAchievements = async () => { - for (const t of ACHIEVEMENT_TYPES) { - await new Promise(resolve => setTimeout(resolve, 100)); - claimAchievement(t); - } - }; -} diff --git a/packages/client/src/scripts/get-note-menu.ts b/packages/client/src/scripts/get-note-menu.ts index 413d6d1da..55e3cbf68 100644 --- a/packages/client/src/scripts/get-note-menu.ts +++ b/packages/client/src/scripts/get-note-menu.ts @@ -1,6 +1,5 @@ import { defineAsyncComponent, Ref, inject } from "vue"; import * as misskey from "iceshrimp-js"; -import { claimAchievement } from './achievements'; import { $i } from "@/account"; import { i18n } from "@/i18n"; import { instance } from "@/instance"; @@ -40,10 +39,6 @@ export function getNoteMenu(props: { os.api("notes/delete", { noteId: appearNote.id, }); - - if (Date.now() - new Date(appearNote.createdAt).getTime() < 1000 * 60) { - claimAchievement('noteDeletedWithin1min'); - } }); } @@ -64,10 +59,6 @@ export function getNoteMenu(props: { reply: appearNote.reply, channel: appearNote.channel, }); - - if (Date.now() - new Date(appearNote.createdAt).getTime() < 1000 * 60) { - claimAchievement('noteDeletedWithin1min'); - } }); } @@ -82,7 +73,6 @@ export function getNoteMenu(props: { } function toggleFavorite(favorite: boolean): void { - claimAchievement('noteFavorited1'); os.apiWithDialog( favorite ? "notes/favorites/create" : "notes/favorites/delete", { @@ -170,7 +160,6 @@ export function getNoteMenu(props: { const clip = await os.apiWithDialog("clips/create", result); - claimAchievement('noteClipped1'); os.apiWithDialog("clips/add-note", { clipId: clip.id, noteId: appearNote.id, @@ -181,7 +170,6 @@ export function getNoteMenu(props: { ...clips.map((clip) => ({ text: clip.name, action: () => { - claimAchievement('noteClipped1'); os.promiseDialog( os.api("clips/add-note", { clipId: clip.id,