diff --git a/locales/en-US.yml b/locales/en-US.yml index 77ea22e1c4..1583286ada 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -99,6 +99,7 @@ serverIsDead: "This server is not responding. Please wait for a while and try ag youShouldUpgradeClient: "To view this page, please refresh to update your client." enterListName: "Enter a name for the list" privacy: "Privacy" +autoDeleteNotes: "Self-destructing notes" makeFollowManuallyApprove: "Follow requests require approval" defaultNoteVisibility: "Default visibility" follow: "Follow" @@ -947,6 +948,7 @@ oneHour: "One hour" oneDay: "One day" oneWeek: "One week" oneMonth: "One month" +oneYear: "One year" reflectMayTakeTime: "It may take some time for this to be reflected." failedToFetchAccountInformation: "Could not fetch account information" rateLimitExceeded: "Rate limit exceeded" diff --git a/packages/backend/migration/1709530777533-autoDeleteNotes.js b/packages/backend/migration/1709530777533-autoDeleteNotes.js new file mode 100644 index 0000000000..2b296c4f29 --- /dev/null +++ b/packages/backend/migration/1709530777533-autoDeleteNotes.js @@ -0,0 +1,14 @@ +export class AutoDeleteNotes1709530777533 { + name = "AutoDeleteNotes1709530777533"; + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE user_profile ADD "autoDeleteNotes" boolean NOT NULL DEFAULT false;`); + await queryRunner.query(`ALTER TABLE user_profile ADD "autoDeleteNotesMinutes" integer NOT NULL DEFAULT 43200;`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE user_profile DROP COLUMN "autoDeleteNotes";`); + await queryRunner.query(`ALTER TABLE user_profile DROP COLUMN "autoDeleteNotesMinutes";`); + } + +} diff --git a/packages/backend/migration/1709530777533-noteSelfDestructInterval.js b/packages/backend/migration/1709530777533-noteSelfDestructInterval.js deleted file mode 100644 index 370eed516f..0000000000 --- a/packages/backend/migration/1709530777533-noteSelfDestructInterval.js +++ /dev/null @@ -1,13 +0,0 @@ -export class NoteSelfDestructInterval1709530777533 { - - async up(queryRunner) { - await queryRunner.query(`ALTER TABLE user_profile ADD "noteSelfDestructInterval" interval NOT NULL DEFAULT '1 months';`); - await queryRunner.query(`ALTER TABLE user_profile ADD "noteSelfDestructEnable" boolean NOT NULL DEFAULT false;`); - } - - async down(queryRunner) { - await queryRunner.query(`ALTER TABLE user_profile DROP COLUMN "noteSelfDestructInterval";`); - await queryRunner.query(`ALTER TABLE user_profile DROP COLUMN "noteSelfDestructEnable";`); - } - -} diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index f9d0066814..20a3ca64c7 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -509,8 +509,8 @@ export class UserEntityService implements OnModuleInit { mutedWords: profile!.mutedWords, hardMutedWords: profile!.hardMutedWords, mutedInstances: profile!.mutedInstances, - noteSelfDestructInterval: profile!.noteSelfDestructInterval, - noteSelfDestructEnable: profile!.noteSelfDestructEnable, + autoDeleteNotes: profile!.autoDeleteNotes, + autoDeleteNotesMinutes: profile!.autoDeleteNotesMinutes, mutingNotificationTypes: [], // 後方互換性のため notificationRecieveConfig: profile!.notificationRecieveConfig, emailNotificationTypes: profile!.emailNotificationTypes, diff --git a/packages/backend/src/models/User.ts b/packages/backend/src/models/User.ts index 407b7e5e2b..b0910133c9 100644 --- a/packages/backend/src/models/User.ts +++ b/packages/backend/src/models/User.ts @@ -343,4 +343,3 @@ export const descriptionSchema = { type: 'string', minLength: 1, maxLength: 1500 export const locationSchema = { type: 'string', minLength: 1, maxLength: 50 } as const; export const listenbrainzSchema = { type: "string", minLength: 1, maxLength: 128 } as const; export const birthdaySchema = { type: 'string', pattern: /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.toString().slice(1, -1) } as const; -export const selfDestructIntervalSchema = { type: 'string', pattern: /^[1-9][0-9]+ (years|months|days|hours|minutes)$/.toString().slice(1, -1) } as const; diff --git a/packages/backend/src/models/UserProfile.ts b/packages/backend/src/models/UserProfile.ts index 8a6cd096b2..f0e06866a4 100644 --- a/packages/backend/src/models/UserProfile.ts +++ b/packages/backend/src/models/UserProfile.ts @@ -277,15 +277,15 @@ export class MiUserProfile { unlockedAt: number; }[]; - @Column('interval', { - default: '1 months', - }) - public noteSelfDestructInterval: string; - @Column('boolean', { default: false, }) - public noteSelfDestructEnable: string; + public autoDeleteNotes: boolean; + + @Column('integer', { + default: 43200, // 30 days in minutes + }) + public autoDeleteNotesMinutes: number; //#region Denormalized fields diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts index f334bc5205..c31291a6a4 100644 --- a/packages/backend/src/models/json-schema/user.ts +++ b/packages/backend/src/models/json-schema/user.ts @@ -605,12 +605,12 @@ export const packedMeDetailedOnlySchema = { nullable: false, optional: false, }, }, - noteSelfDestructInterval: { - type: 'string', + autoDeleteNotes: { + type: 'boolean', nullable: false, optional: false, }, - noteSelfDestructEnable: { - type: 'boolean', + autoDeleteNotesMinutes: { + type: 'number', nullable: false, optional: false, }, notificationRecieveConfig: { diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts index c88a626952..818322eb8e 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-user.ts @@ -88,14 +88,14 @@ export const meta = { type: 'string', }, }, - noteSelfDestructInterval: { - type: 'string', - optional: false, nullable: false, - }, - noteSelfDestructEnable: { + autoDeleteNotes: { type: 'boolean', optional: false, nullable: false, }, + autoDeleteNotesMinutes: { + type: 'number', + optional: false, nullable: false, + }, notificationRecieveConfig: { type: 'object', optional: false, nullable: false, @@ -247,8 +247,8 @@ export default class extends Endpoint { // eslint- receiveAnnouncementEmail: profile.receiveAnnouncementEmail, mutedWords: profile.mutedWords, mutedInstances: profile.mutedInstances, - noteSelfDestructInterval: profile.noteSelfDestructInterval, - noteSelfDestructEnable: profile.noteSelfDestructEnable, + autoDeleteNotesMinutes: profile.autoDeleteNotesMinutes, + autoDeleteNotes: profile.autoDeleteNotes, notificationRecieveConfig: profile.notificationRecieveConfig, isModerator: isModerator, isSilenced: isSilenced, diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index 2143d58ee0..7bd3cbf68d 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -13,7 +13,7 @@ import { extractHashtags } from '@/misc/extract-hashtags.js'; import * as Acct from '@/misc/acct.js'; import type { UsersRepository, DriveFilesRepository, UserProfilesRepository, PagesRepository } from '@/models/_.js'; import type { MiLocalUser, MiUser } from '@/models/User.js'; -import { birthdaySchema, listenbrainzSchema, descriptionSchema, locationSchema, nameSchema, selfDestructIntervalSchema } from '@/models/User.js'; +import { birthdaySchema, listenbrainzSchema, descriptionSchema, locationSchema, nameSchema } from '@/models/User.js'; import type { MiUserProfile } from '@/models/UserProfile.js'; import { notificationTypes } from '@/types.js'; import { normalizeForSearch } from '@/misc/normalize-for-search.js'; @@ -202,8 +202,8 @@ export const paramDef = { mutedInstances: { type: 'array', items: { type: 'string', } }, - noteSelfDestructInterval: { ...selfDestructIntervalSchema, nullable: false }, - noteSelfDestructEnable: { type: 'boolean', nullable: false }, + autoDeleteNotes: { type: 'boolean', nullable: false }, + autoDeleteNotesMinutes: { type: 'number', nullable: false, minimum: 1 }, notificationRecieveConfig: { type: 'object', nullable: false, @@ -321,8 +321,8 @@ export default class extends Endpoint { // eslint- profileUpdates.hardMutedWords = ps.hardMutedWords; } if (ps.mutedInstances !== undefined) profileUpdates.mutedInstances = ps.mutedInstances; - if (ps.noteSelfDestructInterval !== undefined) profileUpdates.noteSelfDestructInterval = ps.noteSelfDestructInterval; - if (ps.noteSelfDestructEnable !== undefined) profileUpdates.noteSelfDestructEnable = ps.noteSelfDestructEnable; + if (ps.autoDeleteNotes !== undefined) profileUpdates.autoDeleteNotes = ps.autoDeleteNotes; + if (ps.autoDeleteNotesMinutes !== undefined) profileUpdates.autoDeleteNotesMinutes = ps.autoDeleteNotesMinutes; if (ps.notificationRecieveConfig !== undefined) profileUpdates.notificationRecieveConfig = ps.notificationRecieveConfig; if (typeof ps.isLocked === 'boolean') updates.isLocked = ps.isLocked; if (typeof ps.isExplorable === 'boolean') updates.isExplorable = ps.isExplorable; diff --git a/packages/frontend/src/pages/settings/privacy.autodelete.vue b/packages/frontend/src/pages/settings/privacy.autodelete.vue new file mode 100644 index 0000000000..ebe58c5de8 --- /dev/null +++ b/packages/frontend/src/pages/settings/privacy.autodelete.vue @@ -0,0 +1,66 @@ + + + diff --git a/packages/frontend/src/pages/settings/privacy.vue b/packages/frontend/src/pages/settings/privacy.vue index 69bd6d6eb7..36f3319871 100644 --- a/packages/frontend/src/pages/settings/privacy.vue +++ b/packages/frontend/src/pages/settings/privacy.vue @@ -72,24 +72,8 @@ SPDX-License-Identifier: AGPL-3.0-only
- -
- {{ i18n.ts.save }} - - - {{ i18n.ts.enable }} - - - - - - - - - - - -
+ +
@@ -99,10 +83,7 @@ SPDX-License-Identifier: AGPL-3.0-only