Compare commits
20 Commits
2024.8.0-r
...
multiple-r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ddd4bc545 | ||
|
|
3cd5f86510 | ||
|
|
9b78ce8047 | ||
|
|
1629c0e50d | ||
|
|
427f4a2cda | ||
|
|
ba9c5c37b8 | ||
|
|
e790aa0548 | ||
|
|
bf8c42eecd | ||
|
|
129af06198 | ||
|
|
83c04c55ad | ||
|
|
0b98554319 | ||
|
|
4e0d57000c | ||
|
|
c0de57c08d | ||
|
|
cb6a1c773e | ||
|
|
9df887ba93 | ||
|
|
75b0315ace | ||
|
|
a2769d0733 | ||
|
|
036f90133c | ||
|
|
f9bfff604d | ||
|
|
fd0e840138 |
@@ -17,7 +17,7 @@
|
|||||||
- Fix: 特定の条件下でノートの削除ボタンが出ないのを修正
|
- Fix: 特定の条件下でノートの削除ボタンが出ないのを修正
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
- enhance: 照会時にURLがhtmlかつheadタグ内に`rel="alternate"`, `type="application/activity+json"`の`link`タグがある場合に追ってリンク先を照会できるように
|
- Enhance: 照会時にURLがhtmlかつheadタグ内に`rel="alternate"`, `type="application/activity+json"`の`link`タグがある場合に追ってリンク先を照会できるように
|
||||||
- Enhance: 凍結されたアカウントのフォローリクエストを表示しないように
|
- Enhance: 凍結されたアカウントのフォローリクエストを表示しないように
|
||||||
- Fix: WSの`readAllNotifications` メッセージが `body` を持たない場合に動作しない問題 #14374
|
- Fix: WSの`readAllNotifications` メッセージが `body` を持たない場合に動作しない問題 #14374
|
||||||
- 通知ページや通知カラム(デッキ)を開いている状態において、新たに発生した通知が既読されない問題が修正されます。
|
- 通知ページや通知カラム(デッキ)を開いている状態において、新たに発生した通知が既読されない問題が修正されます。
|
||||||
|
|||||||
@@ -2499,6 +2499,7 @@ _moderationLogTypes:
|
|||||||
createAbuseReportNotificationRecipient: "Create a recipient for abuse reports"
|
createAbuseReportNotificationRecipient: "Create a recipient for abuse reports"
|
||||||
updateAbuseReportNotificationRecipient: "Update recipients for abuse reports"
|
updateAbuseReportNotificationRecipient: "Update recipients for abuse reports"
|
||||||
deleteAbuseReportNotificationRecipient: "Delete a recipient for abuse reports"
|
deleteAbuseReportNotificationRecipient: "Delete a recipient for abuse reports"
|
||||||
|
deleteFlash: "Delete Play"
|
||||||
_fileViewer:
|
_fileViewer:
|
||||||
title: "File details"
|
title: "File details"
|
||||||
type: "File type"
|
type: "File type"
|
||||||
|
|||||||
4
locales/index.d.ts
vendored
4
locales/index.d.ts
vendored
@@ -6686,6 +6686,10 @@ export interface Locale extends ILocale {
|
|||||||
* ノートのピン留めの最大数
|
* ノートのピン留めの最大数
|
||||||
*/
|
*/
|
||||||
"pinMax": string;
|
"pinMax": string;
|
||||||
|
/**
|
||||||
|
* 一つのノートに対する最大リアクション数
|
||||||
|
*/
|
||||||
|
"reactionsPerNoteLimit": string;
|
||||||
/**
|
/**
|
||||||
* アンテナの作成可能数
|
* アンテナの作成可能数
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1728,6 +1728,7 @@ _role:
|
|||||||
alwaysMarkNsfw: "ファイルにNSFWを常に付与"
|
alwaysMarkNsfw: "ファイルにNSFWを常に付与"
|
||||||
canUpdateBioMedia: "アイコンとバナーの更新を許可"
|
canUpdateBioMedia: "アイコンとバナーの更新を許可"
|
||||||
pinMax: "ノートのピン留めの最大数"
|
pinMax: "ノートのピン留めの最大数"
|
||||||
|
reactionsPerNoteLimit: "一つのノートに対する最大リアクション数"
|
||||||
antennaMax: "アンテナの作成可能数"
|
antennaMax: "アンテナの作成可能数"
|
||||||
wordMuteMax: "ワードミュートの最大文字数"
|
wordMuteMax: "ワードミュートの最大文字数"
|
||||||
webhookMax: "Webhookの作成可能数"
|
webhookMax: "Webhookの作成可能数"
|
||||||
|
|||||||
@@ -2316,6 +2316,7 @@ _pages:
|
|||||||
eyeCatchingImageSet: "设置封面图片"
|
eyeCatchingImageSet: "设置封面图片"
|
||||||
eyeCatchingImageRemove: "删除封面图片"
|
eyeCatchingImageRemove: "删除封面图片"
|
||||||
chooseBlock: "添加块"
|
chooseBlock: "添加块"
|
||||||
|
enterSectionTitle: "输入会话标题"
|
||||||
selectType: "选择类型"
|
selectType: "选择类型"
|
||||||
contentBlocks: "内容"
|
contentBlocks: "内容"
|
||||||
inputBlocks: "输入"
|
inputBlocks: "输入"
|
||||||
@@ -2499,6 +2500,10 @@ _moderationLogTypes:
|
|||||||
createAbuseReportNotificationRecipient: "新建了举报通知"
|
createAbuseReportNotificationRecipient: "新建了举报通知"
|
||||||
updateAbuseReportNotificationRecipient: "更新了举报通知"
|
updateAbuseReportNotificationRecipient: "更新了举报通知"
|
||||||
deleteAbuseReportNotificationRecipient: "删除了举报通知"
|
deleteAbuseReportNotificationRecipient: "删除了举报通知"
|
||||||
|
deleteAccount: "删除了账户"
|
||||||
|
deletePage: "删除了页面"
|
||||||
|
deleteFlash: "删除了 Play"
|
||||||
|
deleteGalleryPost: "删除了图库稿件"
|
||||||
_fileViewer:
|
_fileViewer:
|
||||||
title: "文件信息"
|
title: "文件信息"
|
||||||
type: "文件类型"
|
type: "文件类型"
|
||||||
|
|||||||
@@ -2316,6 +2316,7 @@ _pages:
|
|||||||
eyeCatchingImageSet: "設定封面影像"
|
eyeCatchingImageSet: "設定封面影像"
|
||||||
eyeCatchingImageRemove: "刪除封面影像"
|
eyeCatchingImageRemove: "刪除封面影像"
|
||||||
chooseBlock: "新增方塊"
|
chooseBlock: "新增方塊"
|
||||||
|
enterSectionTitle: "輸入區段的標題"
|
||||||
selectType: "選擇類型"
|
selectType: "選擇類型"
|
||||||
contentBlocks: "內容"
|
contentBlocks: "內容"
|
||||||
inputBlocks: "輸入"
|
inputBlocks: "輸入"
|
||||||
@@ -2499,6 +2500,10 @@ _moderationLogTypes:
|
|||||||
createAbuseReportNotificationRecipient: "建立接收檢舉的通知對象"
|
createAbuseReportNotificationRecipient: "建立接收檢舉的通知對象"
|
||||||
updateAbuseReportNotificationRecipient: "更新接收檢舉的通知對象"
|
updateAbuseReportNotificationRecipient: "更新接收檢舉的通知對象"
|
||||||
deleteAbuseReportNotificationRecipient: "刪除接收檢舉的通知對象"
|
deleteAbuseReportNotificationRecipient: "刪除接收檢舉的通知對象"
|
||||||
|
deleteAccount: "刪除帳戶"
|
||||||
|
deletePage: "刪除頁面"
|
||||||
|
deleteFlash: "刪除 Play"
|
||||||
|
deleteGalleryPost: "刪除相簿的貼文"
|
||||||
_fileViewer:
|
_fileViewer:
|
||||||
title: "檔案詳細資訊"
|
title: "檔案詳細資訊"
|
||||||
type: "檔案類型 "
|
type: "檔案類型 "
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class MultipleReactions1721117896543 {
|
||||||
|
name = 'MultipleReactions1721117896543';
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query('DROP INDEX "public"."IDX_ad0c221b25672daf2df320a817"');
|
||||||
|
await queryRunner.query('CREATE UNIQUE INDEX "IDX_a7751b74317122d11575bff31c" ON "note_reaction" ("userId", "noteId", "reaction") ');
|
||||||
|
await queryRunner.query('CREATE INDEX "IDX_ad0c221b25672daf2df320a817" ON "note_reaction" ("userId", "noteId") ');
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query('DROP INDEX "public"."IDX_ad0c221b25672daf2df320a817"');
|
||||||
|
await queryRunner.query('DROP INDEX "public"."IDX_a7751b74317122d11575bff31c"');
|
||||||
|
await queryRunner.query('CREATE UNIQUE INDEX "IDX_ad0c221b25672daf2df320a817" ON "note_reaction" ("userId", "noteId") ');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -174,24 +174,12 @@ export class ReactionService {
|
|||||||
reaction,
|
reaction,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create reaction
|
|
||||||
try {
|
try {
|
||||||
await this.noteReactionsRepository.insert(record);
|
await this.noteReactionsRepository.insert(record);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (isDuplicateKeyValueError(e)) {
|
if (isDuplicateKeyValueError(e)) {
|
||||||
const exists = await this.noteReactionsRepository.findOneByOrFail({
|
|
||||||
noteId: note.id,
|
|
||||||
userId: user.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (exists.reaction !== reaction) {
|
|
||||||
// 別のリアクションがすでにされていたら置き換える
|
|
||||||
await this.delete(user, note);
|
|
||||||
await this.noteReactionsRepository.insert(record);
|
|
||||||
} else {
|
|
||||||
// 同じリアクションがすでにされていたらエラー
|
// 同じリアクションがすでにされていたらエラー
|
||||||
throw new IdentifiableError('51c42bb4-931a-456b-bff7-e5a8a70dd298');
|
throw new IdentifiableError('51c42bb4-931a-456b-bff7-e5a8a70dd298');
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
@@ -286,11 +274,12 @@ export class ReactionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async delete(user: { id: MiUser['id']; host: MiUser['host']; isBot: MiUser['isBot']; }, note: MiNote) {
|
public async delete(user: { id: MiUser['id']; host: MiUser['host']; isBot: MiUser['isBot']; }, note: MiNote, _reaction?: string | null) {
|
||||||
// if already unreacted
|
// if already unreacted
|
||||||
const exist = await this.noteReactionsRepository.findOneBy({
|
const exist = await this.noteReactionsRepository.findOneBy({
|
||||||
noteId: note.id,
|
noteId: note.id,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
|
reaction: _reaction ?? FALLBACK,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist == null) {
|
if (exist == null) {
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ export type RolePolicies = {
|
|||||||
alwaysMarkNsfw: boolean;
|
alwaysMarkNsfw: boolean;
|
||||||
canUpdateBioMedia: boolean;
|
canUpdateBioMedia: boolean;
|
||||||
pinLimit: number;
|
pinLimit: number;
|
||||||
|
reactionsPerNoteLimit: number;
|
||||||
antennaLimit: number;
|
antennaLimit: number;
|
||||||
wordMuteLimit: number;
|
wordMuteLimit: number;
|
||||||
webhookLimit: number;
|
webhookLimit: number;
|
||||||
@@ -78,6 +79,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
|
|||||||
alwaysMarkNsfw: false,
|
alwaysMarkNsfw: false,
|
||||||
canUpdateBioMedia: true,
|
canUpdateBioMedia: true,
|
||||||
pinLimit: 5,
|
pinLimit: 5,
|
||||||
|
reactionsPerNoteLimit: 1,
|
||||||
antennaLimit: 5,
|
antennaLimit: 5,
|
||||||
wordMuteLimit: 200,
|
wordMuteLimit: 200,
|
||||||
webhookLimit: 3,
|
webhookLimit: 3,
|
||||||
@@ -380,6 +382,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
|
|||||||
alwaysMarkNsfw: calc('alwaysMarkNsfw', vs => vs.some(v => v === true)),
|
alwaysMarkNsfw: calc('alwaysMarkNsfw', vs => vs.some(v => v === true)),
|
||||||
canUpdateBioMedia: calc('canUpdateBioMedia', vs => vs.some(v => v === true)),
|
canUpdateBioMedia: calc('canUpdateBioMedia', vs => vs.some(v => v === true)),
|
||||||
pinLimit: calc('pinLimit', vs => Math.max(...vs)),
|
pinLimit: calc('pinLimit', vs => Math.max(...vs)),
|
||||||
|
reactionsPerNoteLimit: calc('reactionsPerNoteLimit', vs => Math.max(...vs)),
|
||||||
antennaLimit: calc('antennaLimit', vs => Math.max(...vs)),
|
antennaLimit: calc('antennaLimit', vs => Math.max(...vs)),
|
||||||
wordMuteLimit: calc('wordMuteLimit', vs => Math.max(...vs)),
|
wordMuteLimit: calc('wordMuteLimit', vs => Math.max(...vs)),
|
||||||
webhookLimit: calc('webhookLimit', vs => Math.max(...vs)),
|
webhookLimit: calc('webhookLimit', vs => Math.max(...vs)),
|
||||||
|
|||||||
@@ -203,7 +203,9 @@ export class ApRequestService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//#region リクエスト先がhtmlかつactivity+jsonへのalternate linkタグがあるとき
|
//#region リクエスト先がhtmlかつactivity+jsonへのalternate linkタグがあるとき
|
||||||
if (res.headers.get('Content-type')?.startsWith('text/html;') && _followAlternate === true) {
|
const contentType = res.headers.get('content-type');
|
||||||
|
|
||||||
|
if ((contentType ?? '').split(';')[0].trimEnd().toLowerCase() === 'text/html' && _followAlternate === true) {
|
||||||
const html = await res.text();
|
const html = await res.text();
|
||||||
const window = new Window();
|
const window = new Window();
|
||||||
const document = window.document;
|
const document = window.document;
|
||||||
|
|||||||
@@ -170,10 +170,10 @@ export class NoteEntityService implements OnModuleInit {
|
|||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async populateMyReaction(note: { id: MiNote['id']; reactions: MiNote['reactions']; reactionAndUserPairCache?: MiNote['reactionAndUserPairCache']; }, meId: MiUser['id'], _hint_?: {
|
public async populateMyReaction(note: { id: MiNote['id']; reactions: MiNote['reactions']; reactionAndUserPairCache?: MiNote['reactionAndUserPairCache']; }, meId: MiUser['id'], _hint_?: {
|
||||||
myReactions: Map<MiNote['id'], string | null>;
|
myReactionsMap: Map<MiNote['id'], string | null>;
|
||||||
}) {
|
}) {
|
||||||
if (_hint_?.myReactions) {
|
if (_hint_?.myReactionsMap) {
|
||||||
const reaction = _hint_.myReactions.get(note.id);
|
const reaction = _hint_.myReactionsMap.get(note.id);
|
||||||
if (reaction) {
|
if (reaction) {
|
||||||
return this.reactionService.convertLegacyReaction(reaction);
|
return this.reactionService.convertLegacyReaction(reaction);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ import { MiUser } from './User.js';
|
|||||||
import { MiNote } from './Note.js';
|
import { MiNote } from './Note.js';
|
||||||
|
|
||||||
@Entity('note_reaction')
|
@Entity('note_reaction')
|
||||||
@Index(['userId', 'noteId'], { unique: true })
|
@Index(['userId', 'noteId'])
|
||||||
|
@Index(['userId', 'noteId', 'reaction'], { unique: true })
|
||||||
export class MiNoteReaction {
|
export class MiNoteReaction {
|
||||||
@PrimaryColumn(id())
|
@PrimaryColumn(id())
|
||||||
public id: string;
|
public id: string;
|
||||||
|
|||||||
@@ -236,6 +236,10 @@ export const packedRolePoliciesSchema = {
|
|||||||
type: 'integer',
|
type: 'integer',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
|
reactionsPerNoteLimit: {
|
||||||
|
type: 'integer',
|
||||||
|
optional: false, nullable: false,
|
||||||
|
},
|
||||||
antennaLimit: {
|
antennaLimit: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="$style.preview">
|
<div :class="$style.preview">
|
||||||
<div :class="$style.preview__content1">
|
<div>
|
||||||
<MkInput v-model="text">
|
<MkInput v-model="text">
|
||||||
<template #label>Text</template>
|
<template #label>Text</template>
|
||||||
</MkInput>
|
</MkInput>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<span :class="$style.bodyName">{{ role.name }}</span>
|
<span :class="$style.bodyName">{{ role.name }}</span>
|
||||||
<template v-if="detailed">
|
<template v-if="detailed">
|
||||||
<span v-if="role.target === 'manual'" :class="$style.bodyUsers">{{ role.usersCount }} users</span>
|
<span v-if="role.target === 'manual'" :class="$style.bodyUsers">{{ role.usersCount }} users</span>
|
||||||
<span v-else-if="role.target === 'conditional'" :class="$style.bodyUsers">({{ i18n.ts._role.conditional }})</span>
|
<span v-else-if="role.target === 'conditional'" :class="$style.bodyUsers">? users</span>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.bodyDescription">{{ role.description }}</div>
|
<div :class="$style.bodyDescription">{{ role.description }}</div>
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ export const ROLE_POLICIES = [
|
|||||||
'alwaysMarkNsfw',
|
'alwaysMarkNsfw',
|
||||||
'canUpdateBioMedia',
|
'canUpdateBioMedia',
|
||||||
'pinLimit',
|
'pinLimit',
|
||||||
|
'reactionsPerNoteLimit',
|
||||||
'antennaLimit',
|
'antennaLimit',
|
||||||
'wordMuteLimit',
|
'wordMuteLimit',
|
||||||
'webhookLimit',
|
'webhookLimit',
|
||||||
|
|||||||
@@ -72,10 +72,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<img src="https://avatars.githubusercontent.com/u/4439005?v=4" :class="$style.contributorAvatar">
|
<img src="https://avatars.githubusercontent.com/u/4439005?v=4" :class="$style.contributorAvatar">
|
||||||
<span :class="$style.contributorUsername">@syuilo</span>
|
<span :class="$style.contributorUsername">@syuilo</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/tamaina" target="_blank" :class="$style.contributor">
|
|
||||||
<img src="https://avatars.githubusercontent.com/u/7973572?v=4" :class="$style.contributorAvatar">
|
|
||||||
<span :class="$style.contributorUsername">@tamaina</span>
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/acid-chicken" target="_blank" :class="$style.contributor">
|
<a href="https://github.com/acid-chicken" target="_blank" :class="$style.contributor">
|
||||||
<img src="https://avatars.githubusercontent.com/u/20679825?v=4" :class="$style.contributorAvatar">
|
<img src="https://avatars.githubusercontent.com/u/20679825?v=4" :class="$style.contributorAvatar">
|
||||||
<span :class="$style.contributorUsername">@acid-chicken</span>
|
<span :class="$style.contributorUsername">@acid-chicken</span>
|
||||||
@@ -267,6 +263,9 @@ const patronsWithIcon = [{
|
|||||||
}, {
|
}, {
|
||||||
name: 'Macop',
|
name: 'Macop',
|
||||||
icon: 'https://assets.misskey-hub.net/patrons/ee052bf550014d36a643ce3dce595640.jpg',
|
icon: 'https://assets.misskey-hub.net/patrons/ee052bf550014d36a643ce3dce595640.jpg',
|
||||||
|
}, {
|
||||||
|
name: 'なっかあ',
|
||||||
|
icon: 'https://assets.misskey-hub.net/patrons/c2f5f3e394e74a64912284a2f4ca710e.jpg',
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const patrons = [
|
const patrons = [
|
||||||
|
|||||||
@@ -417,6 +417,25 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.reactionsPerNoteLimit, 'reactionsPerNoteLimit'])">
|
||||||
|
<template #label>{{ i18n.ts._role._options.reactionsPerNoteLimit }}</template>
|
||||||
|
<template #suffix>
|
||||||
|
<span v-if="role.policies.reactionsPerNoteLimit.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||||
|
<span v-else>{{ role.policies.reactionsPerNoteLimit.value }}</span>
|
||||||
|
<span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.reactionsPerNoteLimit)"></i></span>
|
||||||
|
</template>
|
||||||
|
<div class="_gaps">
|
||||||
|
<MkSwitch v-model="role.policies.reactionsPerNoteLimit.useDefault" :readonly="readonly">
|
||||||
|
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
<MkInput v-model="role.policies.reactionsPerNoteLimit.value" :disabled="role.policies.reactionsPerNoteLimit.useDefault" type="number" :readonly="readonly">
|
||||||
|
</MkInput>
|
||||||
|
<MkRange v-model="role.policies.reactionsPerNoteLimit.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''">
|
||||||
|
<template #label>{{ i18n.ts._role.priority }}</template>
|
||||||
|
</MkRange>
|
||||||
|
</div>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.antennaMax, 'antennaLimit'])">
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.antennaMax, 'antennaLimit'])">
|
||||||
<template #label>{{ i18n.ts._role._options.antennaMax }}</template>
|
<template #label>{{ i18n.ts._role._options.antennaMax }}</template>
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
|
|||||||
@@ -149,6 +149,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</MkInput>
|
</MkInput>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.reactionsPerNoteLimit, 'reactionsPerNoteLimit'])">
|
||||||
|
<template #label>{{ i18n.ts._role._options.reactionsPerNoteLimit }}</template>
|
||||||
|
<template #suffix>{{ policies.reactionsPerNoteLimit }}</template>
|
||||||
|
<MkInput v-model="policies.reactionsPerNoteLimit" type="number">
|
||||||
|
</MkInput>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.antennaMax, 'antennaLimit'])">
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.antennaMax, 'antennaLimit'])">
|
||||||
<template #label>{{ i18n.ts._role._options.antennaMax }}</template>
|
<template #label>{{ i18n.ts._role._options.antennaMax }}</template>
|
||||||
<template #suffix>{{ policies.antennaLimit }}</template>
|
<template #suffix>{{ policies.antennaLimit }}</template>
|
||||||
|
|||||||
@@ -236,10 +236,12 @@ function reportAbuse() {
|
|||||||
|
|
||||||
const pageUrl = `${url}/play/${flash.value.id}`;
|
const pageUrl = `${url}/play/${flash.value.id}`;
|
||||||
|
|
||||||
os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), {
|
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), {
|
||||||
user: flash.value.user,
|
user: flash.value.user,
|
||||||
initialComment: `Play: ${pageUrl}\n-----\n`,
|
initialComment: `Play: ${pageUrl}\n-----\n`,
|
||||||
}, {}, 'closed');
|
}, {
|
||||||
|
closed: () => dispose(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function showMenu(ev: MouseEvent) {
|
function showMenu(ev: MouseEvent) {
|
||||||
|
|||||||
@@ -160,10 +160,12 @@ function reportAbuse() {
|
|||||||
|
|
||||||
const pageUrl = `${url}/gallery/${post.value.id}`;
|
const pageUrl = `${url}/gallery/${post.value.id}`;
|
||||||
|
|
||||||
os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), {
|
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), {
|
||||||
user: post.value.user,
|
user: post.value.user,
|
||||||
initialComment: `Post: ${pageUrl}\n-----\n`,
|
initialComment: `Post: ${pageUrl}\n-----\n`,
|
||||||
}, {}, 'closed');
|
}, {
|
||||||
|
closed: () => dispose(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function showMenu(ev: MouseEvent) {
|
function showMenu(ev: MouseEvent) {
|
||||||
|
|||||||
@@ -245,10 +245,12 @@ function reportAbuse() {
|
|||||||
|
|
||||||
const pageUrl = `${url}/@${props.username}/pages/${props.pageName}`;
|
const pageUrl = `${url}/@${props.username}/pages/${props.pageName}`;
|
||||||
|
|
||||||
os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), {
|
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), {
|
||||||
user: page.value.user,
|
user: page.value.user,
|
||||||
initialComment: `Page: ${pageUrl}\n-----\n`,
|
initialComment: `Page: ${pageUrl}\n-----\n`,
|
||||||
}, {}, 'closed');
|
}, {
|
||||||
|
closed: () => dispose(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function showMenu(ev: MouseEvent) {
|
function showMenu(ev: MouseEvent) {
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ function closeTutorial(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function switchTlIfNeeded() {
|
function switchTlIfNeeded() {
|
||||||
if (isBasicTimeline(src.value) && !availableBasicTimelines().includes(src.value)) {
|
if (isBasicTimeline(src.value) && !isAvailableBasicTimeline(src.value)) {
|
||||||
src.value = availableBasicTimelines()[0];
|
src.value = availableBasicTimelines()[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,12 @@ import type {
|
|||||||
Ad,
|
Ad,
|
||||||
Announcement,
|
Announcement,
|
||||||
EmojiDetailed,
|
EmojiDetailed,
|
||||||
|
Flash,
|
||||||
|
GalleryPost,
|
||||||
InviteCode,
|
InviteCode,
|
||||||
MetaDetailed,
|
MetaDetailed,
|
||||||
Note,
|
Note,
|
||||||
|
Page,
|
||||||
Role,
|
Role,
|
||||||
ReversiGameDetailed,
|
ReversiGameDetailed,
|
||||||
SystemWebhook,
|
SystemWebhook,
|
||||||
@@ -405,18 +408,18 @@ export type ModerationLogPayloads = {
|
|||||||
pageId: string;
|
pageId: string;
|
||||||
pageUserId: string;
|
pageUserId: string;
|
||||||
pageUserUsername: string;
|
pageUserUsername: string;
|
||||||
page: any;
|
page: Page;
|
||||||
};
|
};
|
||||||
deleteFlash: {
|
deleteFlash: {
|
||||||
flashId: string;
|
flashId: string;
|
||||||
flashUserId: string;
|
flashUserId: string;
|
||||||
flashUserUsername: string;
|
flashUserUsername: string;
|
||||||
flash: any;
|
flash: Flash;
|
||||||
};
|
};
|
||||||
deleteGalleryPost: {
|
deleteGalleryPost: {
|
||||||
postId: string;
|
postId: string;
|
||||||
postUserId: string;
|
postUserId: string;
|
||||||
postUserUsername: string;
|
postUserUsername: string;
|
||||||
post: any;
|
post: GalleryPost;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user