diff options
| author | tamaina <tamaina@hotmail.co.jp> | 2023-01-22 12:07:38 +0000 |
|---|---|---|
| committer | tamaina <tamaina@hotmail.co.jp> | 2023-01-22 12:07:38 +0000 |
| commit | a8b19f4aa8ca014ee4f86f15279c1b9b0b592c65 (patch) | |
| tree | 779967d21452e8fab4d9ec872a1277ac68f95956 /packages/frontend/src/scripts | |
| parent | refactor (diff) | |
| parent | 13.1.7 (diff) | |
| download | sharkey-a8b19f4aa8ca014ee4f86f15279c1b9b0b592c65.tar.gz sharkey-a8b19f4aa8ca014ee4f86f15279c1b9b0b592c65.tar.bz2 sharkey-a8b19f4aa8ca014ee4f86f15279c1b9b0b592c65.zip | |
Merge branch 'develop' into emoji-re
Diffstat (limited to 'packages/frontend/src/scripts')
| -rw-r--r-- | packages/frontend/src/scripts/achievements.ts | 474 | ||||
| -rw-r--r-- | packages/frontend/src/scripts/aiscript/ui.ts | 7 | ||||
| -rw-r--r-- | packages/frontend/src/scripts/api.ts | 2 | ||||
| -rw-r--r-- | packages/frontend/src/scripts/get-note-menu.ts | 28 | ||||
| -rw-r--r-- | packages/frontend/src/scripts/mfm-tags.ts | 2 |
5 files changed, 509 insertions, 4 deletions
diff --git a/packages/frontend/src/scripts/achievements.ts b/packages/frontend/src/scripts/achievements.ts new file mode 100644 index 0000000000..c77f8e12d3 --- /dev/null +++ b/packages/frontend/src/scripts/achievements.ts @@ -0,0 +1,474 @@ +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', + 'loggedInOnNewYearsDay', + 'noteClipped1', + 'noteFavorited1', + 'myNoteFavorited1', + 'profileFilled', + 'markedAsCat', + 'following1', + 'following10', + 'following50', + 'following100', + 'following300', + 'followers1', + 'followers10', + 'followers50', + 'followers100', + 'followers300', + 'followers500', + 'followers1000', + 'collectAchievements30', + 'viewAchievements3min', + 'iLoveMisskey', + 'foundTreasure', + 'client30min', + 'noteDeletedWithin1min', + 'postedAtLateNight', + 'postedAt0min0sec', + 'selfQuote', + 'htl20npm', + 'viewInstanceChart', + 'outputHelloWorldOnScratchpad', + 'open3windows', + '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', + }, + 'myNoteFavorited1': { + img: '/fluent-emoji/1f320.png', + bg: null, + frame: 'silver', + }, + '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/1f60e.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', + }, + 'viewAchievements3min': { + img: '/fluent-emoji/1f3c5.png', + bg: 'linear-gradient(0deg, rgb(144 224 255), rgb(255 168 252))', + frame: 'bronze', + }, + 'iLoveMisskey': { + img: '/fluent-emoji/2764.png', + bg: 'linear-gradient(0deg, rgb(255 77 77), rgb(247 155 214))', + frame: 'silver', + }, + 'foundTreasure': { + img: '/fluent-emoji/1f3c6.png', + bg: 'linear-gradient(0deg, rgb(197 69 192), rgb(2 112 155))', + frame: 'gold', + }, + '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', + }, + 'viewInstanceChart': { + img: '/fluent-emoji/1f4ca.png', + bg: 'linear-gradient(0deg, rgb(58 231 198), rgb(37 194 255))', + frame: 'bronze', + }, + 'outputHelloWorldOnScratchpad': { + img: '/fluent-emoji/1f530.png', + bg: 'linear-gradient(0deg, rgb(58 231 198), rgb(37 194 255))', + frame: 'bronze', + }, + 'open3windows': { + img: '/fluent-emoji/1f5a5.png', + bg: 'linear-gradient(0deg, rgb(144 224 255), rgb(255 168 252))', + 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(255 77 77), rgb(247 155 214))', + frame: 'silver', + }, + 'loggedInOnNewYearsDay': { + img: '/fluent-emoji/1f38d.png', + bg: 'linear-gradient(0deg, rgb(255 144 144), rgb(255 232 168))', + 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<typeof ACHIEVEMENT_TYPES[number], { + img: string; + bg: string | null; + frame: 'bronze' | 'silver' | 'gold' | 'platinum'; +}>; + +export const claimedAchievements: typeof ACHIEVEMENT_TYPES[number][] = ($i && $i.achievements) ? $i.achievements.map(x => x.name) : []; + +const claimingQueue = new Set<string>(); + +export async function claimAchievement(type: typeof ACHIEVEMENT_TYPES[number]) { + if ($i == null) return; + if (claimedAchievements.includes(type)) return; + claimingQueue.add(type); + claimedAchievements.push(type); + await new Promise(resolve => setTimeout(resolve, (claimingQueue.size - 1) * 500)); + window.setTimeout(() => { + claimingQueue.delete(type); + }, 500); + os.api('i/claim-achievement', { name: type }); +} + +if (_DEV_) { + (window as any).unlockAllAchievements = () => { + for (const t of ACHIEVEMENT_TYPES) { + claimAchievement(t); + } + }; +} diff --git a/packages/frontend/src/scripts/aiscript/ui.ts b/packages/frontend/src/scripts/aiscript/ui.ts index 2555cd391b..b1895a5f33 100644 --- a/packages/frontend/src/scripts/aiscript/ui.ts +++ b/packages/frontend/src/scripts/aiscript/ui.ts @@ -50,6 +50,7 @@ export type AsUiButton = AsUiComponentBase & { onClick?: () => void; primary?: boolean; rounded?: boolean; + disabled?: boolean; }; export type AsUiButtons = AsUiComponentBase & { @@ -302,6 +303,8 @@ function getButtonOptions(def: values.Value | undefined, call: (fn: values.VFn, if (primary) utils.assertBoolean(primary); const rounded = def.value.get('rounded'); if (rounded) utils.assertBoolean(rounded); + const disabled = button.value.get('disabled'); + if (disabled) utils.assertBoolean(disabled); return { text: text?.value, @@ -310,6 +313,7 @@ function getButtonOptions(def: values.Value | undefined, call: (fn: values.VFn, }, primary: primary?.value, rounded: rounded?.value, + disabled: disabled?.value, }; } @@ -330,6 +334,8 @@ function getButtonsOptions(def: values.Value | undefined, call: (fn: values.VFn, if (primary) utils.assertBoolean(primary); const rounded = button.value.get('rounded'); if (rounded) utils.assertBoolean(rounded); + const disabled = button.value.get('disabled'); + if (disabled) utils.assertBoolean(disabled); return { text: text.value, @@ -338,6 +344,7 @@ function getButtonsOptions(def: values.Value | undefined, call: (fn: values.VFn, }, primary: primary?.value, rounded: rounded?.value, + disabled: disabled?.value, }; }) : [], }; diff --git a/packages/frontend/src/scripts/api.ts b/packages/frontend/src/scripts/api.ts index f9fd11f069..5f34f5333e 100644 --- a/packages/frontend/src/scripts/api.ts +++ b/packages/frontend/src/scripts/api.ts @@ -45,7 +45,7 @@ export function api<E extends keyof Endpoints, P extends Endpoints[E]['req']>(en } // Implements Misskey.api.ApiClient.request -export function apiGet<E extends keyof Endpoints, P extends Endpoints[E]['req']>(endpoint: E, data: P = {} as any): Promise<Endpoints[E]['res']> { +export function apiGet <E extends keyof Endpoints, P extends Endpoints[E]['req']>(endpoint: E, data: P = {} as any): Promise<Endpoints[E]['res']> { pendingApiRequestsCount.value++; const onFinally = () => { diff --git a/packages/frontend/src/scripts/get-note-menu.ts b/packages/frontend/src/scripts/get-note-menu.ts index 54de3d95df..b5d2251d28 100644 --- a/packages/frontend/src/scripts/get-note-menu.ts +++ b/packages/frontend/src/scripts/get-note-menu.ts @@ -1,6 +1,7 @@ import { defineAsyncComponent, Ref, inject } from 'vue'; import * as misskey from 'misskey-js'; import { pleaseLogin } from './please-login'; +import { claimAchievement } from './achievements'; import { $i } from '@/account'; import { i18n } from '@/i18n'; import { instance } from '@/instance'; @@ -38,6 +39,10 @@ export function getNoteMenu(props: { os.api('notes/delete', { noteId: appearNote.id, }); + + if (Date.now() - new Date(appearNote.createdAt).getTime() < 1000 * 60) { + claimAchievement('noteDeletedWithin1min'); + } }); } @@ -53,10 +58,15 @@ export function getNoteMenu(props: { }); os.post({ initialNote: appearNote, renote: appearNote.renote, reply: appearNote.reply, channel: appearNote.channel }); + + if (Date.now() - new Date(appearNote.createdAt).getTime() < 1000 * 60) { + claimAchievement('noteDeletedWithin1min'); + } }); } function toggleFavorite(favorite: boolean): void { + claimAchievement('noteFavorited1'); os.apiWithDialog(favorite ? 'notes/favorites/create' : 'notes/favorites/delete', { noteId: appearNote.id, }); @@ -118,11 +128,13 @@ 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 }); }, }, null, ...clips.map(clip => ({ text: clip.name, action: () => { + claimAchievement('noteClipped1'); os.promiseDialog( os.api('clips/add-note', { clipId: clip.id, noteId: appearNote.id }), null, @@ -174,9 +186,17 @@ export function getNoteMenu(props: { url: `${url}/notes/${appearNote.id}`, }); } - function notedetails(): void { + + function openDetail(): void { os.pageWindow(`/notes/${appearNote.id}`); } + + function showReactions(): void { + os.popup(defineAsyncComponent(() => import('@/components/MkReactedUsersDialog.vue')), { + noteId: appearNote.id, + }, {}, 'closed'); + } + async function translate(): Promise<void> { if (props.translation.value != null) return; props.translating.value = true; @@ -205,7 +225,11 @@ export function getNoteMenu(props: { ), { icon: 'ti ti-info-circle', text: i18n.ts.details, - action: notedetails, + action: openDetail, + }, { + icon: 'ti ti-users', + text: i18n.ts.reactions, + action: showReactions, }, { icon: 'ti ti-copy', text: i18n.ts.copyContent, diff --git a/packages/frontend/src/scripts/mfm-tags.ts b/packages/frontend/src/scripts/mfm-tags.ts index be944a7139..a84198282d 100644 --- a/packages/frontend/src/scripts/mfm-tags.ts +++ b/packages/frontend/src/scripts/mfm-tags.ts @@ -1 +1 @@ -export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'position', 'fg', 'bg', 'font', 'blur', 'rainbow', 'sparkle', 'rotate']; +export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'font', 'blur', 'rainbow', 'sparkle', 'rotate']; |