Merge branch 'develop' into feat-14852
This commit is contained in:
commit
fd059bf49d
|
@ -5,7 +5,7 @@
|
||||||
"workspaceFolder": "/workspace",
|
"workspaceFolder": "/workspace",
|
||||||
"features": {
|
"features": {
|
||||||
"ghcr.io/devcontainers/features/node:1": {
|
"ghcr.io/devcontainers/features/node:1": {
|
||||||
"version": "20.16.0"
|
"version": "22.11.0"
|
||||||
},
|
},
|
||||||
"ghcr.io/devcontainers-contrib/features/corepack:1": {}
|
"ghcr.io/devcontainers-contrib/features/corepack:1": {}
|
||||||
},
|
},
|
||||||
|
|
|
@ -17,7 +17,7 @@ jobs:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [20.16.0]
|
node-version: [22.11.0]
|
||||||
api-json-name: [api-base.json, api-head.json]
|
api-json-name: [api-base.json, api-head.json]
|
||||||
include:
|
include:
|
||||||
- api-json-name: api-base.json
|
- api-json-name: api-base.json
|
||||||
|
|
|
@ -17,7 +17,7 @@ jobs:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [20.16.0]
|
node-version: [22.11.0]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.1
|
- uses: actions/checkout@v4.1.1
|
||||||
|
|
|
@ -22,7 +22,7 @@ jobs:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [20.16.0]
|
node-version: [22.11.0]
|
||||||
|
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
|
@ -71,7 +71,7 @@ jobs:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [20.16.0]
|
node-version: [22.11.0]
|
||||||
|
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
|
|
|
@ -20,7 +20,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [20.16.0]
|
node-version: [22.11.0]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -26,7 +26,7 @@ jobs:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [20.16.0]
|
node-version: [22.11.0]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.1
|
- uses: actions/checkout@v4.1.1
|
||||||
|
@ -61,7 +61,7 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [20.16.0]
|
node-version: [22.11.0]
|
||||||
browser: [chrome]
|
browser: [chrome]
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
|
@ -21,7 +21,7 @@ jobs:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [20.16.0]
|
node-version: [22.11.0]
|
||||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
|
@ -16,7 +16,7 @@ jobs:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [20.16.0]
|
node-version: [22.11.0]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.1
|
- uses: actions/checkout@v4.1.1
|
||||||
|
|
|
@ -18,7 +18,7 @@ jobs:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [20.16.0]
|
node-version: [22.11.0]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.1
|
- uses: actions/checkout@v4.1.1
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
20.16.0
|
22.11.0
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
## 2024.11.0
|
## 2024.11.0
|
||||||
|
|
||||||
|
### Note
|
||||||
|
- DockerのNode.jsが22.11.0に更新されました
|
||||||
|
|
||||||
### General
|
### General
|
||||||
- Feat: コンテンツの表示にログインを必須にできるように
|
- Feat: コンテンツの表示にログインを必須にできるように
|
||||||
- Feat: 過去のノートを非公開化/フォロワーのみ表示可能にできるように
|
- Feat: 過去のノートを非公開化/フォロワーのみ表示可能にできるように
|
||||||
|
@ -19,6 +22,7 @@
|
||||||
- Enhance: Self-XSS防止用の警告を追加
|
- Enhance: Self-XSS防止用の警告を追加
|
||||||
- Enhance: カタルーニャ語 (ca-ES) に対応
|
- Enhance: カタルーニャ語 (ca-ES) に対応
|
||||||
- Enhance: 個別お知らせページではMetaタグを出力するように
|
- Enhance: 個別お知らせページではMetaタグを出力するように
|
||||||
|
- Enhance: ノート詳細画面にロールのバッジを表示
|
||||||
- Enhance: 過去に送信したフォローリクエストを確認できるように
|
- Enhance: 過去に送信したフォローリクエストを確認できるように
|
||||||
(Based on https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/663)
|
(Based on https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/663)
|
||||||
- Fix: 通知の範囲指定の設定項目が必要ない通知設定でも範囲指定の設定がでている問題を修正
|
- Fix: 通知の範囲指定の設定項目が必要ない通知設定でも範囲指定の設定がでている問題を修正
|
||||||
|
@ -32,6 +36,7 @@
|
||||||
- Fix: メールアドレス登録有効化時の「完了」ダイアログボックスの表示条件を修正
|
- Fix: メールアドレス登録有効化時の「完了」ダイアログボックスの表示条件を修正
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
|
- Enhance: DockerのNode.jsを22.11.0に更新
|
||||||
- Enhance: 起動前の疎通チェックで、DBとメイン以外のRedisの疎通確認も行うように
|
- Enhance: 起動前の疎通チェックで、DBとメイン以外のRedisの疎通確認も行うように
|
||||||
(Based on https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/588)
|
(Based on https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/588)
|
||||||
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/715)
|
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/715)
|
||||||
|
@ -47,6 +52,7 @@
|
||||||
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/712)
|
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/712)
|
||||||
- Fix: FTT無効時にユーザーリストタイムラインが使用できない問題を修正
|
- Fix: FTT無効時にユーザーリストタイムラインが使用できない問題を修正
|
||||||
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/709)
|
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/709)
|
||||||
|
- Fix: User Webhookテスト機能のMock Payloadを修正
|
||||||
|
|
||||||
### Misskey.js
|
### Misskey.js
|
||||||
- Fix: Stream初期化時、別途WebSocketを指定する場合の型定義を修正
|
- Fix: Stream初期化時、別途WebSocketを指定する場合の型定義を修正
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# syntax = docker/dockerfile:1.4
|
# syntax = docker/dockerfile:1.4
|
||||||
|
|
||||||
ARG NODE_VERSION=20.16.0-bullseye
|
ARG NODE_VERSION=22.11.0-bullseye
|
||||||
|
|
||||||
# build assets & compile TypeScript
|
# build assets & compile TypeScript
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { randomUUID } from 'node:crypto';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import type { IActivity } from '@/core/activitypub/type.js';
|
import type { IActivity } from '@/core/activitypub/type.js';
|
||||||
import type { MiDriveFile } from '@/models/DriveFile.js';
|
import type { MiDriveFile } from '@/models/DriveFile.js';
|
||||||
import type { MiWebhook, webhookEventTypes } from '@/models/Webhook.js';
|
import type { MiWebhook, WebhookEventTypes, webhookEventTypes } from '@/models/Webhook.js';
|
||||||
import type { MiSystemWebhook, SystemWebhookEventType } from '@/models/SystemWebhook.js';
|
import type { MiSystemWebhook, SystemWebhookEventType } from '@/models/SystemWebhook.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
|
@ -35,6 +35,7 @@ import type {
|
||||||
} from './QueueModule.js';
|
} from './QueueModule.js';
|
||||||
import type httpSignature from '@peertube/http-signature';
|
import type httpSignature from '@peertube/http-signature';
|
||||||
import type * as Bull from 'bullmq';
|
import type * as Bull from 'bullmq';
|
||||||
|
import { type UserWebhookPayload } from './UserWebhookService.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QueueService {
|
export class QueueService {
|
||||||
|
@ -468,10 +469,10 @@ export class QueueService {
|
||||||
* @see UserWebhookDeliverProcessorService
|
* @see UserWebhookDeliverProcessorService
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public userWebhookDeliver(
|
public userWebhookDeliver<T extends WebhookEventTypes>(
|
||||||
webhook: MiWebhook,
|
webhook: MiWebhook,
|
||||||
type: typeof webhookEventTypes[number],
|
type: T,
|
||||||
content: unknown,
|
content: UserWebhookPayload<T>,
|
||||||
opts?: { attempts?: number },
|
opts?: { attempts?: number },
|
||||||
) {
|
) {
|
||||||
const data: UserWebhookDeliverJobData = {
|
const data: UserWebhookDeliverJobData = {
|
||||||
|
|
|
@ -6,11 +6,23 @@
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import * as Redis from 'ioredis';
|
import * as Redis from 'ioredis';
|
||||||
import { type WebhooksRepository } from '@/models/_.js';
|
import { type WebhooksRepository } from '@/models/_.js';
|
||||||
import { MiWebhook } from '@/models/Webhook.js';
|
import { MiWebhook, WebhookEventTypes } from '@/models/Webhook.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { GlobalEvents } from '@/core/GlobalEventService.js';
|
import { GlobalEvents } from '@/core/GlobalEventService.js';
|
||||||
import type { OnApplicationShutdown } from '@nestjs/common';
|
import type { OnApplicationShutdown } from '@nestjs/common';
|
||||||
|
import type { Packed } from '@/misc/json-schema.js';
|
||||||
|
|
||||||
|
export type UserWebhookPayload<T extends WebhookEventTypes> =
|
||||||
|
T extends 'note' | 'reply' | 'renote' |'mention' ? {
|
||||||
|
note: Packed<'Note'>,
|
||||||
|
} :
|
||||||
|
T extends 'follow' | 'unfollow' ? {
|
||||||
|
user: Packed<'UserDetailedNotMe'>,
|
||||||
|
} :
|
||||||
|
T extends 'followed' ? {
|
||||||
|
user: Packed<'UserLite'>,
|
||||||
|
} : never;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserWebhookService implements OnApplicationShutdown {
|
export class UserWebhookService implements OnApplicationShutdown {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { MiSystemWebhook, type SystemWebhookEventType } from '@/models/SystemWeb
|
||||||
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
||||||
import { Packed } from '@/misc/json-schema.js';
|
import { Packed } from '@/misc/json-schema.js';
|
||||||
import { type WebhookEventTypes } from '@/models/Webhook.js';
|
import { type WebhookEventTypes } from '@/models/Webhook.js';
|
||||||
import { UserWebhookService } from '@/core/UserWebhookService.js';
|
import { type UserWebhookPayload, UserWebhookService } from '@/core/UserWebhookService.js';
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
import { ModeratorInactivityRemainingTime } from '@/queue/processors/CheckModeratorsActivityProcessorService.js';
|
import { ModeratorInactivityRemainingTime } from '@/queue/processors/CheckModeratorsActivityProcessorService.js';
|
||||||
|
|
||||||
|
@ -306,10 +306,10 @@ export class WebhookTestService {
|
||||||
* - 送信対象イベント(on)に関する設定
|
* - 送信対象イベント(on)に関する設定
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async testUserWebhook(
|
public async testUserWebhook<T extends WebhookEventTypes>(
|
||||||
params: {
|
params: {
|
||||||
webhookId: MiWebhook['id'],
|
webhookId: MiWebhook['id'],
|
||||||
type: WebhookEventTypes,
|
type: T,
|
||||||
override?: Partial<Omit<MiWebhook, 'id'>>,
|
override?: Partial<Omit<MiWebhook, 'id'>>,
|
||||||
},
|
},
|
||||||
sender: MiUser | null,
|
sender: MiUser | null,
|
||||||
|
@ -321,7 +321,7 @@ export class WebhookTestService {
|
||||||
}
|
}
|
||||||
|
|
||||||
const webhook = webhooks[0];
|
const webhook = webhooks[0];
|
||||||
const send = (contents: unknown) => {
|
const send = <U extends WebhookEventTypes>(type: U, contents: UserWebhookPayload<U>) => {
|
||||||
const merged = {
|
const merged = {
|
||||||
...webhook,
|
...webhook,
|
||||||
...params.override,
|
...params.override,
|
||||||
|
@ -329,7 +329,7 @@ export class WebhookTestService {
|
||||||
|
|
||||||
// テスト目的なのでUserWebhookServiceの機能を経由せず直接キューに追加する(チェック処理などをスキップする意図).
|
// テスト目的なのでUserWebhookServiceの機能を経由せず直接キューに追加する(チェック処理などをスキップする意図).
|
||||||
// また、Jobの試行回数も1回だけ.
|
// また、Jobの試行回数も1回だけ.
|
||||||
this.queueService.userWebhookDeliver(merged, params.type, contents, { attempts: 1 });
|
this.queueService.userWebhookDeliver(merged, type, contents, { attempts: 1 });
|
||||||
};
|
};
|
||||||
|
|
||||||
const dummyNote1 = generateDummyNote({
|
const dummyNote1 = generateDummyNote({
|
||||||
|
@ -361,33 +361,40 @@ export class WebhookTestService {
|
||||||
|
|
||||||
switch (params.type) {
|
switch (params.type) {
|
||||||
case 'note': {
|
case 'note': {
|
||||||
send(toPackedNote(dummyNote1));
|
send('note', { note: toPackedNote(dummyNote1) });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'reply': {
|
case 'reply': {
|
||||||
send(toPackedNote(dummyReply1));
|
send('reply', { note: toPackedNote(dummyReply1) });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'renote': {
|
case 'renote': {
|
||||||
send(toPackedNote(dummyRenote1));
|
send('renote', { note: toPackedNote(dummyRenote1) });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'mention': {
|
case 'mention': {
|
||||||
send(toPackedNote(dummyMention1));
|
send('mention', { note: toPackedNote(dummyMention1) });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'follow': {
|
case 'follow': {
|
||||||
send(toPackedUserDetailedNotMe(dummyUser1));
|
send('follow', { user: toPackedUserDetailedNotMe(dummyUser1) });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'followed': {
|
case 'followed': {
|
||||||
send(toPackedUserLite(dummyUser2));
|
send('followed', { user: toPackedUserLite(dummyUser2) });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'unfollow': {
|
case 'unfollow': {
|
||||||
send(toPackedUserDetailedNotMe(dummyUser3));
|
send('unfollow', { user: toPackedUserDetailedNotMe(dummyUser3) });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// まだ実装されていない (#9485)
|
||||||
|
case 'reaction': return;
|
||||||
|
default: {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const _exhaustiveAssertion: never = params.type;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
import { beforeAll, describe, jest } from '@jest/globals';
|
import { beforeAll, describe, jest } from '@jest/globals';
|
||||||
import { WebhookTestService } from '@/core/WebhookTestService.js';
|
import { WebhookTestService } from '@/core/WebhookTestService.js';
|
||||||
import { UserWebhookService } from '@/core/UserWebhookService.js';
|
import { UserWebhookPayload, UserWebhookService } from '@/core/UserWebhookService.js';
|
||||||
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
||||||
import { GlobalModule } from '@/GlobalModule.js';
|
import { GlobalModule } from '@/GlobalModule.js';
|
||||||
import { MiSystemWebhook, MiUser, MiWebhook, UserProfilesRepository, UsersRepository } from '@/models/_.js';
|
import { MiSystemWebhook, MiUser, MiWebhook, UserProfilesRepository, UsersRepository } from '@/models/_.js';
|
||||||
|
@ -122,7 +122,7 @@ describe('WebhookTestService', () => {
|
||||||
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
||||||
expect((calls[0] as any).id).toBe('dummy-webhook');
|
expect((calls[0] as any).id).toBe('dummy-webhook');
|
||||||
expect(calls[1]).toBe('note');
|
expect(calls[1]).toBe('note');
|
||||||
expect((calls[2] as any).id).toBe('dummy-note-1');
|
expect((calls[2] as UserWebhookPayload<'note'>).note.id).toBe('dummy-note-1');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('reply', async () => {
|
test('reply', async () => {
|
||||||
|
@ -131,7 +131,7 @@ describe('WebhookTestService', () => {
|
||||||
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
||||||
expect((calls[0] as any).id).toBe('dummy-webhook');
|
expect((calls[0] as any).id).toBe('dummy-webhook');
|
||||||
expect(calls[1]).toBe('reply');
|
expect(calls[1]).toBe('reply');
|
||||||
expect((calls[2] as any).id).toBe('dummy-reply-1');
|
expect((calls[2] as UserWebhookPayload<'reply'>).note.id).toBe('dummy-reply-1');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('renote', async () => {
|
test('renote', async () => {
|
||||||
|
@ -140,7 +140,7 @@ describe('WebhookTestService', () => {
|
||||||
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
||||||
expect((calls[0] as any).id).toBe('dummy-webhook');
|
expect((calls[0] as any).id).toBe('dummy-webhook');
|
||||||
expect(calls[1]).toBe('renote');
|
expect(calls[1]).toBe('renote');
|
||||||
expect((calls[2] as any).id).toBe('dummy-renote-1');
|
expect((calls[2] as UserWebhookPayload<'renote'>).note.id).toBe('dummy-renote-1');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('mention', async () => {
|
test('mention', async () => {
|
||||||
|
@ -149,7 +149,7 @@ describe('WebhookTestService', () => {
|
||||||
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
||||||
expect((calls[0] as any).id).toBe('dummy-webhook');
|
expect((calls[0] as any).id).toBe('dummy-webhook');
|
||||||
expect(calls[1]).toBe('mention');
|
expect(calls[1]).toBe('mention');
|
||||||
expect((calls[2] as any).id).toBe('dummy-mention-1');
|
expect((calls[2] as UserWebhookPayload<'mention'>).note.id).toBe('dummy-mention-1');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('follow', async () => {
|
test('follow', async () => {
|
||||||
|
@ -158,7 +158,7 @@ describe('WebhookTestService', () => {
|
||||||
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
||||||
expect((calls[0] as any).id).toBe('dummy-webhook');
|
expect((calls[0] as any).id).toBe('dummy-webhook');
|
||||||
expect(calls[1]).toBe('follow');
|
expect(calls[1]).toBe('follow');
|
||||||
expect((calls[2] as any).id).toBe('dummy-user-1');
|
expect((calls[2] as UserWebhookPayload<'follow'>).user.id).toBe('dummy-user-1');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('followed', async () => {
|
test('followed', async () => {
|
||||||
|
@ -167,7 +167,7 @@ describe('WebhookTestService', () => {
|
||||||
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
||||||
expect((calls[0] as any).id).toBe('dummy-webhook');
|
expect((calls[0] as any).id).toBe('dummy-webhook');
|
||||||
expect(calls[1]).toBe('followed');
|
expect(calls[1]).toBe('followed');
|
||||||
expect((calls[2] as any).id).toBe('dummy-user-2');
|
expect((calls[2] as UserWebhookPayload<'followed'>).user.id).toBe('dummy-user-2');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('unfollow', async () => {
|
test('unfollow', async () => {
|
||||||
|
@ -176,7 +176,7 @@ describe('WebhookTestService', () => {
|
||||||
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
const calls = queueService.userWebhookDeliver.mock.calls[0];
|
||||||
expect((calls[0] as any).id).toBe('dummy-webhook');
|
expect((calls[0] as any).id).toBe('dummy-webhook');
|
||||||
expect(calls[1]).toBe('unfollow');
|
expect(calls[1]).toBe('unfollow');
|
||||||
expect((calls[2] as any).id).toBe('dummy-user-3');
|
expect((calls[2] as UserWebhookPayload<'unfollow'>).user.id).toBe('dummy-user-3');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('NoSuchWebhookError', () => {
|
describe('NoSuchWebhookError', () => {
|
||||||
|
|
|
@ -62,7 +62,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<span v-if="appearNote.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-rocket-off"></i></span>
|
<span v-if="appearNote.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-rocket-off"></i></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.noteHeaderUsername"><MkAcct :user="appearNote.user"/></div>
|
<div :class="$style.noteHeaderUsernameAndBadgeRoles">
|
||||||
|
<div :class="$style.noteHeaderUsername">
|
||||||
|
<MkAcct :user="appearNote.user"/>
|
||||||
|
</div>
|
||||||
|
<div v-if="appearNote.user.badgeRoles" :class="$style.noteHeaderBadgeRoles">
|
||||||
|
<img v-for="(role, i) in appearNote.user.badgeRoles" :key="i" v-tooltip="role.name" :class="$style.noteHeaderBadgeRole" :src="role.iconUrl!"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<MkInstanceTicker v-if="showTicker" :instance="appearNote.user.instance"/>
|
<MkInstanceTicker v-if="showTicker" :instance="appearNote.user.instance"/>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
@ -679,12 +686,30 @@ function loadConversation() {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.noteHeaderUsernameAndBadgeRoles {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
.noteHeaderUsername {
|
.noteHeaderUsername {
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
|
margin-right: 0.5em;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
word-wrap: anywhere;
|
word-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.noteHeaderBadgeRoles {
|
||||||
|
margin: 0 .5em 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noteHeaderBadgeRole {
|
||||||
|
height: 1.3em;
|
||||||
|
vertical-align: -20%;
|
||||||
|
|
||||||
|
& + .noteHeaderBadgeRole {
|
||||||
|
margin-left: 0.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.noteContent {
|
.noteContent {
|
||||||
container-type: inline-size;
|
container-type: inline-size;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
|
|
|
@ -272,6 +272,9 @@ const patronsWithIcon = [{
|
||||||
}, {
|
}, {
|
||||||
name: 'Yatoigawa',
|
name: 'Yatoigawa',
|
||||||
icon: 'https://assets.misskey-hub.net/patrons/505e3568885a4a488431a8f22b4553d0.jpg',
|
icon: 'https://assets.misskey-hub.net/patrons/505e3568885a4a488431a8f22b4553d0.jpg',
|
||||||
|
}, {
|
||||||
|
name: '秋瀬カヲル',
|
||||||
|
icon: 'https://assets.misskey-hub.net/patrons/0f22aeb866484f4fa51db6721e3f9847.jpg',
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const patrons = [
|
const patrons = [
|
||||||
|
@ -380,6 +383,7 @@ const patrons = [
|
||||||
'ケモナーのケシン',
|
'ケモナーのケシン',
|
||||||
'こまつぶり',
|
'こまつぶり',
|
||||||
'まゆつな空高',
|
'まゆつな空高',
|
||||||
|
'asata',
|
||||||
];
|
];
|
||||||
|
|
||||||
const thereIsTreasure = ref($i && !claimedAchievements.includes('foundTreasure'));
|
const thereIsTreasure = ref($i && !claimedAchievements.includes('foundTreasure'));
|
||||||
|
|
|
@ -44,7 +44,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkButton transparent :class="$style.testButton" :disabled="!(active && event_renote)" @click="test('renote')"><i class="ti ti-send"></i></MkButton>
|
<MkButton transparent :class="$style.testButton" :disabled="!(active && event_renote)" @click="test('renote')"><i class="ti ti-send"></i></MkButton>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.switchBox">
|
<div :class="$style.switchBox">
|
||||||
<MkSwitch v-model="event_reaction">{{ i18n.ts._webhookSettings._events.reaction }}</MkSwitch>
|
<MkSwitch v-model="event_reaction" :disabled="true">{{ i18n.ts._webhookSettings._events.reaction }}</MkSwitch>
|
||||||
<MkButton transparent :class="$style.testButton" :disabled="!(active && event_reaction)" @click="test('reaction')"><i class="ti ti-send"></i></MkButton>
|
<MkButton transparent :class="$style.testButton" :disabled="!(active && event_reaction)" @click="test('reaction')"><i class="ti ti-send"></i></MkButton>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.switchBox">
|
<div :class="$style.switchBox">
|
||||||
|
|
|
@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkSwitch v-model="event_note">{{ i18n.ts._webhookSettings._events.note }}</MkSwitch>
|
<MkSwitch v-model="event_note">{{ i18n.ts._webhookSettings._events.note }}</MkSwitch>
|
||||||
<MkSwitch v-model="event_reply">{{ i18n.ts._webhookSettings._events.reply }}</MkSwitch>
|
<MkSwitch v-model="event_reply">{{ i18n.ts._webhookSettings._events.reply }}</MkSwitch>
|
||||||
<MkSwitch v-model="event_renote">{{ i18n.ts._webhookSettings._events.renote }}</MkSwitch>
|
<MkSwitch v-model="event_renote">{{ i18n.ts._webhookSettings._events.renote }}</MkSwitch>
|
||||||
<MkSwitch v-model="event_reaction">{{ i18n.ts._webhookSettings._events.reaction }}</MkSwitch>
|
<MkSwitch v-model="event_reaction" :disabled="true">{{ i18n.ts._webhookSettings._events.reaction }}</MkSwitch>
|
||||||
<MkSwitch v-model="event_mention">{{ i18n.ts._webhookSettings._events.mention }}</MkSwitch>
|
<MkSwitch v-model="event_mention">{{ i18n.ts._webhookSettings._events.mention }}</MkSwitch>
|
||||||
</div>
|
</div>
|
||||||
</FormSection>
|
</FormSection>
|
||||||
|
|
Loading…
Reference in New Issue