Merge branch 'develop' into pag-back
This commit is contained in:
		
							
								
								
									
										8
									
								
								.github/workflows/docker-develop.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/docker-develop.yml
									
									
									
									
										vendored
									
									
								
							| @@ -16,21 +16,21 @@ jobs: | |||||||
|         uses: actions/checkout@v4.0.0 |         uses: actions/checkout@v4.0.0 | ||||||
|       - name: Set up Docker Buildx |       - name: Set up Docker Buildx | ||||||
|         id: buildx |         id: buildx | ||||||
|         uses: docker/setup-buildx-action@v2.10.0 |         uses: docker/setup-buildx-action@v3.0.0 | ||||||
|         with: |         with: | ||||||
|           platforms: linux/amd64,linux/arm64 |           platforms: linux/amd64,linux/arm64 | ||||||
|       - name: Docker meta |       - name: Docker meta | ||||||
|         id: meta |         id: meta | ||||||
|         uses: docker/metadata-action@v4 |         uses: docker/metadata-action@v5 | ||||||
|         with: |         with: | ||||||
|           images: misskey/misskey |           images: misskey/misskey | ||||||
|       - name: Log in to Docker Hub |       - name: Log in to Docker Hub | ||||||
|         uses: docker/login-action@v2 |         uses: docker/login-action@v3 | ||||||
|         with: |         with: | ||||||
|           username: ${{ secrets.DOCKER_USERNAME }} |           username: ${{ secrets.DOCKER_USERNAME }} | ||||||
|           password: ${{ secrets.DOCKER_PASSWORD }} |           password: ${{ secrets.DOCKER_PASSWORD }} | ||||||
|       - name: Build and Push to Docker Hub |       - name: Build and Push to Docker Hub | ||||||
|         uses: docker/build-push-action@v4 |         uses: docker/build-push-action@v5 | ||||||
|         with: |         with: | ||||||
|           builder: ${{ steps.buildx.outputs.name }} |           builder: ${{ steps.buildx.outputs.name }} | ||||||
|           context: . |           context: . | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								.github/workflows/docker.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/docker.yml
									
									
									
									
										vendored
									
									
								
							| @@ -15,12 +15,12 @@ jobs: | |||||||
|         uses: actions/checkout@v4.0.0 |         uses: actions/checkout@v4.0.0 | ||||||
|       - name: Set up Docker Buildx |       - name: Set up Docker Buildx | ||||||
|         id: buildx |         id: buildx | ||||||
|         uses: docker/setup-buildx-action@v2.10.0 |         uses: docker/setup-buildx-action@v3.0.0 | ||||||
|         with: |         with: | ||||||
|           platforms: linux/amd64,linux/arm64 |           platforms: linux/amd64,linux/arm64 | ||||||
|       - name: Docker meta |       - name: Docker meta | ||||||
|         id: meta |         id: meta | ||||||
|         uses: docker/metadata-action@v4 |         uses: docker/metadata-action@v5 | ||||||
|         with: |         with: | ||||||
|           images: misskey/misskey |           images: misskey/misskey | ||||||
|           tags: | |           tags: | | ||||||
| @@ -31,12 +31,12 @@ jobs: | |||||||
|             type=semver,pattern={{major}}.{{minor}} |             type=semver,pattern={{major}}.{{minor}} | ||||||
|             type=semver,pattern={{major}} |             type=semver,pattern={{major}} | ||||||
|       - name: Log in to Docker Hub |       - name: Log in to Docker Hub | ||||||
|         uses: docker/login-action@v2 |         uses: docker/login-action@v3 | ||||||
|         with: |         with: | ||||||
|           username: ${{ secrets.DOCKER_USERNAME }} |           username: ${{ secrets.DOCKER_USERNAME }} | ||||||
|           password: ${{ secrets.DOCKER_PASSWORD }} |           password: ${{ secrets.DOCKER_PASSWORD }} | ||||||
|       - name: Build and Push to Docker Hub |       - name: Build and Push to Docker Hub | ||||||
|         uses: docker/build-push-action@v4 |         uses: docker/build-push-action@v5 | ||||||
|         with: |         with: | ||||||
|           builder: ${{ steps.buildx.outputs.name }} |           builder: ${{ steps.buildx.outputs.name }} | ||||||
|           context: . |           context: . | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/workflows/ok-to-test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/ok-to-test.yml
									
									
									
									
										vendored
									
									
								
							| @@ -17,7 +17,7 @@ jobs: | |||||||
