Compare commits
5 Commits
8a6791da3f
...
b43906705c
Author | SHA1 | Date |
---|---|---|
|
b43906705c | |
|
e11320dbb7 | |
|
2217a3c549 | |
|
c5b8766a18 | |
|
79966d33b5 |
|
@ -165,8 +165,8 @@ proxyBypassHosts:
|
||||||
# Media Proxy
|
# Media Proxy
|
||||||
#mediaProxy: https://example.com/proxy
|
#mediaProxy: https://example.com/proxy
|
||||||
|
|
||||||
# Proxy remote files (default: false)
|
# Proxy remote files (default: true)
|
||||||
#proxyRemoteFiles: true
|
proxyRemoteFiles: true
|
||||||
|
|
||||||
# Sign to ActivityPub GET request (default: true)
|
# Sign to ActivityPub GET request (default: true)
|
||||||
signToActivityPubGet: true
|
signToActivityPubGet: true
|
||||||
|
|
|
@ -183,9 +183,9 @@ proxyBypassHosts:
|
||||||
# * Perform image compression (on a different server resource than the main process)
|
# * Perform image compression (on a different server resource than the main process)
|
||||||
#mediaProxy: https://example.com/proxy
|
#mediaProxy: https://example.com/proxy
|
||||||
|
|
||||||
# Proxy remote files (default: false)
|
# Proxy remote files (default: true)
|
||||||
# Proxy remote files by this instance or mediaProxy to prevent remote files from running in remote domains.
|
# Proxy remote files by this instance or mediaProxy to prevent remote files from running in remote domains.
|
||||||
#proxyRemoteFiles: true
|
proxyRemoteFiles: true
|
||||||
|
|
||||||
# Movie Thumbnail Generation URL
|
# Movie Thumbnail Generation URL
|
||||||
# There is no reference implementation.
|
# There is no reference implementation.
|
||||||
|
|
|
@ -165,8 +165,8 @@ proxyBypassHosts:
|
||||||
# Media Proxy
|
# Media Proxy
|
||||||
#mediaProxy: https://example.com/proxy
|
#mediaProxy: https://example.com/proxy
|
||||||
|
|
||||||
# Proxy remote files (default: false)
|
# Proxy remote files (default: true)
|
||||||
#proxyRemoteFiles: true
|
proxyRemoteFiles: true
|
||||||
|
|
||||||
# Sign to ActivityPub GET request (default: true)
|
# Sign to ActivityPub GET request (default: true)
|
||||||
signToActivityPubGet: true
|
signToActivityPubGet: true
|
||||||
|
|
|
@ -16,16 +16,18 @@
|
||||||
|
|
||||||
### General
|
### General
|
||||||
- OAuth 2.0のサポート
|
- OAuth 2.0のサポート
|
||||||
|
- チャンネルをセンシティブ指定できるようになりました
|
||||||
|
|
||||||
### Client
|
### Client
|
||||||
- メニューのスイッチの動作を改善
|
- メニューのスイッチの動作を改善
|
||||||
|
- 絵文字ピッカーの検索の表示件数を100件に増加
|
||||||
- Enhance: ユーザーメニューでスイッチでユーザーリストに追加・削除できるように
|
- Enhance: ユーザーメニューでスイッチでユーザーリストに追加・削除できるように
|
||||||
- Enhance: 自分が押したリアクションのデザインを改善
|
- Enhance: 自分が押したリアクションのデザインを改善
|
||||||
- Fix: サーバー情報画面(`/instance-info/{domain}`)でブロックができないのを修正
|
- Fix: サーバー情報画面(`/instance-info/{domain}`)でブロックができないのを修正
|
||||||
- Fix: 未読のお知らせの「わかった」をクリック・タップしてもその場で「わかった」が消えない問題を修正
|
- Fix: 未読のお知らせの「わかった」をクリック・タップしてもその場で「わかった」が消えない問題を修正
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
-
|
- cacheRemoteFilesの初期値はfalseになりました
|
||||||
|
|
||||||
## 13.14.2
|
## 13.14.2
|
||||||
|
|
||||||
|
|
|
@ -159,6 +159,7 @@ export interface Locale {
|
||||||
"settingGuide": string;
|
"settingGuide": string;
|
||||||
"cacheRemoteFiles": string;
|
"cacheRemoteFiles": string;
|
||||||
"cacheRemoteFilesDescription": string;
|
"cacheRemoteFilesDescription": string;
|
||||||
|
"youCanCleanRemoteFilesCache": string;
|
||||||
"cacheRemoteSensitiveFiles": string;
|
"cacheRemoteSensitiveFiles": string;
|
||||||
"cacheRemoteSensitiveFilesDescription": string;
|
"cacheRemoteSensitiveFilesDescription": string;
|
||||||
"flagAsBot": string;
|
"flagAsBot": string;
|
||||||
|
|
|
@ -155,7 +155,8 @@ emojiUrl: "絵文字画像URL"
|
||||||
addEmoji: "絵文字を追加"
|
addEmoji: "絵文字を追加"
|
||||||
settingGuide: "おすすめ設定"
|
settingGuide: "おすすめ設定"
|
||||||
cacheRemoteFiles: "リモートのファイルをキャッシュする"
|
cacheRemoteFiles: "リモートのファイルをキャッシュする"
|
||||||
cacheRemoteFilesDescription: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクするようになります。サーバーのストレージを節約できますが、サムネイルが生成されないので通信量が増加します。"
|
cacheRemoteFilesDescription: "この設定を有効にすると、リモートファイルをこのサーバーのストレージにキャッシュするようになります。画像の表示が高速になりますが、サーバーのストレージを多く消費します。リモートユーザーがどれほどキャッシュを保持するかは、ロールによるドライブ容量制限によって決定されます。この制限を超えた場合、古いファイルからキャッシュが削除されリンクになります。この設定が無効の場合、リモートのファイルを最初からリンクとして保持しますが、画像のサムネイル生成やユーザーのプライバシー保護のために、default.ymlでproxyRemoteFilesをtrueにすることをお勧めします。"
|
||||||
|
youCanCleanRemoteFilesCache: "ファイル管理の🗑️ボタンで全てのキャッシュを削除できます。"
|
||||||
cacheRemoteSensitiveFiles: "リモートのセンシティブなファイルをキャッシュする"
|
cacheRemoteSensitiveFiles: "リモートのセンシティブなファイルをキャッシュする"
|
||||||
cacheRemoteSensitiveFilesDescription: "この設定を無効にすると、リモートのセンシティブなファイルはキャッシュせず直リンクするようになります。"
|
cacheRemoteSensitiveFilesDescription: "この設定を無効にすると、リモートのセンシティブなファイルはキャッシュせず直リンクするようになります。"
|
||||||
flagAsBot: "Botとして設定"
|
flagAsBot: "Botとして設定"
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
export class ChangeCacheRemoteFilesDefault1690417561186 {
|
||||||
|
name = 'ChangeCacheRemoteFilesDefault1690417561186'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "cacheRemoteFiles" SET DEFAULT false`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "cacheRemoteFiles" SET DEFAULT true`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
export class Fix1690417561187 {
|
||||||
|
name = 'Fix1690417561187'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_2cd3b2a6b4cf0b910b260afe08"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_renote_muting_createdAt"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_renote_muting_muteeId"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_renote_muting_muterId"`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "user"."isRoot" IS 'Whether the User is the root.'`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "ad"."startsAt" IS 'The expired date of the Ad.'`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "lastUsedAt" DROP DEFAULT`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "mascotImageUrl" DROP DEFAULT`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "preservedUsernames" SET DEFAULT '{ "admin", "administrator", "root", "system", "maintainer", "host", "mod", "moderator", "owner", "superuser", "staff", "auth", "i", "me", "everyone", "all", "mention", "mentions", "example", "user", "users", "account", "accounts", "official", "help", "helps", "support", "supports", "info", "information", "informations", "announce", "announces", "announcement", "announcements", "notice", "notification", "notifications", "dev", "developer", "developers", "tech", "misskey" }'`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "renote_muting"."createdAt" IS 'The created date of the Muting.'`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "renote_muting"."muteeId" IS 'The mutee user ID.'`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "renote_muting"."muterId" IS 'The muter user ID.'`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "poll" DROP CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "poll" DROP CONSTRAINT "UQ_da851e06d0dfe2ef397d8b1bf1b"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "promo_note" DROP CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "promo_note" DROP CONSTRAINT "UQ_e263909ca4fe5d57f8d4230dd5c"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_keypair" DROP CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_keypair" DROP CONSTRAINT "UQ_f4853eb41ab722fe05f81cedeb6"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "UQ_51cb79b5555effaf7d69ba1cff9"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "FK_10c146e4b39b443ede016f6736d"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "UQ_10c146e4b39b443ede016f6736d"`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_3fcc2c589eaefc205e0714b99c" ON "ad" ("startsAt") `);
|
||||||
|
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_c71faf11f0a28a5c0bb506203c" ON "channel_favorite" ("userId", "channelId") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_f7b9d338207e40e768e4a5265a" ON "instance" ("firstRetrievedAt") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_d1259a2c2b7bb413ff449e8711" ON "renote_muting" ("createdAt") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_7eac97594bcac5ffcf2068089b" ON "renote_muting" ("muteeId") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_7aa72a5fe76019bfe8e5e0e8b7" ON "renote_muting" ("muterId") `);
|
||||||
|
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0d801c609cec4e9eb4b6b4490c" ON "renote_muting" ("muterId", "muteeId") `);
|
||||||
|
await queryRunner.query(`ALTER TABLE "renote_muting" ADD CONSTRAINT "FK_7eac97594bcac5ffcf2068089b6" FOREIGN KEY ("muteeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "renote_muting" ADD CONSTRAINT "FK_7aa72a5fe76019bfe8e5e0e8b7d" FOREIGN KEY ("muterId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "poll" ADD CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "promo_note" ADD CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_keypair" ADD CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "FK_10c146e4b39b443ede016f6736d" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "FK_10c146e4b39b443ede016f6736d"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_keypair" DROP CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "promo_note" DROP CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "poll" DROP CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "renote_muting" DROP CONSTRAINT "FK_7aa72a5fe76019bfe8e5e0e8b7d"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "renote_muting" DROP CONSTRAINT "FK_7eac97594bcac5ffcf2068089b6"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_0d801c609cec4e9eb4b6b4490c"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_7aa72a5fe76019bfe8e5e0e8b7"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_7eac97594bcac5ffcf2068089b"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_d1259a2c2b7bb413ff449e8711"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_f7b9d338207e40e768e4a5265a"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_c71faf11f0a28a5c0bb506203c"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_3fcc2c589eaefc205e0714b99c"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "UQ_10c146e4b39b443ede016f6736d" UNIQUE ("userId")`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "FK_10c146e4b39b443ede016f6736d" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "UQ_51cb79b5555effaf7d69ba1cff9" UNIQUE ("userId")`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_keypair" ADD CONSTRAINT "UQ_f4853eb41ab722fe05f81cedeb6" UNIQUE ("userId")`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "user_keypair" ADD CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "promo_note" ADD CONSTRAINT "UQ_e263909ca4fe5d57f8d4230dd5c" UNIQUE ("noteId")`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "promo_note" ADD CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "poll" ADD CONSTRAINT "UQ_da851e06d0dfe2ef397d8b1bf1b" UNIQUE ("noteId")`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "poll" ADD CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "renote_muting"."muterId" IS NULL`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "renote_muting"."muteeId" IS NULL`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "renote_muting"."createdAt" IS NULL`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "preservedUsernames" SET DEFAULT '{admin,administrator,root,system,maintainer,host,mod,moderator,owner,superuser,staff,auth,i,me,everyone,all,mention,mentions,example,user,users,account,accounts,official,help,helps,support,supports,info,information,informations,announce,announces,announcement,announcements,notice,notification,notifications,dev,developer,developers,tech,misskey}'`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "mascotImageUrl" SET DEFAULT '/assets/ai.png'`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "lastUsedAt" SET DEFAULT '2023-04-25 06:51:20.985478+00'`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "ad"."startsAt" IS NULL`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "user"."isRoot" IS 'Whether the User is the admin.'`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_renote_muting_muterId" ON "muting" ("muterId") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_renote_muting_muteeId" ON "muting" ("muteeId") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_renote_muting_createdAt" ON "muting" ("createdAt") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_2cd3b2a6b4cf0b910b260afe08" ON "instance" ("firstRetrievedAt") `);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class SensitiveChannel1690782653311 {
|
||||||
|
name = 'SensitiveChannel1690782653311'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "channel"
|
||||||
|
ADD "isSensitive" boolean NOT NULL DEFAULT false`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "channel" DROP COLUMN "isSensitive"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -332,7 +332,7 @@ export class DriveService {
|
||||||
this.registerLogger.debug('web image not created (not an required image)');
|
this.registerLogger.debug('web image not created (not an required image)');
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.registerLogger.warn('web image not created (an error occured)', err as Error);
|
this.registerLogger.warn('web image not created (an error occurred)', err as Error);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (satisfyWebpublic) this.registerLogger.info('web image not created (original satisfies webpublic)');
|
if (satisfyWebpublic) this.registerLogger.info('web image not created (original satisfies webpublic)');
|
||||||
|
@ -351,7 +351,7 @@ export class DriveService {
|
||||||
thumbnail = await this.imageProcessingService.convertSharpToWebp(img, 498, 422);
|
thumbnail = await this.imageProcessingService.convertSharpToWebp(img, 498, 422);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.registerLogger.warn('thumbnail not created (an error occured)', err as Error);
|
this.registerLogger.warn('thumbnail not created (an error occurred)', err as Error);
|
||||||
}
|
}
|
||||||
// #endregion thumbnail
|
// #endregion thumbnail
|
||||||
|
|
||||||
|
|
|
@ -286,7 +286,7 @@ export class ApPersonService implements OnModuleInit {
|
||||||
const emojis = await this.apNoteService.extractEmojis(person.tag ?? [], host)
|
const emojis = await this.apNoteService.extractEmojis(person.tag ?? [], host)
|
||||||
.then(_emojis => _emojis.map(emoji => emoji.name))
|
.then(_emojis => _emojis.map(emoji => emoji.name))
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
this.logger.error('error occured while fetching user emojis', { stack: err });
|
this.logger.error('error occurred while fetching user emojis', { stack: err });
|
||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
//#endregion
|
//#endregion
|
||||||
|
@ -380,7 +380,7 @@ export class ApPersonService implements OnModuleInit {
|
||||||
// Register to the cache
|
// Register to the cache
|
||||||
this.cacheService.uriPersonCache.set(user.uri, user);
|
this.cacheService.uriPersonCache.set(user.uri, user);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error('error occured while fetching user avatar/banner', { stack: err });
|
this.logger.error('error occurred while fetching user avatar/banner', { stack: err });
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,7 @@ export class ChannelEntityService {
|
||||||
isArchived: channel.isArchived,
|
isArchived: channel.isArchived,
|
||||||
usersCount: channel.usersCount,
|
usersCount: channel.usersCount,
|
||||||
notesCount: channel.notesCount,
|
notesCount: channel.notesCount,
|
||||||
|
isSensitive: channel.isSensitive,
|
||||||
|
|
||||||
...(me ? {
|
...(me ? {
|
||||||
isFollowing,
|
isFollowing,
|
||||||
|
|
|
@ -333,6 +333,7 @@ export class NoteEntityService implements OnModuleInit {
|
||||||
id: channel.id,
|
id: channel.id,
|
||||||
name: channel.name,
|
name: channel.name,
|
||||||
color: channel.color,
|
color: channel.color,
|
||||||
|
isSensitive: channel.isSensitive,
|
||||||
} : undefined,
|
} : undefined,
|
||||||
mentions: note.mentions.length > 0 ? note.mentions : undefined,
|
mentions: note.mentions.length > 0 ? note.mentions : undefined,
|
||||||
uri: note.uri ?? undefined,
|
uri: note.uri ?? undefined,
|
||||||
|
|
|
@ -94,4 +94,9 @@ export class Channel {
|
||||||
comment: 'The count of users.',
|
comment: 'The count of users.',
|
||||||
})
|
})
|
||||||
public usersCount: number;
|
public usersCount: number;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
public isSensitive: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ export class Meta {
|
||||||
public infoImageUrl: string | null;
|
public infoImageUrl: string | null;
|
||||||
|
|
||||||
@Column('boolean', {
|
@Column('boolean', {
|
||||||
default: true,
|
default: false,
|
||||||
})
|
})
|
||||||
public cacheRemoteFiles: boolean;
|
public cacheRemoteFiles: boolean;
|
||||||
|
|
||||||
|
|
|
@ -72,5 +72,9 @@ export const packedChannelSchema = {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
|
isSensitive: {
|
||||||
|
type: 'boolean',
|
||||||
|
optional: false, nullable: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -139,6 +139,10 @@ export const packedNoteSchema = {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: false, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
|
isSensitive: {
|
||||||
|
type: 'boolean',
|
||||||
|
optional: true, nullable: false,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -49,6 +49,7 @@ export const paramDef = {
|
||||||
description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 },
|
description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 },
|
||||||
bannerId: { type: 'string', format: 'misskey:id', nullable: true },
|
bannerId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||||
color: { type: 'string', minLength: 1, maxLength: 16 },
|
color: { type: 'string', minLength: 1, maxLength: 16 },
|
||||||
|
isSensitive: { type: 'boolean', nullable: true },
|
||||||
},
|
},
|
||||||
required: ['name'],
|
required: ['name'],
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -86,6 +87,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
name: ps.name,
|
name: ps.name,
|
||||||
description: ps.description ?? null,
|
description: ps.description ?? null,
|
||||||
bannerId: banner ? banner.id : null,
|
bannerId: banner ? banner.id : null,
|
||||||
|
isSensitive: ps.isSensitive ?? false,
|
||||||
...(ps.color !== undefined ? { color: ps.color } : {}),
|
...(ps.color !== undefined ? { color: ps.color } : {}),
|
||||||
} as Channel).then(x => this.channelsRepository.findOneByOrFail(x.identifiers[0]));
|
} as Channel).then(x => this.channelsRepository.findOneByOrFail(x.identifiers[0]));
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ export const paramDef = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
color: { type: 'string', minLength: 1, maxLength: 16 },
|
color: { type: 'string', minLength: 1, maxLength: 16 },
|
||||||
|
isSensitive: { type: 'boolean', nullable: true },
|
||||||
},
|
},
|
||||||
required: ['channelId'],
|
required: ['channelId'],
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -114,6 +115,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
...(ps.color !== undefined ? { color: ps.color } : {}),
|
...(ps.color !== undefined ? { color: ps.color } : {}),
|
||||||
...(typeof ps.isArchived === 'boolean' ? { isArchived: ps.isArchived } : {}),
|
...(typeof ps.isArchived === 'boolean' ? { isArchived: ps.isArchived } : {}),
|
||||||
...(banner ? { bannerId: banner.id } : {}),
|
...(banner ? { bannerId: banner.id } : {}),
|
||||||
|
...(typeof ps.isSensitive === 'boolean' ? { isSensitive: ps.isSensitive } : {}),
|
||||||
});
|
});
|
||||||
|
|
||||||
return await this.channelEntityService.pack(channel.id, me);
|
return await this.channelEntityService.pack(channel.id, me);
|
||||||
|
|
|
@ -682,7 +682,7 @@ export class ClientServerService {
|
||||||
|
|
||||||
fastify.setErrorHandler(async (error, request, reply) => {
|
fastify.setErrorHandler(async (error, request, reply) => {
|
||||||
const errId = randomUUID();
|
const errId = randomUUID();
|
||||||
this.clientLoggerService.logger.error(`Internal error occured in ${request.routerPath}: ${error.message}`, {
|
this.clientLoggerService.logger.error(`Internal error occurred in ${request.routerPath}: ${error.message}`, {
|
||||||
path: request.routerPath,
|
path: request.routerPath,
|
||||||
params: request.params,
|
params: request.params,
|
||||||
query: request.query,
|
query: request.query,
|
||||||
|
|
|
@ -8,6 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div class="banner" :style="bannerStyle">
|
<div class="banner" :style="bannerStyle">
|
||||||
<div class="fade"></div>
|
<div class="fade"></div>
|
||||||
<div class="name"><i class="ti ti-device-tv"></i> {{ channel.name }}</div>
|
<div class="name"><i class="ti ti-device-tv"></i> {{ channel.name }}</div>
|
||||||
|
<div v-if="channel.isSensitive" class="sensitiveIndicator">{{ i18n.ts.sensitive }}</div>
|
||||||
<div class="status">
|
<div class="status">
|
||||||
<div>
|
<div>
|
||||||
<i class="ti ti-users ti-fw"></i>
|
<i class="ti ti-users ti-fw"></i>
|
||||||
|
@ -102,6 +103,19 @@ const bannerStyle = computed(() => {
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> .sensitiveIndicator {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
bottom: 16px;
|
||||||
|
left: 16px;
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
color: var(--warn);
|
||||||
|
border-radius: 6px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1em;
|
||||||
|
padding: 4px 7px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> article {
|
> article {
|
||||||
|
|
|
@ -156,7 +156,7 @@ watch(q, () => {
|
||||||
const newQ = q.value.replace(/:/g, '').toLowerCase();
|
const newQ = q.value.replace(/:/g, '').toLowerCase();
|
||||||
|
|
||||||
const searchCustom = () => {
|
const searchCustom = () => {
|
||||||
const max = 8;
|
const max = 100;
|
||||||
const emojis = customEmojis.value;
|
const emojis = customEmojis.value;
|
||||||
const matches = new Set<Misskey.entities.CustomEmoji>();
|
const matches = new Set<Misskey.entities.CustomEmoji>();
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ watch(q, () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const searchUnicode = () => {
|
const searchUnicode = () => {
|
||||||
const max = 8;
|
const max = 100;
|
||||||
const emojis = emojilist;
|
const emojis = emojilist;
|
||||||
const matches = new Set<UnicodeEmojiDef>();
|
const matches = new Set<UnicodeEmojiDef>();
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<MkSwitch v-model="cacheRemoteFiles">
|
<MkSwitch v-model="cacheRemoteFiles">
|
||||||
<template #label>{{ i18n.ts.cacheRemoteFiles }}</template>
|
<template #label>{{ i18n.ts.cacheRemoteFiles }}</template>
|
||||||
<template #caption>{{ i18n.ts.cacheRemoteFilesDescription }}</template>
|
<template #caption>{{ i18n.ts.cacheRemoteFilesDescription }}{{ i18n.ts.youCanCleanRemoteFilesCache }}</template>
|
||||||
</MkSwitch>
|
</MkSwitch>
|
||||||
|
|
||||||
<template v-if="cacheRemoteFiles">
|
<template v-if="cacheRemoteFiles">
|
||||||
|
|
|
@ -20,6 +20,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<template #label>{{ i18n.ts.color }}</template>
|
<template #label>{{ i18n.ts.color }}</template>
|
||||||
</MkColorInput>
|
</MkColorInput>
|
||||||
|
|
||||||
|
<MkSwitch v-model="isSensitive">
|
||||||
|
<template #label>{{ i18n.ts.sensitive }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<MkButton v-if="bannerId == null" @click="setBannerImage"><i class="ti ti-plus"></i> {{ i18n.ts._channel.setBanner }}</MkButton>
|
<MkButton v-if="bannerId == null" @click="setBannerImage"><i class="ti ti-plus"></i> {{ i18n.ts._channel.setBanner }}</MkButton>
|
||||||
<div v-else-if="bannerUrl">
|
<div v-else-if="bannerUrl">
|
||||||
|
@ -72,6 +76,7 @@ import { useRouter } from '@/router';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import MkFolder from '@/components/MkFolder.vue';
|
import MkFolder from '@/components/MkFolder.vue';
|
||||||
|
import MkSwitch from "@/components/MkSwitch.vue";
|
||||||
|
|
||||||
const Sortable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default));
|
const Sortable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default));
|
||||||
|
|
||||||
|
@ -87,6 +92,7 @@ let description = $ref(null);
|
||||||
let bannerUrl = $ref<string | null>(null);
|
let bannerUrl = $ref<string | null>(null);
|
||||||
let bannerId = $ref<string | null>(null);
|
let bannerId = $ref<string | null>(null);
|
||||||
let color = $ref('#000');
|
let color = $ref('#000');
|
||||||
|
let isSensitive = $ref(false);
|
||||||
const pinnedNotes = ref([]);
|
const pinnedNotes = ref([]);
|
||||||
|
|
||||||
watch(() => bannerId, async () => {
|
watch(() => bannerId, async () => {
|
||||||
|
@ -110,6 +116,7 @@ async function fetchChannel() {
|
||||||
description = channel.description;
|
description = channel.description;
|
||||||
bannerId = channel.bannerId;
|
bannerId = channel.bannerId;
|
||||||
bannerUrl = channel.bannerUrl;
|
bannerUrl = channel.bannerUrl;
|
||||||
|
isSensitive = channel.isSensitive;
|
||||||
pinnedNotes.value = channel.pinnedNoteIds.map(id => ({
|
pinnedNotes.value = channel.pinnedNoteIds.map(id => ({
|
||||||
id,
|
id,
|
||||||
}));
|
}));
|
||||||
|
@ -142,6 +149,7 @@ function save() {
|
||||||
bannerId: bannerId,
|
bannerId: bannerId,
|
||||||
pinnedNoteIds: pinnedNotes.value.map(x => x.id),
|
pinnedNoteIds: pinnedNotes.value.map(x => x.id),
|
||||||
color: color,
|
color: color,
|
||||||
|
isSensitive: isSensitive,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (props.channelId) {
|
if (props.channelId) {
|
||||||
|
|
|
@ -17,6 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div><i class="ti ti-users ti-fw"></i><I18n :src="i18n.ts._channel.usersCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.usersCount }}</b></template></I18n></div>
|
<div><i class="ti ti-users ti-fw"></i><I18n :src="i18n.ts._channel.usersCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.usersCount }}</b></template></I18n></div>
|
||||||
<div><i class="ti ti-pencil ti-fw"></i><I18n :src="i18n.ts._channel.notesCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.notesCount }}</b></template></I18n></div>
|
<div><i class="ti ti-pencil ti-fw"></i><I18n :src="i18n.ts._channel.notesCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.notesCount }}</b></template></I18n></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="channel.isSensitive" :class="$style.sensitiveIndicator">{{ i18n.ts.sensitive }}</div>
|
||||||
<div :class="$style.bannerFade"></div>
|
<div :class="$style.bannerFade"></div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="channel.description" :class="$style.description">
|
<div v-if="channel.description" :class="$style.description">
|
||||||
|
@ -274,4 +275,17 @@ definePageMetadata(computed(() => channel ? {
|
||||||
.description {
|
.description {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sensitiveIndicator {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
bottom: 16px;
|
||||||
|
left: 16px;
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
color: var(--warn);
|
||||||
|
border-radius: 6px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1em;
|
||||||
|
padding: 4px 7px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in New Issue