Merge branch 'develop' into feat-14931
This commit is contained in:
commit
662bfd64bb
|
@ -8,6 +8,7 @@
|
||||||
### General
|
### General
|
||||||
- Feat: コンテンツの表示にログインを必須にできるように
|
- Feat: コンテンツの表示にログインを必須にできるように
|
||||||
- Feat: 過去のノートを非公開化/フォロワーのみ表示可能にできるように
|
- Feat: 過去のノートを非公開化/フォロワーのみ表示可能にできるように
|
||||||
|
- Fix: お知らせ作成時に画像URL入力欄を空欄に変更できないのを修正 ( #14976 )
|
||||||
- Enhance: 依存関係の更新
|
- Enhance: 依存関係の更新
|
||||||
- Enhance: l10nの更新
|
- Enhance: l10nの更新
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@
|
||||||
- Enhance: 過去に送信したフォローリクエストを確認できるように
|
- Enhance: 過去に送信したフォローリクエストを確認できるように
|
||||||
(Based on https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/663)
|
(Based on https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/663)
|
||||||
- Enhance: サイドバーを簡単に展開・折りたたみできるように ( #14981 )
|
- Enhance: サイドバーを簡単に展開・折りたたみできるように ( #14981 )
|
||||||
|
- Enhance: リノートメニューに「リノートの詳細」を追加
|
||||||
- Enhance: Blueskyの投稿埋め込みプレビューに対応
|
- Enhance: Blueskyの投稿埋め込みプレビューに対応
|
||||||
- Fix: 通知の範囲指定の設定項目が必要ない通知設定でも範囲指定の設定がでている問題を修正
|
- Fix: 通知の範囲指定の設定項目が必要ない通知設定でも範囲指定の設定がでている問題を修正
|
||||||
- Fix: Turnstileが失敗・期限切れした際にも成功扱いとなってしまう問題を修正
|
- Fix: Turnstileが失敗・期限切れした際にも成功扱いとなってしまう問題を修正
|
||||||
|
@ -40,6 +42,8 @@
|
||||||
- Fix: メールアドレス登録有効化時の「完了」ダイアログボックスの表示条件を修正
|
- Fix: メールアドレス登録有効化時の「完了」ダイアログボックスの表示条件を修正
|
||||||
- Fix: 画面幅が狭い環境でデザインが崩れる問題を修正
|
- Fix: 画面幅が狭い環境でデザインが崩れる問題を修正
|
||||||
(Cherry-picked from https://github.com/MisskeyIO/misskey/pull/815)
|
(Cherry-picked from https://github.com/MisskeyIO/misskey/pull/815)
|
||||||
|
- Fix: TypeScriptの型チェック対象ファイルを限定してビルドを高速化するように
|
||||||
|
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/725)
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
- Enhance: DockerのNode.jsを22.11.0に更新
|
- Enhance: DockerのNode.jsを22.11.0に更新
|
||||||
|
|
|
@ -2362,6 +2362,10 @@ export interface Locale extends ILocale {
|
||||||
* 詳細
|
* 詳細
|
||||||
*/
|
*/
|
||||||
"details": string;
|
"details": string;
|
||||||
|
/**
|
||||||
|
* リノートの詳細
|
||||||
|
*/
|
||||||
|
"renoteDetails": string;
|
||||||
/**
|
/**
|
||||||
* 絵文字を選択
|
* 絵文字を選択
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -586,6 +586,7 @@ masterVolume: "マスター音量"
|
||||||
notUseSound: "サウンドを出力しない"
|
notUseSound: "サウンドを出力しない"
|
||||||
useSoundOnlyWhenActive: "Misskeyがアクティブな時のみサウンドを出力する"
|
useSoundOnlyWhenActive: "Misskeyがアクティブな時のみサウンドを出力する"
|
||||||
details: "詳細"
|
details: "詳細"
|
||||||
|
renoteDetails: "リノートの詳細"
|
||||||
chooseEmoji: "絵文字を選択"
|
chooseEmoji: "絵文字を選択"
|
||||||
unableToProcess: "操作を完了できません"
|
unableToProcess: "操作を完了できません"
|
||||||
recentUsed: "最近使用"
|
recentUsed: "最近使用"
|
||||||
|
|
|
@ -154,9 +154,9 @@ export class AbuseReportNotificationService implements OnApplicationShutdown {
|
||||||
const convertedReports = abuseReports.map(it => {
|
const convertedReports = abuseReports.map(it => {
|
||||||
return {
|
return {
|
||||||
...it,
|
...it,
|
||||||
reporter: usersMap.get(it.reporterId),
|
reporter: usersMap.get(it.reporterId) ?? null,
|
||||||
targetUser: usersMap.get(it.targetUserId),
|
targetUser: usersMap.get(it.targetUserId) ?? null,
|
||||||
assignee: it.assigneeId ? usersMap.get(it.assigneeId) : null,
|
assignee: it.assigneeId ? (usersMap.get(it.assigneeId) ?? null) : null,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ export class AnnouncementService {
|
||||||
updatedAt: null,
|
updatedAt: null,
|
||||||
title: values.title,
|
title: values.title,
|
||||||
text: values.text,
|
text: values.text,
|
||||||
imageUrl: values.imageUrl,
|
imageUrl: values.imageUrl || null,
|
||||||
icon: values.icon,
|
icon: values.icon,
|
||||||
display: values.display,
|
display: values.display,
|
||||||
forExistingUsers: values.forExistingUsers,
|
forExistingUsers: values.forExistingUsers,
|
||||||
|
|
|
@ -7,13 +7,15 @@ 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, webhookEventTypes } from '@/models/Webhook.js';
|
import type { MiWebhook, 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';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import type { Antenna } from '@/server/api/endpoints/i/import-antennas.js';
|
import type { Antenna } from '@/server/api/endpoints/i/import-antennas.js';
|
||||||
import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js';
|
import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js';
|
||||||
|
import { type SystemWebhookPayload } from '@/core/SystemWebhookService.js';
|
||||||
|
import { type UserWebhookPayload } from './UserWebhookService.js';
|
||||||
import type {
|
import type {
|
||||||
DbJobData,
|
DbJobData,
|
||||||
DeliverJobData,
|
DeliverJobData,
|
||||||
|
@ -30,12 +32,11 @@ import type {
|
||||||
ObjectStorageQueue,
|
ObjectStorageQueue,
|
||||||
RelationshipQueue,
|
RelationshipQueue,
|
||||||
SystemQueue,
|
SystemQueue,
|
||||||
UserWebhookDeliverQueue,
|
|
||||||
SystemWebhookDeliverQueue,
|
SystemWebhookDeliverQueue,
|
||||||
|
UserWebhookDeliverQueue,
|
||||||
} 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 {
|
||||||
|
@ -501,10 +502,10 @@ export class QueueService {
|
||||||
* @see SystemWebhookDeliverProcessorService
|
* @see SystemWebhookDeliverProcessorService
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public systemWebhookDeliver(
|
public systemWebhookDeliver<T extends SystemWebhookEventType>(
|
||||||
webhook: MiSystemWebhook,
|
webhook: MiSystemWebhook,
|
||||||
type: SystemWebhookEventType,
|
type: T,
|
||||||
content: unknown,
|
content: SystemWebhookPayload<T>,
|
||||||
opts?: { attempts?: number },
|
opts?: { attempts?: number },
|
||||||
) {
|
) {
|
||||||
const data: SystemWebhookDeliverJobData = {
|
const data: SystemWebhookDeliverJobData = {
|
||||||
|
|
|
@ -15,8 +15,39 @@ import { QueueService } from '@/core/QueueService.js';
|
||||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||||
import { LoggerService } from '@/core/LoggerService.js';
|
import { LoggerService } from '@/core/LoggerService.js';
|
||||||
import Logger from '@/logger.js';
|
import Logger from '@/logger.js';
|
||||||
|
import { Packed } from '@/misc/json-schema.js';
|
||||||
|
import { AbuseReportResolveType } from '@/models/AbuseUserReport.js';
|
||||||
|
import { ModeratorInactivityRemainingTime } from '@/queue/processors/CheckModeratorsActivityProcessorService.js';
|
||||||
import type { OnApplicationShutdown } from '@nestjs/common';
|
import type { OnApplicationShutdown } from '@nestjs/common';
|
||||||
|
|
||||||
|
export type AbuseReportPayload = {
|
||||||
|
id: string;
|
||||||
|
targetUserId: string;
|
||||||
|
targetUser: Packed<'UserLite'> | null;
|
||||||
|
targetUserHost: string | null;
|
||||||
|
reporterId: string;
|
||||||
|
reporter: Packed<'UserLite'> | null;
|
||||||
|
reporterHost: string | null;
|
||||||
|
assigneeId: string | null;
|
||||||
|
assignee: Packed<'UserLite'> | null;
|
||||||
|
resolved: boolean;
|
||||||
|
forwarded: boolean;
|
||||||
|
comment: string;
|
||||||
|
moderationNote: string;
|
||||||
|
resolvedAs: AbuseReportResolveType | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type InactiveModeratorsWarningPayload = {
|
||||||
|
remainingTime: ModeratorInactivityRemainingTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SystemWebhookPayload<T extends SystemWebhookEventType> =
|
||||||
|
T extends 'abuseReport' | 'abuseReportResolved' ? AbuseReportPayload :
|
||||||
|
T extends 'userCreated' ? Packed<'UserLite'> :
|
||||||
|
T extends 'inactiveModeratorsWarning' ? InactiveModeratorsWarningPayload :
|
||||||
|
T extends 'inactiveModeratorsInvitationOnlyChanged' ? Record<string, never> :
|
||||||
|
never;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SystemWebhookService implements OnApplicationShutdown {
|
export class SystemWebhookService implements OnApplicationShutdown {
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
|
@ -168,7 +199,7 @@ export class SystemWebhookService implements OnApplicationShutdown {
|
||||||
public async enqueueSystemWebhook<T extends SystemWebhookEventType>(
|
public async enqueueSystemWebhook<T extends SystemWebhookEventType>(
|
||||||
webhook: MiSystemWebhook | MiSystemWebhook['id'],
|
webhook: MiSystemWebhook | MiSystemWebhook['id'],
|
||||||
type: T,
|
type: T,
|
||||||
content: unknown,
|
content: SystemWebhookPayload<T>,
|
||||||
) {
|
) {
|
||||||
const webhookEntity = typeof webhook === 'string'
|
const webhookEntity = typeof webhook === 'string'
|
||||||
? (await this.fetchActiveSystemWebhooks()).find(a => a.id === webhook)
|
? (await this.fetchActiveSystemWebhooks()).find(a => a.id === webhook)
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Injectable } from '@nestjs/common';
|
||||||
import { MiAbuseUserReport, MiNote, MiUser, MiWebhook } from '@/models/_.js';
|
import { MiAbuseUserReport, MiNote, MiUser, MiWebhook } from '@/models/_.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { MiSystemWebhook, type SystemWebhookEventType } from '@/models/SystemWebhook.js';
|
import { MiSystemWebhook, type SystemWebhookEventType } from '@/models/SystemWebhook.js';
|
||||||
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
import { AbuseReportPayload, SystemWebhookPayload, 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 { type UserWebhookPayload, UserWebhookService } from '@/core/UserWebhookService.js';
|
import { type UserWebhookPayload, UserWebhookService } from '@/core/UserWebhookService.js';
|
||||||
|
@ -16,13 +16,7 @@ import { ModeratorInactivityRemainingTime } from '@/queue/processors/CheckModera
|
||||||
|
|
||||||
const oneDayMillis = 24 * 60 * 60 * 1000;
|
const oneDayMillis = 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
type AbuseUserReportDto = Omit<MiAbuseUserReport, 'targetUser' | 'reporter' | 'assignee'> & {
|
function generateAbuseReport(override?: Partial<MiAbuseUserReport>): AbuseReportPayload {
|
||||||
targetUser: Packed<'UserLite'> | null,
|
|
||||||
reporter: Packed<'UserLite'> | null,
|
|
||||||
assignee: Packed<'UserLite'> | null,
|
|
||||||
};
|
|
||||||
|
|
||||||
function generateAbuseReport(override?: Partial<MiAbuseUserReport>): AbuseUserReportDto {
|
|
||||||
const result: MiAbuseUserReport = {
|
const result: MiAbuseUserReport = {
|
||||||
id: 'dummy-abuse-report1',
|
id: 'dummy-abuse-report1',
|
||||||
targetUserId: 'dummy-target-user',
|
targetUserId: 'dummy-target-user',
|
||||||
|
@ -389,7 +383,8 @@ export class WebhookTestService {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// まだ実装されていない (#9485)
|
// まだ実装されていない (#9485)
|
||||||
case 'reaction': return;
|
case 'reaction':
|
||||||
|
return;
|
||||||
default: {
|
default: {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const _exhaustiveAssertion: never = params.type;
|
const _exhaustiveAssertion: never = params.type;
|
||||||
|
@ -407,10 +402,10 @@ export class WebhookTestService {
|
||||||
* - 送信対象イベント(on)に関する設定
|
* - 送信対象イベント(on)に関する設定
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async testSystemWebhook(
|
public async testSystemWebhook<T extends SystemWebhookEventType>(
|
||||||
params: {
|
params: {
|
||||||
webhookId: MiSystemWebhook['id'],
|
webhookId: MiSystemWebhook['id'],
|
||||||
type: SystemWebhookEventType,
|
type: T,
|
||||||
override?: Partial<Omit<MiSystemWebhook, 'id'>>,
|
override?: Partial<Omit<MiSystemWebhook, 'id'>>,
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
|
@ -420,7 +415,7 @@ export class WebhookTestService {
|
||||||
}
|
}
|
||||||
|
|
||||||
const webhook = webhooks[0];
|
const webhook = webhooks[0];
|
||||||
const send = (contents: unknown) => {
|
const send = <U extends SystemWebhookEventType>(type: U, contents: SystemWebhookPayload<U>) => {
|
||||||
const merged = {
|
const merged = {
|
||||||
...webhook,
|
...webhook,
|
||||||
...params.override,
|
...params.override,
|
||||||
|
@ -428,12 +423,12 @@ export class WebhookTestService {
|
||||||
|
|
||||||
// テスト目的なのでSystemWebhookServiceの機能を経由せず直接キューに追加する(チェック処理などをスキップする意図).
|
// テスト目的なのでSystemWebhookServiceの機能を経由せず直接キューに追加する(チェック処理などをスキップする意図).
|
||||||
// また、Jobの試行回数も1回だけ.
|
// また、Jobの試行回数も1回だけ.
|
||||||
this.queueService.systemWebhookDeliver(merged, params.type, contents, { attempts: 1 });
|
this.queueService.systemWebhookDeliver(merged, type, contents, { attempts: 1 });
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (params.type) {
|
switch (params.type) {
|
||||||
case 'abuseReport': {
|
case 'abuseReport': {
|
||||||
send(generateAbuseReport({
|
send('abuseReport', generateAbuseReport({
|
||||||
targetUserId: dummyUser1.id,
|
targetUserId: dummyUser1.id,
|
||||||
targetUser: dummyUser1,
|
targetUser: dummyUser1,
|
||||||
reporterId: dummyUser2.id,
|
reporterId: dummyUser2.id,
|
||||||
|
@ -442,7 +437,7 @@ export class WebhookTestService {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'abuseReportResolved': {
|
case 'abuseReportResolved': {
|
||||||
send(generateAbuseReport({
|
send('abuseReportResolved', generateAbuseReport({
|
||||||
targetUserId: dummyUser1.id,
|
targetUserId: dummyUser1.id,
|
||||||
targetUser: dummyUser1,
|
targetUser: dummyUser1,
|
||||||
reporterId: dummyUser2.id,
|
reporterId: dummyUser2.id,
|
||||||
|
@ -454,7 +449,7 @@ export class WebhookTestService {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'userCreated': {
|
case 'userCreated': {
|
||||||
send(toPackedUserLite(dummyUser1));
|
send('userCreated', toPackedUserLite(dummyUser1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'inactiveModeratorsWarning': {
|
case 'inactiveModeratorsWarning': {
|
||||||
|
@ -464,15 +459,20 @@ export class WebhookTestService {
|
||||||
asHours: 24,
|
asHours: 24,
|
||||||
};
|
};
|
||||||
|
|
||||||
send({
|
send('inactiveModeratorsWarning', {
|
||||||
remainingTime: dummyTime,
|
remainingTime: dummyTime,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'inactiveModeratorsInvitationOnlyChanged': {
|
case 'inactiveModeratorsInvitationOnlyChanged': {
|
||||||
send({});
|
send('inactiveModeratorsInvitationOnlyChanged', {});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default: {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const _exhaustiveAssertion: never = params.type;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typ
|
||||||
import { id } from './util/id.js';
|
import { id } from './util/id.js';
|
||||||
import { MiUser } from './User.js';
|
import { MiUser } from './User.js';
|
||||||
|
|
||||||
|
export type AbuseReportResolveType = 'accept' | 'reject';
|
||||||
|
|
||||||
@Entity('abuse_user_report')
|
@Entity('abuse_user_report')
|
||||||
export class MiAbuseUserReport {
|
export class MiAbuseUserReport {
|
||||||
@PrimaryColumn(id())
|
@PrimaryColumn(id())
|
||||||
|
@ -76,7 +78,7 @@ export class MiAbuseUserReport {
|
||||||
@Column('varchar', {
|
@Column('varchar', {
|
||||||
length: 128, nullable: true,
|
length: 128, nullable: true,
|
||||||
})
|
})
|
||||||
public resolvedAs: 'accept' | 'reject' | null;
|
public resolvedAs: AbuseReportResolveType | null;
|
||||||
|
|
||||||
//#region Denormalized fields
|
//#region Denormalized fields
|
||||||
@Index()
|
@Index()
|
||||||
|
|
|
@ -55,7 +55,7 @@ export const paramDef = {
|
||||||
properties: {
|
properties: {
|
||||||
title: { type: 'string', minLength: 1 },
|
title: { type: 'string', minLength: 1 },
|
||||||
text: { type: 'string', minLength: 1 },
|
text: { type: 'string', minLength: 1 },
|
||||||
imageUrl: { type: 'string', nullable: true, minLength: 1 },
|
imageUrl: { type: 'string', nullable: true, minLength: 0 },
|
||||||
icon: { type: 'string', enum: ['info', 'warning', 'error', 'success'], default: 'info' },
|
icon: { type: 'string', enum: ['info', 'warning', 'error', 'success'], default: 'info' },
|
||||||
display: { type: 'string', enum: ['normal', 'banner', 'dialog'], default: 'normal' },
|
display: { type: 'string', enum: ['normal', 'banner', 'dialog'], default: 'normal' },
|
||||||
forExistingUsers: { type: 'boolean', default: false },
|
forExistingUsers: { type: 'boolean', default: false },
|
||||||
|
@ -76,7 +76,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
updatedAt: null,
|
updatedAt: null,
|
||||||
title: ps.title,
|
title: ps.title,
|
||||||
text: ps.text,
|
text: ps.text,
|
||||||
imageUrl: ps.imageUrl,
|
/* eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- 空の文字列の場合、nullを渡すようにするため */
|
||||||
|
imageUrl: ps.imageUrl || null,
|
||||||
icon: ps.icon,
|
icon: ps.icon,
|
||||||
display: ps.display,
|
display: ps.display,
|
||||||
forExistingUsers: ps.forExistingUsers,
|
forExistingUsers: ps.forExistingUsers,
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
"./node_modules"
|
"./node_modules"
|
||||||
],
|
],
|
||||||
"types": [
|
"types": [
|
||||||
"vite/client",
|
"vite/client"
|
||||||
],
|
],
|
||||||
"lib": [
|
"lib": [
|
||||||
"esnext",
|
"esnext",
|
||||||
|
@ -44,8 +44,9 @@
|
||||||
},
|
},
|
||||||
"compileOnSave": false,
|
"compileOnSave": false,
|
||||||
"include": [
|
"include": [
|
||||||
"./**/*.ts",
|
"./src/**/*.ts",
|
||||||
"./**/*.vue"
|
"./src/**/*.vue",
|
||||||
|
"./@types/**/*.ts"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
".storybook/**/*"
|
".storybook/**/*"
|
||||||
|
|
|
@ -187,6 +187,7 @@ import MkUrlPreview from '@/components/MkUrlPreview.vue';
|
||||||
import MkInstanceTicker from '@/components/MkInstanceTicker.vue';
|
import MkInstanceTicker from '@/components/MkInstanceTicker.vue';
|
||||||
import { pleaseLogin, type OpenOnRemoteOptions } from '@/scripts/please-login.js';
|
import { pleaseLogin, type OpenOnRemoteOptions } from '@/scripts/please-login.js';
|
||||||
import { checkWordMute } from '@/scripts/check-word-mute.js';
|
import { checkWordMute } from '@/scripts/check-word-mute.js';
|
||||||
|
import { notePage } from '@/filters/note.js';
|
||||||
import { userPage } from '@/filters/user.js';
|
import { userPage } from '@/filters/user.js';
|
||||||
import number from '@/filters/number.js';
|
import number from '@/filters/number.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
|
@ -566,15 +567,24 @@ function showRenoteMenu(): void {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const renoteDetailsMenu: MenuItem = {
|
||||||
|
type: 'link',
|
||||||
|
text: i18n.ts.renoteDetails,
|
||||||
|
icon: 'ti ti-info-circle',
|
||||||
|
to: notePage(note.value),
|
||||||
|
};
|
||||||
|
|
||||||
if (isMyRenote) {
|
if (isMyRenote) {
|
||||||
pleaseLogin({ openOnRemote: pleaseLoginContext.value });
|
pleaseLogin({ openOnRemote: pleaseLoginContext.value });
|
||||||
os.popupMenu([
|
os.popupMenu([
|
||||||
|
renoteDetailsMenu,
|
||||||
getCopyNoteLinkMenu(note.value, i18n.ts.copyLinkRenote),
|
getCopyNoteLinkMenu(note.value, i18n.ts.copyLinkRenote),
|
||||||
{ type: 'divider' },
|
{ type: 'divider' },
|
||||||
getUnrenote(),
|
getUnrenote(),
|
||||||
], renoteTime.value);
|
], renoteTime.value);
|
||||||
} else {
|
} else {
|
||||||
os.popupMenu([
|
os.popupMenu([
|
||||||
|
renoteDetailsMenu,
|
||||||
getCopyNoteLinkMenu(note.value, i18n.ts.copyLinkRenote),
|
getCopyNoteLinkMenu(note.value, i18n.ts.copyLinkRenote),
|
||||||
{ type: 'divider' },
|
{ type: 'divider' },
|
||||||
getAbuseNoteMenu(note.value, i18n.ts.reportAbuseRenote),
|
getAbuseNoteMenu(note.value, i18n.ts.reportAbuseRenote),
|
||||||
|
|
|
@ -45,8 +45,11 @@
|
||||||
},
|
},
|
||||||
"compileOnSave": false,
|
"compileOnSave": false,
|
||||||
"include": [
|
"include": [
|
||||||
"./**/*.ts",
|
"./src/**/*.ts",
|
||||||
"./**/*.vue"
|
"./src/**/*.vue",
|
||||||
|
"./test/**/*.ts",
|
||||||
|
"./test/**/*.vue",
|
||||||
|
"./@types/**/*.ts"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
".storybook/**/*"
|
".storybook/**/*"
|
||||||
|
|
Loading…
Reference in New Issue