|     # See app.yml for an example app manifest |     # See app.yml for an example app manifest | ||||||
|     - name: Generate token |     - name: Generate token | ||||||
|       id: generate_token |       id: generate_token | ||||||
|       uses: tibdex/github-app-token@v1 |       uses: tibdex/github-app-token@v2 | ||||||
|       with: |       with: | ||||||
|         app_id: ${{ secrets.DEPLOYBOT_APP_ID }} |         app_id: ${{ secrets.DEPLOYBOT_APP_ID }} | ||||||
|         private_key: ${{ secrets.DEPLOYBOT_PRIVATE_KEY }} |         private_key: ${{ secrets.DEPLOYBOT_PRIVATE_KEY }} | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ | |||||||
| 	- センシティブチャンネルのノートはユーザープロフィールに表示されません | 	- センシティブチャンネルのノートはユーザープロフィールに表示されません | ||||||
| - 二要素認証のバックアップコードが生成されるようになりました ref. https://github.com/MisskeyIO/misskey/pull/121 | - 二要素認証のバックアップコードが生成されるようになりました ref. https://github.com/MisskeyIO/misskey/pull/121 | ||||||
| - 二要素認証でパスキーをサポートするようになりました | - 二要素認証でパスキーをサポートするようになりました | ||||||
|  | - 通知をテストできるようになりました | ||||||
|  |  | ||||||
| ### Client | ### Client | ||||||
| - プロフィールにその人が作ったPlayの一覧出せるように | - プロフィールにその人が作ったPlayの一覧出せるように | ||||||
| @@ -33,7 +34,6 @@ | |||||||
| - 投稿フォームのプレビューの表示状態を記憶するように | - 投稿フォームのプレビューの表示状態を記憶するように | ||||||
| - AiScriptからMisskeyサーバーAPIを呼び出す際の制限を撤廃 | - AiScriptからMisskeyサーバーAPIを呼び出す際の制限を撤廃 | ||||||
| - Playで直接投稿フォームを埋め込めるように(`Ui:C:postForm`) | - Playで直接投稿フォームを埋め込めるように(`Ui:C:postForm`) | ||||||
| - 通知をテストできるように |  | ||||||
| - Enhance: ユーザーメニューでスイッチでユーザーリストに追加・削除できるように | - Enhance: ユーザーメニューでスイッチでユーザーリストに追加・削除できるように | ||||||
| - Enhance: 自分が押したリアクションのデザインを改善 | - Enhance: 自分が押したリアクションのデザインを改善 | ||||||
| - Enhance: ノート検索にローカルのみ検索可能なオプションの追加 | - Enhance: ノート検索にローカルのみ検索可能なオプションの追加 | ||||||
| @@ -46,6 +46,8 @@ | |||||||
| - リアクションの表示サイズをより大きくできるように | - リアクションの表示サイズをより大きくできるように | ||||||
| - ノート詳細ページ読み込み時のパフォーマンスを改善 | - ノート詳細ページ読み込み時のパフォーマンスを改善 | ||||||
| - タイムラインでリスト/アンテナ選択時のパフォーマンスを改善 | - タイムラインでリスト/アンテナ選択時のパフォーマンスを改善 | ||||||
|  | - 「Moderation note」、「Add moderation note」をローカライズできるように | ||||||
|  | - 新しい実績を追加 | ||||||
| - Fix: サーバー情報画面(`/instance-info/{domain}`)でブロックができないのを修正 | - Fix: サーバー情報画面(`/instance-info/{domain}`)でブロックができないのを修正 | ||||||
| - Fix: 未読のお知らせの「わかった」をクリック・タップしてもその場で「わかった」が消えない問題を修正 | - Fix: 未読のお知らせの「わかった」をクリック・タップしてもその場で「わかった」が消えない問題を修正 | ||||||
| - Fix: iOSで画面を回転させるとテキストサイズが変わる問題を修正 | - Fix: iOSで画面を回転させるとテキストサイズが変わる問題を修正 | ||||||
| @@ -62,6 +64,7 @@ | |||||||
| - 使われていないアンテナの自動停止を設定可能に | - 使われていないアンテナの自動停止を設定可能に | ||||||
| - nodeinfo 2.1対応 | - nodeinfo 2.1対応 | ||||||
| - 自分へのメンション一覧を取得する際のパフォーマンスを向上 | - 自分へのメンション一覧を取得する際のパフォーマンスを向上 | ||||||
|  | - Docker環境でjemallocを使用することでメモリ使用量を削減 | ||||||
| - Fix: ノート検索 `notes/search` にてhostを指定した際に検索結果に反映されるように | - Fix: ノート検索 `notes/search` にてhostを指定した際に検索結果に反映されるように | ||||||
| - Fix: 一部のfeatured noteを照会できない問題を修正 | - Fix: 一部のfeatured noteを照会できない問題を修正 | ||||||
| - Fix: muteがapiからのuser list timeline取得で機能しない問題を修正 | - Fix: muteがapiからのuser list timeline取得で機能しない問題を修正 | ||||||
|   | |||||||
| @@ -62,7 +62,7 @@ ARG GID="991" | |||||||
|  |  | ||||||
| RUN apt-get update \ | RUN apt-get update \ | ||||||
| 	&& apt-get install -y --no-install-recommends \ | 	&& apt-get install -y --no-install-recommends \ | ||||||
| 	ffmpeg tini curl \ | 	ffmpeg tini curl libjemalloc-dev libjemalloc2 \ | ||||||
| 	&& corepack enable \ | 	&& corepack enable \ | ||||||
| 	&& groupadd -g "${GID}" misskey \ | 	&& groupadd -g "${GID}" misskey \ | ||||||
| 	&& useradd -l -u "${UID}" -g "${GID}" -m -d /misskey misskey \ | 	&& useradd -l -u "${UID}" -g "${GID}" -m -d /misskey misskey \ | ||||||
| @@ -81,6 +81,7 @@ COPY --chown=misskey:misskey --from=native-builder /misskey/packages/backend/bui | |||||||
| COPY --chown=misskey:misskey --from=native-builder /misskey/fluent-emojis /misskey/fluent-emojis | COPY --chown=misskey:misskey --from=native-builder /misskey/fluent-emojis /misskey/fluent-emojis | ||||||
| COPY --chown=misskey:misskey . ./ | COPY --chown=misskey:misskey . ./ | ||||||
|  |  | ||||||
|  | ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2 | ||||||
| ENV NODE_ENV=production | ENV NODE_ENV=production | ||||||
| HEALTHCHECK --interval=5s --retries=20 CMD ["/bin/bash", "/misskey/healthcheck.sh"] | HEALTHCHECK --interval=5s --retries=20 CMD ["/bin/bash", "/misskey/healthcheck.sh"] | ||||||
| ENTRYPOINT ["/usr/bin/tini", "--"] | ENTRYPOINT ["/usr/bin/tini", "--"] | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								locales/index.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								locales/index.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -420,6 +420,8 @@ export interface Locale { | |||||||
|     "totpDescription": string; |     "totpDescription": string; | ||||||
|     "moderator": string; |     "moderator": string; | ||||||
|     "moderation": string; |     "moderation": string; | ||||||
|  |     "moderationNote": string; | ||||||
|  |     "addModerationNote": string; | ||||||
|     "nUsersMentioned": string; |     "nUsersMentioned": string; | ||||||
|     "securityKeyAndPasskey": string; |     "securityKeyAndPasskey": string; | ||||||
|     "securityKey": string; |     "securityKey": string; | ||||||
| @@ -1468,6 +1470,10 @@ export interface Locale { | |||||||
|                 "description": string; |                 "description": string; | ||||||
|                 "flavor": string; |                 "flavor": string; | ||||||
|             }; |             }; | ||||||
|  |             "_smashTestNotificationButton": { | ||||||
|  |                 "title": string; | ||||||
|  |                 "description": string; | ||||||
|  |             }; | ||||||
|         }; |         }; | ||||||
|     }; |     }; | ||||||
|     "_role": { |     "_role": { | ||||||
|   | |||||||
| @@ -417,6 +417,8 @@ totp: "認証アプリ" | |||||||
| totpDescription: "認証アプリを使ってワンタイムパスワードを入力" | totpDescription: "認証アプリを使ってワンタイムパスワードを入力" | ||||||
| moderator: "モデレーター" | moderator: "モデレーター" | ||||||
| moderation: "モデレーション" | moderation: "モデレーション" | ||||||
|  | moderationNote: "モデレーションノート" | ||||||
|  | addModerationNote: "モデレーションノートを追加する" | ||||||
| nUsersMentioned: "{n}人が投稿" | nUsersMentioned: "{n}人が投稿" | ||||||
| securityKeyAndPasskey: "セキュリティキー・パスキー" | securityKeyAndPasskey: "セキュリティキー・パスキー" | ||||||
| securityKey: "セキュリティキー" | securityKey: "セキュリティキー" | ||||||
| @@ -1392,6 +1394,9 @@ _achievements: | |||||||
|       title: "Brain Diver" |       title: "Brain Diver" | ||||||
|       description: "Brain Diverへのリンクを投稿した" |       description: "Brain Diverへのリンクを投稿した" | ||||||
|       flavor: "Misskey-Misskey La-Tu-Ma" |       flavor: "Misskey-Misskey La-Tu-Ma" | ||||||
|  |     _smashTestNotificationButton: | ||||||
|  |       title: "テスト過剰" | ||||||
|  |       description: "通知のテストをごく短時間のうちに連続して行った" | ||||||
|  |  | ||||||
| _role: | _role: | ||||||
|   new: "ロールの作成" |   new: "ロールの作成" | ||||||
|   | |||||||
| @@ -85,6 +85,7 @@ export const ACHIEVEMENT_TYPES = [ | |||||||
| 	'setNameToSyuilo', | 	'setNameToSyuilo', | ||||||
| 	'cookieClicked', | 	'cookieClicked', | ||||||
| 	'brainDiver', | 	'brainDiver', | ||||||
|  | 	'smashTestNotificationButton', | ||||||
| ] as const; | ] as const; | ||||||
|  |  | ||||||
| @Injectable() | @Injectable() | ||||||
|   | |||||||
| @@ -14,6 +14,11 @@ export const meta = { | |||||||
|  |  | ||||||
| 	kind: 'write:notifications', | 	kind: 'write:notifications', | ||||||
|  |  | ||||||
|  | 	limit: { | ||||||
|  | 		duration: 1000 * 60, | ||||||
|  | 		max: 10, | ||||||
|  | 	}, | ||||||
|  |  | ||||||
| 	errors: { | 	errors: { | ||||||
| 	}, | 	}, | ||||||
| } as const; | } as const; | ||||||
|   | |||||||
| @@ -13,6 +13,11 @@ export const meta = { | |||||||
| 	requireCredential: true, | 	requireCredential: true, | ||||||
|  |  | ||||||
| 	kind: 'write:notifications', | 	kind: 'write:notifications', | ||||||
|  |  | ||||||
|  | 	limit: { | ||||||
|  | 		duration: 1000 * 60, | ||||||
|  | 		max: 10, | ||||||
|  | 	}, | ||||||
| } as const; | } as const; | ||||||
|  |  | ||||||
| export const paramDef = { | export const paramDef = { | ||||||
|   | |||||||
| @@ -52,7 +52,7 @@ SPDX-License-Identifier: AGPL-3.0-only | |||||||
| 				</div> | 				</div> | ||||||
|  |  | ||||||
| 				<MkTextarea v-model="moderationNote" manualSave> | 				<MkTextarea v-model="moderationNote" manualSave> | ||||||
| 					<template #label>Moderation note</template> | 					<template #label>{{ i18n.ts.moderationNote }}</template> | ||||||
| 				</MkTextarea> | 				</MkTextarea> | ||||||
|  |  | ||||||
| 				<!-- | 				<!-- | ||||||
|   | |||||||
| @@ -104,7 +104,7 @@ SPDX-License-Identifier: AGPL-3.0-only | |||||||
| 				<option value="horizontal"><i class="ti ti-carousel-horizontal"></i> {{ i18n.ts.horizontal }}</option> | 				<option value="horizontal"><i class="ti ti-carousel-horizontal"></i> {{ i18n.ts.horizontal }}</option> | ||||||
| 			</MkRadios> | 			</MkRadios> | ||||||
|  |  | ||||||
| 			<MkButton @click="testNotification('client')">{{ i18n.ts._notification.checkNotificationBehavior }}</MkButton> | 			<MkButton @click="testNotification">{{ i18n.ts._notification.checkNotificationBehavior }}</MkButton> | ||||||
| 		</div> | 		</div> | ||||||
| 	</FormSection> | 	</FormSection> | ||||||
|  |  | ||||||
| @@ -184,6 +184,7 @@ SPDX-License-Identifier: AGPL-3.0-only | |||||||
|  |  | ||||||
| <script lang="ts" setup> | <script lang="ts" setup> | ||||||
| import { computed, ref, watch } from 'vue'; | import { computed, ref, watch } from 'vue'; | ||||||
|  | import * as Misskey from 'misskey-js'; | ||||||
| import MkSwitch from '@/components/MkSwitch.vue'; | import MkSwitch from '@/components/MkSwitch.vue'; | ||||||
| import MkSelect from '@/components/MkSelect.vue'; | import MkSelect from '@/components/MkSelect.vue'; | ||||||
| import MkRadios from '@/components/MkRadios.vue'; | import MkRadios from '@/components/MkRadios.vue'; | ||||||
| @@ -202,6 +203,8 @@ import { definePageMetadata } from '@/scripts/page-metadata'; | |||||||
| import { miLocalStorage } from '@/local-storage'; | import { miLocalStorage } from '@/local-storage'; | ||||||
| import { isWebKit } from '@/scripts/useragent'; | import { isWebKit } from '@/scripts/useragent'; | ||||||
| import { testNotification } from '@/scripts/test-notification'; | import { testNotification } from '@/scripts/test-notification'; | ||||||
|  | import { globalEvents } from '@/events'; | ||||||
|  | import { claimAchievement } from '@/scripts/achievements'; | ||||||
|  |  | ||||||
| const lang = ref(miLocalStorage.getItem('lang')); | const lang = ref(miLocalStorage.getItem('lang')); | ||||||
| const fontSize = ref(miLocalStorage.getItem('fontSize')); | const fontSize = ref(miLocalStorage.getItem('fontSize')); | ||||||
| @@ -315,6 +318,32 @@ function removeEmojiIndex(lang: string) { | |||||||
| 	os.promiseDialog(main()); | 	os.promiseDialog(main()); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | let smashCount = 0; | ||||||
|  | let smashTimer: number | null = null; | ||||||
|  | function testNotification(): void { | ||||||
|  | 	const notification: Misskey.entities.Notification = { | ||||||
|  | 		id: Math.random().toString(), | ||||||
|  | 		createdAt: new Date().toUTCString(), | ||||||
|  | 		isRead: false, | ||||||
|  | 		type: 'test', | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	globalEvents.emit('clientNotification', notification); | ||||||
|  |  | ||||||
|  | 	// セルフ通知破壊 実績関連 | ||||||
|  | 	smashCount++; | ||||||
|  | 	if (smashCount >= 10) { | ||||||
|  | 		claimAchievement('smashTestNotificationButton'); | ||||||
|  | 		smashCount = 0; | ||||||
|  | 	} | ||||||
|  | 	if (smashTimer) { | ||||||
|  | 		clearTimeout(smashTimer); | ||||||
|  | 	} | ||||||
|  | 	smashTimer = window.setTimeout(() => { | ||||||
|  | 		smashCount = 0; | ||||||
|  | 	}, 300); | ||||||
|  | } | ||||||
|  |  | ||||||
| const headerActions = $computed(() => []); | const headerActions = $computed(() => []); | ||||||
|  |  | ||||||
| const headerTabs = $computed(() => []); | const headerTabs = $computed(() => []); | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only | |||||||
| 	</FormSection> | 	</FormSection> | ||||||
| 	<FormSection> | 	<FormSection> | ||||||
| 		<div class="_gaps_m"> | 		<div class="_gaps_m"> | ||||||
| 			<FormLink @click="testNotification('server')">{{ i18n.ts._notification.sendTestNotification }}</FormLink> | 			<FormLink @click="testNotification">{{ i18n.ts._notification.sendTestNotification }}</FormLink> | ||||||
| 		</div> | 		</div> | ||||||
| 	</FormSection> | 	</FormSection> | ||||||
| 	<FormSection> | 	<FormSection> | ||||||
| @@ -46,7 +46,6 @@ import { i18n } from '@/i18n'; | |||||||
| import { definePageMetadata } from '@/scripts/page-metadata'; | import { definePageMetadata } from '@/scripts/page-metadata'; | ||||||
| import MkPushNotificationAllowButton from '@/components/MkPushNotificationAllowButton.vue'; | import MkPushNotificationAllowButton from '@/components/MkPushNotificationAllowButton.vue'; | ||||||
| import { notificationTypes } from '@/const'; | import { notificationTypes } from '@/const'; | ||||||
| import { testNotification } from '@/scripts/test-notification'; |  | ||||||
|  |  | ||||||
| let allowButton = $shallowRef<InstanceType<typeof MkPushNotificationAllowButton>>(); | let allowButton = $shallowRef<InstanceType<typeof MkPushNotificationAllowButton>>(); | ||||||
| let pushRegistrationInServer = $computed(() => allowButton?.pushRegistrationInServer); | let pushRegistrationInServer = $computed(() => allowButton?.pushRegistrationInServer); | ||||||
| @@ -89,6 +88,10 @@ function onChangeSendReadMessage(v: boolean) { | |||||||
| 	}); | 	}); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function testNotification(): void { | ||||||
|  | 	os.api('notifications/test-notification'); | ||||||
|  | } | ||||||
|  |  | ||||||
| const headerActions = $computed(() => []); | const headerActions = $computed(() => []); | ||||||
|  |  | ||||||
| const headerTabs = $computed(() => []); | const headerTabs = $computed(() => []); | ||||||
|   | |||||||
| @@ -57,10 +57,10 @@ SPDX-License-Identifier: AGPL-3.0-only | |||||||
| 					</div> | 					</div> | ||||||
| 					<div v-if="iAmModerator" class="moderationNote"> | 					<div v-if="iAmModerator" class="moderationNote"> | ||||||
| 						<MkTextarea v-if="editModerationNote || (moderationNote != null && moderationNote !== '')" v-model="moderationNote" manualSave> | 						<MkTextarea v-if="editModerationNote || (moderationNote != null && moderationNote !== '')" v-model="moderationNote" manualSave> | ||||||
| 							<template #label>Moderation note</template> | 							<template #label>{{ i18n.ts.moderationNote }}</template> | ||||||
| 						</MkTextarea> | 						</MkTextarea> | ||||||
| 						<div v-else> | 						<div v-else> | ||||||
| 							<MkButton small @click="editModerationNote = true">Add moderation note</MkButton> | 							<MkButton small @click="editModerationNote = true">{{ i18n.ts.addModerationNote }}</MkButton> | ||||||
| 						</div> | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
| 					<div v-if="isEditingMemo || memoDraft" class="memo" :class="{'no-memo': !memoDraft}"> | 					<div v-if="isEditingMemo || memoDraft" class="memo" :class="{'no-memo': !memoDraft}"> | ||||||
|   | |||||||
| @@ -81,6 +81,7 @@ export const ACHIEVEMENT_TYPES = [ | |||||||
| 	'setNameToSyuilo', | 	'setNameToSyuilo', | ||||||
| 	'cookieClicked', | 	'cookieClicked', | ||||||
| 	'brainDiver', | 	'brainDiver', | ||||||
|  | 	'smashTestNotificationButton', | ||||||
| ] as const; | ] as const; | ||||||
|  |  | ||||||
| export const ACHIEVEMENT_BADGES = { | export const ACHIEVEMENT_BADGES = { | ||||||
| @@ -454,6 +455,11 @@ export const ACHIEVEMENT_BADGES = { | |||||||
| 		bg: 'linear-gradient(0deg, rgb(144, 224, 255), rgb(255, 168, 252))', | 		bg: 'linear-gradient(0deg, rgb(144, 224, 255), rgb(255, 168, 252))', | ||||||
| 		frame: 'bronze', | 		frame: 'bronze', | ||||||
| 	}, | 	}, | ||||||
|  | 	'smashTestNotificationButton': { | ||||||
|  | 		img: '/fluent-emoji/1f514.png', | ||||||
|  | 		bg: 'linear-gradient(0deg, rgb(187 183 59), rgb(255 143 77))', | ||||||
|  | 		frame: 'bronze', | ||||||
|  | 	}, | ||||||
| /* @see <https://github.com/misskey-dev/misskey/pull/10365#discussion_r1155511107> | /* @see <https://github.com/misskey-dev/misskey/pull/10365#discussion_r1155511107> | ||||||
| } as const satisfies Record<typeof ACHIEVEMENT_TYPES[number], { | } as const satisfies Record<typeof ACHIEVEMENT_TYPES[number], { | ||||||
| 	img: string; | 	img: string; | ||||||
|   | |||||||
| @@ -1,34 +0,0 @@ | |||||||
| /* |  | ||||||
|  * SPDX-FileCopyrightText: syuilo and other misskey contributors |  | ||||||
|  * SPDX-License-Identifier: AGPL-3.0-only |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| import * as Misskey from 'misskey-js'; |  | ||||||
| import * as os from '@/os'; |  | ||||||
| import { globalEvents } from '@/events'; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * テスト通知を送信 |  | ||||||
|  *  |  | ||||||
|  * - `client` … 通知ポップアップのみを表示 |  | ||||||
|  * - `server` … サーバー側から通知を送信 |  | ||||||
|  *  |  | ||||||
|  * @param type 通知タイプを指定 |  | ||||||
|  */ |  | ||||||
| export function testNotification(type: 'client' | 'server'): void { |  | ||||||
| 	const notification: Misskey.entities.Notification = { |  | ||||||
| 		id: Math.random().toString(), |  | ||||||
| 		createdAt: new Date().toUTCString(), |  | ||||||
| 		isRead: false, |  | ||||||
| 		type: 'test', |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	switch (type) { |  | ||||||
| 		case 'server': |  | ||||||
| 			os.api('notifications/test-notification'); |  | ||||||
| 			break; |  | ||||||
| 		case 'client': |  | ||||||
| 			globalEvents.emit('clientNotification', notification); |  | ||||||
| 			break; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user
	 tamaina
					tamaina