Merge branch 'misskey-dev:develop' into develop
This commit is contained in:
commit
66aa07e6e6
@ -29,6 +29,7 @@
|
|||||||
- ユーザーが誤ったメールアドレスを入力した場合に招待コードが失効してしまう問題が解消されます。
|
- ユーザーが誤ったメールアドレスを入力した場合に招待コードが失効してしまう問題が解消されます。
|
||||||
- Enhance: すでにフォローしたすべての人の返信をTLに追加できるように
|
- Enhance: すでにフォローしたすべての人の返信をTLに追加できるように
|
||||||
- Enhance: 未読の通知数を表示できるように
|
- Enhance: 未読の通知数を表示できるように
|
||||||
|
- Enhance: 通知されず、確認の必要もないお知らせ(silence)を作成可能になりました
|
||||||
- Enhance: ローカリゼーションの更新
|
- Enhance: ローカリゼーションの更新
|
||||||
- Enhance: 依存関係の更新
|
- Enhance: 依存関係の更新
|
||||||
- Change: CWを使用する場合、注釈を空にすることは許可されなくなりました
|
- Change: CWを使用する場合、注釈を空にすることは許可されなくなりました
|
||||||
@ -63,6 +64,7 @@
|
|||||||
- Fix: 11以上されているリアクションにおいてツールチップで示されるリアクション数が本来よりも1多い問題を修正 #12174
|
- Fix: 11以上されているリアクションにおいてツールチップで示されるリアクション数が本来よりも1多い問題を修正 #12174
|
||||||
- Fix: サイレンス状態で公開範囲のパブリックを選択できてしまう問題を修正 #12224
|
- Fix: サイレンス状態で公開範囲のパブリックを選択できてしまう問題を修正 #12224
|
||||||
- Fix: In deck layout, replies option is not saved after refresh
|
- Fix: In deck layout, replies option is not saved after refresh
|
||||||
|
- Fix: アーカイブしたお知らせがコントロールパネルに表示される問題を修正
|
||||||
- Note: アップデート後、サウンドに関する設定が初期化されます
|
- Note: アップデート後、サウンドに関する設定が初期化されます
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
@ -72,6 +74,7 @@
|
|||||||
- Enhance: プロフィールの自己紹介欄のMFMが連合するようになりました
|
- Enhance: プロフィールの自己紹介欄のMFMが連合するようになりました
|
||||||
- 相手がMisskey v2023.11.0以降である必要があります
|
- 相手がMisskey v2023.11.0以降である必要があります
|
||||||
- Enhance: チャンネル取得時のパフォーマンスを向上
|
- Enhance: チャンネル取得時のパフォーマンスを向上
|
||||||
|
- Enhance: AP: ApplicationタイプのアカウントをisBotとして扱うように
|
||||||
- Fix: リストTLに自分のフォロワー限定投稿が含まれない問題を修正
|
- Fix: リストTLに自分のフォロワー限定投稿が含まれない問題を修正
|
||||||
- Fix: ローカルタイムラインに投稿者自身の投稿への返信が含まれない問題を修正
|
- Fix: ローカルタイムラインに投稿者自身の投稿への返信が含まれない問題を修正
|
||||||
- Fix: 自分のフォローしているユーザーの自分のフォローしていないユーザーの visibility: followers な投稿への返信がストリーミングで流れてくる問題を修正
|
- Fix: 自分のフォローしているユーザーの自分のフォローしていないユーザーの visibility: followers な投稿への返信がストリーミングで流れてくる問題を修正
|
||||||
|
@ -1157,6 +1157,7 @@ disableStreamingTimeline: "Disable real-time timeline updates"
|
|||||||
useGroupedNotifications: "Display grouped notifications"
|
useGroupedNotifications: "Display grouped notifications"
|
||||||
signupPendingError: "There was a problem verifying the email address. The link may have expired."
|
signupPendingError: "There was a problem verifying the email address. The link may have expired."
|
||||||
cwNotationRequired: "If \"Hide content\" is enabled, a description must be provided."
|
cwNotationRequired: "If \"Hide content\" is enabled, a description must be provided."
|
||||||
|
doReaction: "Add reaction"
|
||||||
_announcement:
|
_announcement:
|
||||||
forExistingUsers: "Existing users only"
|
forExistingUsers: "Existing users only"
|
||||||
forExistingUsersDescription: "This announcement will only be shown to users existing at the point of publishment if enabled. If disabled, those newly signing up after it has been posted will also see it."
|
forExistingUsersDescription: "This announcement will only be shown to users existing at the point of publishment if enabled. If disabled, those newly signing up after it has been posted will also see it."
|
||||||
@ -1203,6 +1204,54 @@ _initialTutorial:
|
|||||||
title: "What are Reactions?"
|
title: "What are Reactions?"
|
||||||
description: "Notes can be reacted to with various emojis. Reactions allow you to express nuances that may not be conveyed with just a 'like.'"
|
description: "Notes can be reacted to with various emojis. Reactions allow you to express nuances that may not be conveyed with just a 'like.'"
|
||||||
letsTryReacting: "Reactions can be added by clicking the '+' button on the note. Try reacting to this sample note!"
|
letsTryReacting: "Reactions can be added by clicking the '+' button on the note. Try reacting to this sample note!"
|
||||||
|
reactToContinue: "Add a reaction to proceed."
|
||||||
|
reactNotification: "You'll receive real-time notifications when someone reacts to your note."
|
||||||
|
reactDone: "You can undo a reaction by pressing the '-' button."
|
||||||
|
_timeline:
|
||||||
|
title: "The Concept of Timelines"
|
||||||
|
description1: "Misskey provides multiple timelines based on usage (some may not be available depending on the server's policies)."
|
||||||
|
home: "You can view notes from accounts you follow."
|
||||||
|
local: "You can view notes from all users on this server."
|
||||||
|
social: "Notes from the Home and Local timelines will be displayed."
|
||||||
|
global: "You can view notes from all connected servers."
|
||||||
|
description2: "You can switch between timelines at the top of the screen at any time."
|
||||||
|
description3: "Additionally, there are list timelines and channel timelines. For more details, please refer to {link}."
|
||||||
|
_postNote:
|
||||||
|
title: "Note Posting Settings"
|
||||||
|
description1: "When posting a note on Misskey, various options are available. The posting form looks like this."
|
||||||
|
_visibility:
|
||||||
|
description: "You can limit who can view your note."
|
||||||
|
public: "Your note will be visible for all users."
|
||||||
|
home: "Public only on the Home timeline. People visiting your profile, via followers, and through renotes can see it."
|
||||||
|
followers: "Visible to followers only. Only followers can see it and no one else, and it cannot be renoted by others."
|
||||||
|
direct: "Visible only to specified users, and the recipient will be notified. It can be used as an alternative to direct messaging."
|
||||||
|
doNotSendConfidencialOnDirect1: "Be careful when sending sensitive information!"
|
||||||
|
doNotSendConfidencialOnDirect2: "Administrators of the server can see what you write. Be careful with sensitive information when sending direct notes to users on untrusted servers."
|
||||||
|
localOnly: "Posting with this flag will not federate the note to other servers. Users on other servers will not be able to view these notes directly, regardless of the display settings above."
|
||||||
|
_cw:
|
||||||
|
title: "Content Warning"
|
||||||
|
description: "Instead of the body, the content written in 'comments' field will be displayed. Pressing \"read more\" will reveal the body."
|
||||||
|
_exampleNote:
|
||||||
|
cw: "This will surely make you hungry!"
|
||||||
|
note: "Just had a chocolate-glazed donut 🍩😋"
|
||||||
|
useCases: "This is used when following the server guidelines for necessary notes or for self-restriction of spoiler or sensitive text."
|
||||||
|
_howToMakeAttachmentsSensitive:
|
||||||
|
title: "How to Mark Attachments as Sensitive?"
|
||||||
|
description: "For attachments that are required by server guidelines or that should not be left intact, add a \"sensitive\" flag."
|
||||||
|
tryThisFile: "Try marking the image attached in this form as sensitive!"
|
||||||
|
_exampleNote:
|
||||||
|
note: "Oops, messed up opening the natto lid..."
|
||||||
|
method: "To mark an attachment as sensitive, click the file thumbnail, open the menu, and click \"Mark as Sensitive.\""
|
||||||
|
sensitiveSucceeded: "When attaching files, please set sensitivities in accordance with the server guidelines."
|
||||||
|
doItToContinue: "Mark the attachment file as sensitive to proceed."
|
||||||
|
_done:
|
||||||
|
title: "The tutorial is complete! 🎉"
|
||||||
|
description: "The functions introduced here are just a small part. For a more detailed understanding of using Misskey, please refer to {link}."
|
||||||
|
_timelineDescription:
|
||||||
|
home: "In the Home timeline, you can see notes from accounts you follow."
|
||||||
|
local: "In the Local timeline, you can see notes from all users on this server."
|
||||||
|
social: "The Social timeline displays notes from both the Home and Local timelines."
|
||||||
|
global: "In the Global timeline, you can see notes from all connected servers."
|
||||||
_serverRules:
|
_serverRules:
|
||||||
description: "A set of rules to be displayed before registration. Setting a summary of the Terms of Service is recommended."
|
description: "A set of rules to be displayed before registration. Setting a summary of the Terms of Service is recommended."
|
||||||
_serverSettings:
|
_serverSettings:
|
||||||
@ -1472,6 +1521,9 @@ _achievements:
|
|||||||
_smashTestNotificationButton:
|
_smashTestNotificationButton:
|
||||||
title: "Test overflow"
|
title: "Test overflow"
|
||||||
description: "Trigger the notification test repeatedly within an extremely short time"
|
description: "Trigger the notification test repeatedly within an extremely short time"
|
||||||
|
_tutorialCompleted:
|
||||||
|
title: "Misskey Elementary Course Diploma"
|
||||||
|
description: "Tutorial completed"
|
||||||
_role:
|
_role:
|
||||||
new: "New role"
|
new: "New role"
|
||||||
edit: "Edit role"
|
edit: "Edit role"
|
||||||
@ -1660,6 +1712,7 @@ _channel:
|
|||||||
notesCount: "{n} Notes"
|
notesCount: "{n} Notes"
|
||||||
nameAndDescription: "Name and description"
|
nameAndDescription: "Name and description"
|
||||||
nameOnly: "Name only"
|
nameOnly: "Name only"
|
||||||
|
allowRenoteToExternal: "Allow renote and quote outside the channel"
|
||||||
_menuDisplay:
|
_menuDisplay:
|
||||||
sideFull: "Side"
|
sideFull: "Side"
|
||||||
sideIcon: "Side (Icons)"
|
sideIcon: "Side (Icons)"
|
||||||
|
2
locales/index.d.ts
vendored
2
locales/index.d.ts
vendored
@ -1172,6 +1172,8 @@ export interface Locale {
|
|||||||
"readConfirmText": string;
|
"readConfirmText": string;
|
||||||
"shouldNotBeUsedToPresentPermanentInfo": string;
|
"shouldNotBeUsedToPresentPermanentInfo": string;
|
||||||
"dialogAnnouncementUxWarn": string;
|
"dialogAnnouncementUxWarn": string;
|
||||||
|
"silence": string;
|
||||||
|
"silenceDescription": string;
|
||||||
};
|
};
|
||||||
"_initialAccountSetting": {
|
"_initialAccountSetting": {
|
||||||
"accountCreated": string;
|
"accountCreated": string;
|
||||||
|
@ -1170,6 +1170,8 @@ _announcement:
|
|||||||
readConfirmText: "「{title}」の内容を読み、既読にします。"
|
readConfirmText: "「{title}」の内容を読み、既読にします。"
|
||||||
shouldNotBeUsedToPresentPermanentInfo: "特に新規ユーザーのUXを損ねる可能性が高いため、ストック情報ではなくフロー情報の掲示にお知らせを使用することを推奨します。"
|
shouldNotBeUsedToPresentPermanentInfo: "特に新規ユーザーのUXを損ねる可能性が高いため、ストック情報ではなくフロー情報の掲示にお知らせを使用することを推奨します。"
|
||||||
dialogAnnouncementUxWarn: "ダイアログ形式のお知らせが同時に2つ以上ある場合、UXに悪影響を及ぼす可能性が非常に高いため、使用は慎重に行うことを推奨します。"
|
dialogAnnouncementUxWarn: "ダイアログ形式のお知らせが同時に2つ以上ある場合、UXに悪影響を及ぼす可能性が非常に高いため、使用は慎重に行うことを推奨します。"
|
||||||
|
silence: "非通知"
|
||||||
|
silenceDescription: "オンにすると、このお知らせは通知されず、既読にする必要もなくなります。"
|
||||||
|
|
||||||
_initialAccountSetting:
|
_initialAccountSetting:
|
||||||
accountCreated: "アカウントの作成が完了しました!"
|
accountCreated: "アカウントの作成が完了しました!"
|
||||||
|
@ -1157,6 +1157,7 @@ disableStreamingTimeline: "停用時間軸的即時更新"
|
|||||||
useGroupedNotifications: "分組顯示通知訊息"
|
useGroupedNotifications: "分組顯示通知訊息"
|
||||||
signupPendingError: "驗證您的電子郵件地址時出現問題。連結可能已過期。"
|
signupPendingError: "驗證您的電子郵件地址時出現問題。連結可能已過期。"
|
||||||
cwNotationRequired: "如果開啟「隱藏內容」,則需要註解說明。"
|
cwNotationRequired: "如果開啟「隱藏內容」,則需要註解說明。"
|
||||||
|
doReaction: "做出反應"
|
||||||
_announcement:
|
_announcement:
|
||||||
forExistingUsers: "僅限既有的使用者"
|
forExistingUsers: "僅限既有的使用者"
|
||||||
forExistingUsersDescription: "啟用代表僅向現存使用者顯示;停用代表張貼後註冊的新使用者也會看到。"
|
forExistingUsersDescription: "啟用代表僅向現存使用者顯示;停用代表張貼後註冊的新使用者也會看到。"
|
||||||
@ -1229,7 +1230,7 @@ _initialTutorial:
|
|||||||
localOnly: "不將貼文發布到聯邦上的其他伺服器。不論上述發布範圍,使用此設定後,其他伺服器上的使用者將無法直接查看此貼文。"
|
localOnly: "不將貼文發布到聯邦上的其他伺服器。不論上述發布範圍,使用此設定後,其他伺服器上的使用者將無法直接查看此貼文。"
|
||||||
_cw:
|
_cw:
|
||||||
title: "隱藏內容(CW)"
|
title: "隱藏內容(CW)"
|
||||||
description: "將顯示「註釋」中寫入的內容而不是本文。按一下「查看更多」以顯示本文。"
|
description: "將顯示「註釋」中寫入的內容而不是本文。按一下「顯示內容」以顯示本文。"
|
||||||
_exampleNote:
|
_exampleNote:
|
||||||
cw: "美食恐怖主義注意"
|
cw: "美食恐怖主義注意"
|
||||||
note: "我吃了一個巧克力甜甜圈🍩😋"
|
note: "我吃了一個巧克力甜甜圈🍩😋"
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class AnnouncementSilence1699141698112 {
|
||||||
|
name = 'AnnouncementSilence1699141698112'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "announcement" ADD "silence" boolean NOT NULL DEFAULT false`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_7b8d9225168e962f94ea517e00" ON "announcement" ("silence") `);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_7b8d9225168e962f94ea517e00"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "silence"`);
|
||||||
|
}
|
||||||
|
}
|
@ -47,6 +47,7 @@ export class AnnouncementService {
|
|||||||
|
|
||||||
const q = this.announcementsRepository.createQueryBuilder('announcement')
|
const q = this.announcementsRepository.createQueryBuilder('announcement')
|
||||||
.where('announcement.isActive = true')
|
.where('announcement.isActive = true')
|
||||||
|
.andWhere('announcement.silence = false')
|
||||||
.andWhere(new Brackets(qb => {
|
.andWhere(new Brackets(qb => {
|
||||||
qb.orWhere('announcement.userId = :userId', { userId: user.id });
|
qb.orWhere('announcement.userId = :userId', { userId: user.id });
|
||||||
qb.orWhere('announcement.userId IS NULL');
|
qb.orWhere('announcement.userId IS NULL');
|
||||||
@ -73,6 +74,7 @@ export class AnnouncementService {
|
|||||||
icon: values.icon,
|
icon: values.icon,
|
||||||
display: values.display,
|
display: values.display,
|
||||||
forExistingUsers: values.forExistingUsers,
|
forExistingUsers: values.forExistingUsers,
|
||||||
|
silence: values.silence,
|
||||||
needConfirmationToRead: values.needConfirmationToRead,
|
needConfirmationToRead: values.needConfirmationToRead,
|
||||||
userId: values.userId,
|
userId: values.userId,
|
||||||
}).then(x => this.announcementsRepository.findOneByOrFail(x.identifiers[0]));
|
}).then(x => this.announcementsRepository.findOneByOrFail(x.identifiers[0]));
|
||||||
@ -124,6 +126,7 @@ export class AnnouncementService {
|
|||||||
display: values.display,
|
display: values.display,
|
||||||
icon: values.icon,
|
icon: values.icon,
|
||||||
forExistingUsers: values.forExistingUsers,
|
forExistingUsers: values.forExistingUsers,
|
||||||
|
silence: values.silence,
|
||||||
needConfirmationToRead: values.needConfirmationToRead,
|
needConfirmationToRead: values.needConfirmationToRead,
|
||||||
isActive: values.isActive,
|
isActive: values.isActive,
|
||||||
});
|
});
|
||||||
@ -210,6 +213,7 @@ export class AnnouncementService {
|
|||||||
icon: announcement.icon,
|
icon: announcement.icon,
|
||||||
display: announcement.display,
|
display: announcement.display,
|
||||||
needConfirmationToRead: announcement.needConfirmationToRead,
|
needConfirmationToRead: announcement.needConfirmationToRead,
|
||||||
|
silence: announcement.silence,
|
||||||
forYou: announcement.userId === me?.id,
|
forYou: announcement.userId === me?.id,
|
||||||
isRead: reads.some(read => read.announcementId === announcement.id),
|
isRead: reads.some(read => read.announcementId === announcement.id),
|
||||||
}));
|
}));
|
||||||
|
@ -269,7 +269,7 @@ export class ApPersonService implements OnModuleInit {
|
|||||||
|
|
||||||
const tags = extractApHashtags(person.tag).map(normalizeForSearch).splice(0, 32);
|
const tags = extractApHashtags(person.tag).map(normalizeForSearch).splice(0, 32);
|
||||||
|
|
||||||
const isBot = getApType(object) === 'Service';
|
const isBot = getApType(object) === 'Service' || getApType(object) === 'Application';
|
||||||
|
|
||||||
const bday = person['vcard:bday']?.match(/^\d{4}-\d{2}-\d{2}/);
|
const bday = person['vcard:bday']?.match(/^\d{4}-\d{2}-\d{2}/);
|
||||||
|
|
||||||
@ -456,7 +456,7 @@ export class ApPersonService implements OnModuleInit {
|
|||||||
emojis: emojiNames,
|
emojis: emojiNames,
|
||||||
name: truncate(person.name, nameLength),
|
name: truncate(person.name, nameLength),
|
||||||
tags,
|
tags,
|
||||||
isBot: getApType(object) === 'Service',
|
isBot: getApType(object) === 'Service' || getApType(object) === 'Application',
|
||||||
isCat: (person as any).isCat === true,
|
isCat: (person as any).isCat === true,
|
||||||
isLocked: person.manuallyApprovesFollowers,
|
isLocked: person.manuallyApprovesFollowers,
|
||||||
movedToUri: person.movedTo ?? null,
|
movedToUri: person.movedTo ?? null,
|
||||||
|
@ -66,6 +66,12 @@ export class MiAnnouncement {
|
|||||||
})
|
})
|
||||||
public forExistingUsers: boolean;
|
public forExistingUsers: boolean;
|
||||||
|
|
||||||
|
@Index()
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
public silence: boolean;
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
@Column({
|
@Column({
|
||||||
...id(),
|
...id(),
|
||||||
|
@ -58,6 +58,7 @@ export const paramDef = {
|
|||||||
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 },
|
||||||
|
silence: { type: 'boolean', default: false },
|
||||||
needConfirmationToRead: { type: 'boolean', default: false },
|
needConfirmationToRead: { type: 'boolean', default: false },
|
||||||
userId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
|
userId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
|
||||||
},
|
},
|
||||||
@ -78,6 +79,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||||||
icon: ps.icon,
|
icon: ps.icon,
|
||||||
display: ps.display,
|
display: ps.display,
|
||||||
forExistingUsers: ps.forExistingUsers,
|
forExistingUsers: ps.forExistingUsers,
|
||||||
|
silence: ps.silence,
|
||||||
needConfirmationToRead: ps.needConfirmationToRead,
|
needConfirmationToRead: ps.needConfirmationToRead,
|
||||||
userId: ps.userId,
|
userId: ps.userId,
|
||||||
}, me);
|
}, me);
|
||||||
|
@ -86,6 +86,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(meta, paramDef, async (ps, me) => {
|
||||||
const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId);
|
const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId);
|
||||||
|
query.andWhere('announcement.isActive = true');
|
||||||
if (ps.userId) {
|
if (ps.userId) {
|
||||||
query.andWhere('announcement.userId = :userId', { userId: ps.userId });
|
query.andWhere('announcement.userId = :userId', { userId: ps.userId });
|
||||||
} else {
|
} else {
|
||||||
@ -113,6 +114,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||||||
display: announcement.display,
|
display: announcement.display,
|
||||||
isActive: announcement.isActive,
|
isActive: announcement.isActive,
|
||||||
forExistingUsers: announcement.forExistingUsers,
|
forExistingUsers: announcement.forExistingUsers,
|
||||||
|
silence: announcement.silence,
|
||||||
needConfirmationToRead: announcement.needConfirmationToRead,
|
needConfirmationToRead: announcement.needConfirmationToRead,
|
||||||
userId: announcement.userId,
|
userId: announcement.userId,
|
||||||
reads: reads.get(announcement)!,
|
reads: reads.get(announcement)!,
|
||||||
|
@ -35,6 +35,7 @@ export const paramDef = {
|
|||||||
icon: { type: 'string', enum: ['info', 'warning', 'error', 'success'] },
|
icon: { type: 'string', enum: ['info', 'warning', 'error', 'success'] },
|
||||||
display: { type: 'string', enum: ['normal', 'banner', 'dialog'] },
|
display: { type: 'string', enum: ['normal', 'banner', 'dialog'] },
|
||||||
forExistingUsers: { type: 'boolean' },
|
forExistingUsers: { type: 'boolean' },
|
||||||
|
silence: { type: 'boolean' },
|
||||||
needConfirmationToRead: { type: 'boolean' },
|
needConfirmationToRead: { type: 'boolean' },
|
||||||
isActive: { type: 'boolean' },
|
isActive: { type: 'boolean' },
|
||||||
},
|
},
|
||||||
@ -63,6 +64,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||||||
display: ps.display,
|
display: ps.display,
|
||||||
icon: ps.icon,
|
icon: ps.icon,
|
||||||
forExistingUsers: ps.forExistingUsers,
|
forExistingUsers: ps.forExistingUsers,
|
||||||
|
silence: ps.silence,
|
||||||
needConfirmationToRead: ps.needConfirmationToRead,
|
needConfirmationToRead: ps.needConfirmationToRead,
|
||||||
isActive: ps.isActive,
|
isActive: ps.isActive,
|
||||||
}, me);
|
}, me);
|
||||||
|
@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<template>
|
<template>
|
||||||
<div class="_gaps">
|
<div class="_gaps">
|
||||||
<div style="text-align: center; padding: 0 16px;">{{ i18n.ts._initialTutorial._postNote.description1 }}</div>
|
<div style="text-align: center; padding: 0 16px;">{{ i18n.ts._initialTutorial._postNote.description1 }}</div>
|
||||||
<MkPostForm :class="$style.exampleRoot" :mock="true"/>
|
<MkPostForm :class="$style.exampleRoot" :mock="true" :autofocus="false"/>
|
||||||
<MkFormSection>
|
<MkFormSection>
|
||||||
<template #label>{{ i18n.ts.visibility }}</template>
|
<template #label>{{ i18n.ts.visibility }}</template>
|
||||||
<div class="_gaps">
|
<div class="_gaps">
|
||||||
|
@ -11,6 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<MkPostForm
|
<MkPostForm
|
||||||
:class="$style.exampleRoot"
|
:class="$style.exampleRoot"
|
||||||
:mock="true"
|
:mock="true"
|
||||||
|
:autofocus="false"
|
||||||
:initialNote="exampleNote"
|
:initialNote="exampleNote"
|
||||||
@fileChangeSensitive="doSucceeded"
|
@fileChangeSensitive="doSucceeded"
|
||||||
></MkPostForm>
|
></MkPostForm>
|
||||||
|
@ -48,6 +48,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<MkSwitch v-model="announcement.forExistingUsers" :helpText="i18n.ts._announcement.forExistingUsersDescription">
|
<MkSwitch v-model="announcement.forExistingUsers" :helpText="i18n.ts._announcement.forExistingUsersDescription">
|
||||||
{{ i18n.ts._announcement.forExistingUsers }}
|
{{ i18n.ts._announcement.forExistingUsers }}
|
||||||
</MkSwitch>
|
</MkSwitch>
|
||||||
|
<MkSwitch v-model="announcement.silence" :helpText="i18n.ts._announcement.silenceDescription">
|
||||||
|
{{ i18n.ts._announcement.silence }}
|
||||||
|
</MkSwitch>
|
||||||
<MkSwitch v-model="announcement.needConfirmationToRead" :helpText="i18n.ts._announcement.needConfirmationToReadDescription">
|
<MkSwitch v-model="announcement.needConfirmationToRead" :helpText="i18n.ts._announcement.needConfirmationToReadDescription">
|
||||||
{{ i18n.ts._announcement.needConfirmationToRead }}
|
{{ i18n.ts._announcement.needConfirmationToRead }}
|
||||||
</MkSwitch>
|
</MkSwitch>
|
||||||
@ -97,6 +100,7 @@ function add() {
|
|||||||
icon: 'info',
|
icon: 'info',
|
||||||
display: 'normal',
|
display: 'normal',
|
||||||
forExistingUsers: false,
|
forExistingUsers: false,
|
||||||
|
silence: false,
|
||||||
needConfirmationToRead: false,
|
needConfirmationToRead: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<section v-for="announcement in items" :key="announcement.id" class="_panel" :class="$style.announcement">
|
<section v-for="announcement in items" :key="announcement.id" class="_panel" :class="$style.announcement">
|
||||||
<div v-if="announcement.forYou" :class="$style.forYou"><i class="ti ti-pin"></i> {{ i18n.ts.forYou }}</div>
|
<div v-if="announcement.forYou" :class="$style.forYou"><i class="ti ti-pin"></i> {{ i18n.ts.forYou }}</div>
|
||||||
<div :class="$style.header">
|
<div :class="$style.header">
|
||||||
<span v-if="$i && !announcement.isRead" style="margin-right: 0.5em;">🆕</span>
|
<span v-if="$i && !announcement.silence && !announcement.isRead" style="margin-right: 0.5em;">🆕</span>
|
||||||
<span style="margin-right: 0.5em;">
|
<span style="margin-right: 0.5em;">
|
||||||
<i v-if="announcement.icon === 'info'" class="ti ti-info-circle"></i>
|
<i v-if="announcement.icon === 'info'" class="ti ti-info-circle"></i>
|
||||||
<i v-else-if="announcement.icon === 'warning'" class="ti ti-alert-triangle" style="color: var(--warn);"></i>
|
<i v-else-if="announcement.icon === 'warning'" class="ti ti-alert-triangle" style="color: var(--warn);"></i>
|
||||||
@ -29,7 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<MkTime :time="announcement.updatedAt ?? announcement.createdAt" mode="detail"/>
|
<MkTime :time="announcement.updatedAt ?? announcement.createdAt" mode="detail"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="tab !== 'past' && $i && !announcement.isRead" :class="$style.footer">
|
<div v-if="tab !== 'past' && $i && !announcement.silence && !announcement.isRead" :class="$style.footer">
|
||||||
<MkButton primary @click="read(announcement)"><i class="ti ti-check"></i> {{ i18n.ts.gotIt }}</MkButton>
|
<MkButton primary @click="read(announcement)"><i class="ti ti-check"></i> {{ i18n.ts.gotIt }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -94,7 +94,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
:class="[$style.avatarDecoration, { [$style.avatarDecorationActive]: $i.avatarDecorations.some(x => x.id === avatarDecoration.id) }]"
|
:class="[$style.avatarDecoration, { [$style.avatarDecorationActive]: $i.avatarDecorations.some(x => x.id === avatarDecoration.id) }]"
|
||||||
@click="openDecoration(avatarDecoration)"
|
@click="openDecoration(avatarDecoration)"
|
||||||
>
|
>
|
||||||
<div :class="$style.avatarDecorationName"><MkCondensedLine :minScale="2 / 3">{{ avatarDecoration.name }}</MkCondensedLine></div>
|
<div :class="$style.avatarDecorationName"><MkCondensedLine :minScale="0.5">{{ avatarDecoration.name }}</MkCondensedLine></div>
|
||||||
<MkAvatar style="width: 60px; height: 60px;" :user="$i" :decoration="{ url: avatarDecoration.url }" forceShowDecoration/>
|
<MkAvatar style="width: 60px; height: 60px;" :user="$i" :decoration="{ url: avatarDecoration.url }" forceShowDecoration/>
|
||||||
<i v-if="avatarDecoration.roleIdsThatCanBeUsedThisDecoration.length > 0 && !$i.roles.some(r => avatarDecoration.roleIdsThatCanBeUsedThisDecoration.includes(r.id))" :class="$style.avatarDecorationLock" class="ti ti-lock"></i>
|
<i v-if="avatarDecoration.roleIdsThatCanBeUsedThisDecoration.length > 0 && !$i.roles.some(r => avatarDecoration.roleIdsThatCanBeUsedThisDecoration.includes(r.id))" :class="$style.avatarDecorationLock" class="ti ti-lock"></i>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user