From ff189ea9a75be32c066d8801a19ae7f818616a9a Mon Sep 17 00:00:00 2001 From: mattyatea Date: Thu, 21 Nov 2024 00:45:48 +0900 Subject: [PATCH 1/6] =?UTF-8?q?Enhance(Page):=20=E3=83=9A=E3=83=BC?= =?UTF-8?q?=E3=82=B8=E3=82=92=E9=9D=9E=E5=85=AC=E9=96=8B=E3=81=AB=E3=81=A7?= =?UTF-8?q?=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/index.d.ts | 4 ++++ locales/ja-JP.yml | 1 + .../migration/1731806320819-pageIsPublic.js | 21 +++++++++++++++++++ .../src/core/entities/PageEntityService.ts | 1 + packages/backend/src/models/Page.ts | 15 +++---------- .../src/server/api/endpoints/pages/create.ts | 3 ++- .../server/api/endpoints/pages/featured.ts | 2 +- .../src/server/api/endpoints/pages/show.ts | 4 ++++ .../src/server/api/endpoints/pages/update.ts | 2 ++ .../src/server/api/endpoints/users/pages.ts | 2 +- .../src/pages/page-editor/page-editor.vue | 5 +++++ 11 files changed, 45 insertions(+), 15 deletions(-) create mode 100644 packages/backend/migration/1731806320819-pageIsPublic.js diff --git a/locales/index.d.ts b/locales/index.d.ts index eba90728a1d0..7bae7cea4f27 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -5318,6 +5318,10 @@ export interface Locale extends ILocale { * 選択した項目のみ許可 */ "consentSelected": string; + /** + * 公開 + */ + "isPublic": string; "_bubbleGame": { /** * 遊び方 diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 746854467de4..11acdaa61937 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1323,6 +1323,7 @@ pleaseConsentToTracking: "{host}は[プライバシーポリシー]({privacyPoli consentEssential: "必須項目のみ許可" consentAll: "全て許可" consentSelected: "選択した項目のみ許可" +isPublic: "公開" _bubbleGame: howToPlay: "遊び方" diff --git a/packages/backend/migration/1731806320819-pageIsPublic.js b/packages/backend/migration/1731806320819-pageIsPublic.js new file mode 100644 index 000000000000..e4a780e7b998 --- /dev/null +++ b/packages/backend/migration/1731806320819-pageIsPublic.js @@ -0,0 +1,21 @@ +export class PageIsPublic1731806320819 { + name = 'PageIsPublic1731806320819' + + async up(queryRunner) { + await queryRunner.query(`DROP INDEX "public"."IDX_90148bbc2bf0854428786bfc15"`); + await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "visibility"`); + await queryRunner.query(`DROP TYPE "public"."page_visibility_enum"`); + await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "visibleUserIds"`); + await queryRunner.query(`ALTER TABLE "page" ADD "isPublish" boolean NOT NULL DEFAULT true`); + await queryRunner.query(`CREATE INDEX "IDX_dce798cab7e5478ba4fc15e515" ON "page" ("isPublish") `); + } + + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "public"."IDX_dce798cab7e5478ba4fc15e515"`); + await queryRunner.query(`CREATE TYPE "public"."user_profile_followersVisibility_enum_old" AS ENUM('public', 'followers', 'private')`); + await queryRunner.query(`ALTER TABLE "page" ADD "visibleUserIds" character varying(32) array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."page_visibility_enum" AS ENUM('public', 'followers', 'specified')`); + await queryRunner.query(`ALTER TABLE "page" ADD "visibility" "public"."page_visibility_enum" NOT NULL`); + await queryRunner.query(`CREATE INDEX "IDX_90148bbc2bf0854428786bfc15" ON "page" ("visibleUserIds") `); + } +} diff --git a/packages/backend/src/core/entities/PageEntityService.ts b/packages/backend/src/core/entities/PageEntityService.ts index 5239f3158510..4bdaaefaeb82 100644 --- a/packages/backend/src/core/entities/PageEntityService.ts +++ b/packages/backend/src/core/entities/PageEntityService.ts @@ -99,6 +99,7 @@ export class PageEntityService { hideTitleWhenPinned: page.hideTitleWhenPinned, alignCenter: page.alignCenter, font: page.font, + isPublish: page.isPublish, script: page.script, eyeCatchingImageId: page.eyeCatchingImageId, eyeCatchingImage: page.eyeCatchingImageId ? await this.driveFileEntityService.pack(page.eyeCatchingImageId, me) : null, diff --git a/packages/backend/src/models/Page.ts b/packages/backend/src/models/Page.ts index 36acf42c6ebf..701c6f765359 100644 --- a/packages/backend/src/models/Page.ts +++ b/packages/backend/src/models/Page.ts @@ -97,20 +97,11 @@ export class MiPage { }) public script: string; - /** - * public ... 公開 - * followers ... フォロワーのみ - * specified ... visibleUserIds で指定したユーザーのみ - */ - @Column('enum', { enum: ['public', 'followers', 'specified'] }) - public visibility: 'public' | 'followers' | 'specified'; - @Index() - @Column({ - ...id(), - array: true, default: '{}', + @Column('boolean', { + default: true, }) - public visibleUserIds: MiUser['id'][]; + public isPublish: boolean; @Column('integer', { default: 0, diff --git a/packages/backend/src/server/api/endpoints/pages/create.ts b/packages/backend/src/server/api/endpoints/pages/create.ts index ee6a1b92c7bc..c45596b7443d 100644 --- a/packages/backend/src/server/api/endpoints/pages/create.ts +++ b/packages/backend/src/server/api/endpoints/pages/create.ts @@ -60,6 +60,7 @@ export const paramDef = { variables: { type: 'array', items: { type: 'object', additionalProperties: true, } }, + isPublish: { type: 'boolean' }, script: { type: 'string' }, eyeCatchingImageId: { type: 'string', format: 'misskey:id', nullable: true }, font: { type: 'string', enum: ['serif', 'sans-serif'], default: 'sans-serif' }, @@ -114,7 +115,7 @@ export default class extends Endpoint { // eslint- script: ps.script, eyeCatchingImageId: eyeCatchingImage ? eyeCatchingImage.id : null, userId: me.id, - visibility: 'public', + isPublish: ps.isPublish, alignCenter: ps.alignCenter, hideTitleWhenPinned: ps.hideTitleWhenPinned, font: ps.font, diff --git a/packages/backend/src/server/api/endpoints/pages/featured.ts b/packages/backend/src/server/api/endpoints/pages/featured.ts index a47b69e56eb0..e7324e79a823 100644 --- a/packages/backend/src/server/api/endpoints/pages/featured.ts +++ b/packages/backend/src/server/api/endpoints/pages/featured.ts @@ -41,7 +41,7 @@ export default class extends Endpoint { // eslint- ) { super(meta, paramDef, async (ps, me) => { const query = this.pagesRepository.createQueryBuilder('page') - .where('page.visibility = \'public\'') + .where('page.isPublish = true') .andWhere('page.likedCount > 0') .orderBy('page.likedCount', 'DESC'); diff --git a/packages/backend/src/server/api/endpoints/pages/show.ts b/packages/backend/src/server/api/endpoints/pages/show.ts index e08b832a3f9a..64ec3053a6ad 100644 --- a/packages/backend/src/server/api/endpoints/pages/show.ts +++ b/packages/backend/src/server/api/endpoints/pages/show.ts @@ -78,6 +78,10 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.noSuchPage); } + if (!page.isPublish && (me == null || (page.userId !== me.id))) { + throw new ApiError(meta.errors.noSuchPage); + } + return await this.pageEntityService.pack(page, me); }); } diff --git a/packages/backend/src/server/api/endpoints/pages/update.ts b/packages/backend/src/server/api/endpoints/pages/update.ts index a42f6adddd1e..47c7e78052c2 100644 --- a/packages/backend/src/server/api/endpoints/pages/update.ts +++ b/packages/backend/src/server/api/endpoints/pages/update.ts @@ -65,6 +65,7 @@ export const paramDef = { variables: { type: 'array', items: { type: 'object', additionalProperties: true, } }, + isPublish: { type: 'boolean' }, script: { type: 'string' }, eyeCatchingImageId: { type: 'string', format: 'misskey:id', nullable: true }, font: { type: 'string', enum: ['serif', 'sans-serif'] }, @@ -123,6 +124,7 @@ export default class extends Endpoint { // eslint- content: ps.content, variables: ps.variables, script: ps.script, + isPublish: ps.isPublish, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing alignCenter: ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing diff --git a/packages/backend/src/server/api/endpoints/users/pages.ts b/packages/backend/src/server/api/endpoints/users/pages.ts index 9b1c80886367..ed77b2a2542a 100644 --- a/packages/backend/src/server/api/endpoints/users/pages.ts +++ b/packages/backend/src/server/api/endpoints/users/pages.ts @@ -49,7 +49,7 @@ export default class extends Endpoint { // eslint- super(meta, paramDef, async (ps, me) => { const query = this.queryService.makePaginationQuery(this.pagesRepository.createQueryBuilder('page'), ps.sinceId, ps.untilId) .andWhere('page.userId = :userId', { userId: ps.userId }) - .andWhere('page.visibility = \'public\''); + .andWhere('page.isPublish = true'); const pages = await query .limit(ps.limit) diff --git a/packages/frontend/src/pages/page-editor/page-editor.vue b/packages/frontend/src/pages/page-editor/page-editor.vue index af32fd227465..2fe7fc5b6dd5 100644 --- a/packages/frontend/src/pages/page-editor/page-editor.vue +++ b/packages/frontend/src/pages/page-editor/page-editor.vue @@ -31,6 +31,8 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts._pages.alignCenter }} + {{ i18n.ts.publish }} + @@ -98,6 +100,7 @@ const eyeCatchingImageId = ref(null); const font = ref('sans-serif'); const content = ref([]); const alignCenter = ref(false); +const isPublish = ref(false); const hideTitleWhenPinned = ref(false); provide('readonly', readonly.value); @@ -122,6 +125,7 @@ function getSaveOptions() { script: '', hideTitleWhenPinned: hideTitleWhenPinned.value, alignCenter: alignCenter.value, + isPublish: isPublish.value, content: content.value, variables: [], eyeCatchingImageId: eyeCatchingImageId.value, @@ -258,6 +262,7 @@ async function init() { font.value = page.value.font; hideTitleWhenPinned.value = page.value.hideTitleWhenPinned; alignCenter.value = page.value.alignCenter; + isPublish.value = page.value.isPublish; content.value = page.value.content; eyeCatchingImageId.value = page.value.eyeCatchingImageId; } else { From 017fd69af58f7f37c54cc75e5b92bbb3269455ac Mon Sep 17 00:00:00 2001 From: mattyatea Date: Sat, 7 Dec 2024 20:00:29 +0900 Subject: [PATCH 2/6] =?UTF-8?q?=E6=97=A2=E3=81=AB=E3=81=82=E3=82=8Bvisibil?= =?UTF-8?q?ity=E3=82=92=E4=BD=BF=E3=81=86=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/index.d.ts | 12 +++++++++++ locales/ja-JP.yml | 3 +++ .../migration/1731806320819-pageIsPublic.js | 21 ------------------- .../1733563840208-page-visibility.js | 17 +++++++++++++++ .../src/core/entities/PageEntityService.ts | 2 +- packages/backend/src/models/Page.ts | 11 +++++----- .../src/server/api/endpoints/pages/create.ts | 4 ++-- .../src/server/api/endpoints/pages/show.ts | 2 +- .../src/server/api/endpoints/pages/update.ts | 4 +++- .../frontend/src/components/MkPagePreview.vue | 2 +- .../src/pages/page-editor/page-editor.vue | 18 +++++++++------- packages/frontend/src/pages/page.vue | 4 ++-- 12 files changed, 59 insertions(+), 41 deletions(-) delete mode 100644 packages/backend/migration/1731806320819-pageIsPublic.js create mode 100644 packages/backend/migration/1733563840208-page-visibility.js diff --git a/locales/index.d.ts b/locales/index.d.ts index 7bae7cea4f27..cfd0c1c788e4 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -9501,6 +9501,18 @@ export interface Locale extends ILocale { * 特殊 */ "specialBlocks": string; + /** + * 公開範囲 + */ + "visibility": string; + /** + * 公開 + */ + "public": string; + /** + * 非公開 + */ + "private": string; "blocks": { /** * テキスト diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 11acdaa61937..dd0b43ba45be 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2496,6 +2496,9 @@ _pages: contentBlocks: "コンテンツ" inputBlocks: "入力" specialBlocks: "特殊" + visibility: "公開範囲" + public: "公開" + private: "非公開" blocks: text: "テキスト" textarea: "テキストエリア" diff --git a/packages/backend/migration/1731806320819-pageIsPublic.js b/packages/backend/migration/1731806320819-pageIsPublic.js deleted file mode 100644 index e4a780e7b998..000000000000 --- a/packages/backend/migration/1731806320819-pageIsPublic.js +++ /dev/null @@ -1,21 +0,0 @@ -export class PageIsPublic1731806320819 { - name = 'PageIsPublic1731806320819' - - async up(queryRunner) { - await queryRunner.query(`DROP INDEX "public"."IDX_90148bbc2bf0854428786bfc15"`); - await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "visibility"`); - await queryRunner.query(`DROP TYPE "public"."page_visibility_enum"`); - await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "visibleUserIds"`); - await queryRunner.query(`ALTER TABLE "page" ADD "isPublish" boolean NOT NULL DEFAULT true`); - await queryRunner.query(`CREATE INDEX "IDX_dce798cab7e5478ba4fc15e515" ON "page" ("isPublish") `); - } - - async down(queryRunner) { - await queryRunner.query(`DROP INDEX "public"."IDX_dce798cab7e5478ba4fc15e515"`); - await queryRunner.query(`CREATE TYPE "public"."user_profile_followersVisibility_enum_old" AS ENUM('public', 'followers', 'private')`); - await queryRunner.query(`ALTER TABLE "page" ADD "visibleUserIds" character varying(32) array NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."page_visibility_enum" AS ENUM('public', 'followers', 'specified')`); - await queryRunner.query(`ALTER TABLE "page" ADD "visibility" "public"."page_visibility_enum" NOT NULL`); - await queryRunner.query(`CREATE INDEX "IDX_90148bbc2bf0854428786bfc15" ON "page" ("visibleUserIds") `); - } -} diff --git a/packages/backend/migration/1733563840208-page-visibility.js b/packages/backend/migration/1733563840208-page-visibility.js new file mode 100644 index 000000000000..c360f31b7cd6 --- /dev/null +++ b/packages/backend/migration/1733563840208-page-visibility.js @@ -0,0 +1,17 @@ +export class PageVisibility1733563840208 { + name = 'PageVisibility1733563840208' + + async up(queryRunner) { + await queryRunner.query(`ALTER TYPE "public"."page_visibility_enum" RENAME TO "page_visibility_enum_old"`); + await queryRunner.query(`CREATE TYPE "public"."page_visibility_enum" AS ENUM('public', 'private')`); + await queryRunner.query(`ALTER TABLE "page" ALTER COLUMN "visibility" TYPE "public"."page_visibility_enum" USING "visibility"::"text"::"public"."page_visibility_enum"`); + await queryRunner.query(`DROP TYPE "public"."page_visibility_enum_old"`); + } + + async down(queryRunner) { + await queryRunner.query(`CREATE TYPE "public"."page_visibility_enum_old" AS ENUM('followers', 'public', 'specified')`); + await queryRunner.query(`ALTER TABLE "page" ALTER COLUMN "visibility" TYPE "public"."page_visibility_enum_old" USING "visibility"::"text"::"public"."page_visibility_enum_old"`); + await queryRunner.query(`DROP TYPE "public"."page_visibility_enum"`); + await queryRunner.query(`ALTER TYPE "public"."page_visibility_enum_old" RENAME TO "page_visibility_enum"`); + } +} diff --git a/packages/backend/src/core/entities/PageEntityService.ts b/packages/backend/src/core/entities/PageEntityService.ts index 4bdaaefaeb82..a3e8f4ec4b51 100644 --- a/packages/backend/src/core/entities/PageEntityService.ts +++ b/packages/backend/src/core/entities/PageEntityService.ts @@ -99,13 +99,13 @@ export class PageEntityService { hideTitleWhenPinned: page.hideTitleWhenPinned, alignCenter: page.alignCenter, font: page.font, - isPublish: page.isPublish, script: page.script, eyeCatchingImageId: page.eyeCatchingImageId, eyeCatchingImage: page.eyeCatchingImageId ? await this.driveFileEntityService.pack(page.eyeCatchingImageId, me) : null, attachedFiles: this.driveFileEntityService.packMany((await Promise.all(attachedFiles)).filter(isNotNull), me), likedCount: page.likedCount, isLiked: meId ? await this.pageLikesRepository.exists({ where: { pageId: page.id, userId: meId } }) : undefined, + visibility: page.visibility, }); } diff --git a/packages/backend/src/models/Page.ts b/packages/backend/src/models/Page.ts index 701c6f765359..04c89bc3b9aa 100644 --- a/packages/backend/src/models/Page.ts +++ b/packages/backend/src/models/Page.ts @@ -97,11 +97,12 @@ export class MiPage { }) public script: string; - @Index() - @Column('boolean', { - default: true, - }) - public isPublish: boolean; + /** + * public ... 公開 + * private ... 非公開 + */ + @Column('enum', { enum: ['public', 'private'] }) + public visibility: 'public' | 'private'; @Column('integer', { default: 0, diff --git a/packages/backend/src/server/api/endpoints/pages/create.ts b/packages/backend/src/server/api/endpoints/pages/create.ts index c45596b7443d..305b62075835 100644 --- a/packages/backend/src/server/api/endpoints/pages/create.ts +++ b/packages/backend/src/server/api/endpoints/pages/create.ts @@ -60,12 +60,12 @@ export const paramDef = { variables: { type: 'array', items: { type: 'object', additionalProperties: true, } }, - isPublish: { type: 'boolean' }, script: { type: 'string' }, eyeCatchingImageId: { type: 'string', format: 'misskey:id', nullable: true }, font: { type: 'string', enum: ['serif', 'sans-serif'], default: 'sans-serif' }, alignCenter: { type: 'boolean', default: false }, hideTitleWhenPinned: { type: 'boolean', default: false }, + visibility: { type: 'string', enum: ['public', 'private'] }, }, required: ['title', 'name', 'content', 'variables', 'script'], } as const; @@ -115,7 +115,7 @@ export default class extends Endpoint { // eslint- script: ps.script, eyeCatchingImageId: eyeCatchingImage ? eyeCatchingImage.id : null, userId: me.id, - isPublish: ps.isPublish, + visibility: ps.visibility, alignCenter: ps.alignCenter, hideTitleWhenPinned: ps.hideTitleWhenPinned, font: ps.font, diff --git a/packages/backend/src/server/api/endpoints/pages/show.ts b/packages/backend/src/server/api/endpoints/pages/show.ts index 64ec3053a6ad..1bf612753289 100644 --- a/packages/backend/src/server/api/endpoints/pages/show.ts +++ b/packages/backend/src/server/api/endpoints/pages/show.ts @@ -78,7 +78,7 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.noSuchPage); } - if (!page.isPublish && (me == null || (page.userId !== me.id))) { + if (page.visibility === 'private' && (me == null || (page.userId !== me.id))) { throw new ApiError(meta.errors.noSuchPage); } diff --git a/packages/backend/src/server/api/endpoints/pages/update.ts b/packages/backend/src/server/api/endpoints/pages/update.ts index 47c7e78052c2..e212a4723e64 100644 --- a/packages/backend/src/server/api/endpoints/pages/update.ts +++ b/packages/backend/src/server/api/endpoints/pages/update.ts @@ -71,6 +71,7 @@ export const paramDef = { font: { type: 'string', enum: ['serif', 'sans-serif'] }, alignCenter: { type: 'boolean' }, hideTitleWhenPinned: { type: 'boolean' }, + visibility: { type: 'string', enum: ['public', 'private'] }, }, required: ['pageId', 'title', 'name', 'content', 'variables', 'script'], } as const; @@ -124,13 +125,14 @@ export default class extends Endpoint { // eslint- content: ps.content, variables: ps.variables, script: ps.script, - isPublish: ps.isPublish, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing alignCenter: ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing hideTitleWhenPinned: ps.hideTitleWhenPinned === undefined ? page.hideTitleWhenPinned : ps.hideTitleWhenPinned, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing font: ps.font === undefined ? page.font : ps.font, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + visibility: ps.visibility === undefined ? page.visibility : ps.visibility, eyeCatchingImageId: ps.eyeCatchingImageId === null ? null : ps.eyeCatchingImageId === undefined diff --git a/packages/frontend/src/components/MkPagePreview.vue b/packages/frontend/src/components/MkPagePreview.vue index c02b0b6f4602..fcb190465a29 100644 --- a/packages/frontend/src/components/MkPagePreview.vue +++ b/packages/frontend/src/components/MkPagePreview.vue @@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-

{{ page.title }}

+

{{ page.title || page.name }}

{{ page.summary.length > 85 ? page.summary.slice(0, 85) + '…' : page.summary }}