From 2e6be33712b8e583e4f54f2c2b2bcb0bd8e0a966 Mon Sep 17 00:00:00 2001 From: Jordan Jones Date: Tue, 12 Mar 2024 15:27:57 -0500 Subject: [PATCH] feat(usersettings): add ability to hide tags on details page fix #3350 --- server/entity/UserSettings.ts | 3 ++ .../interfaces/api/userSettingsInterfaces.ts | 1 + server/lib/settings.ts | 2 ++ .../1710274992992-AddHideTagsColumn.ts | 31 +++++++++++++++++++ server/routes/user/usersettings.ts | 4 +++ src/components/MovieDetails/index.tsx | 2 +- src/components/TvDetails/index.tsx | 2 +- .../UserGeneralSettings/index.tsx | 22 +++++++++++++ src/hooks/useUser.ts | 1 + src/i18n/locale/en.json | 2 ++ 10 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 server/migration/1710274992992-AddHideTagsColumn.ts diff --git a/server/entity/UserSettings.ts b/server/entity/UserSettings.ts index ea4a7d33bf..c0c435fe6b 100644 --- a/server/entity/UserSettings.ts +++ b/server/entity/UserSettings.ts @@ -66,6 +66,9 @@ export class UserSettings { @Column({ nullable: true }) public watchlistSyncTv?: boolean; + @Column({ nullable: true }) + public hideTags?: boolean; + @Column({ type: 'text', nullable: true, diff --git a/server/interfaces/api/userSettingsInterfaces.ts b/server/interfaces/api/userSettingsInterfaces.ts index fb0767b211..61ab6694d3 100644 --- a/server/interfaces/api/userSettingsInterfaces.ts +++ b/server/interfaces/api/userSettingsInterfaces.ts @@ -16,6 +16,7 @@ export interface UserSettingsGeneralResponse { globalTvQuotaDays?: number; watchlistSyncMovies?: boolean; watchlistSyncTv?: boolean; + hideTags?: boolean; } export type NotificationAgentTypes = Record; diff --git a/server/lib/settings.ts b/server/lib/settings.ts index 10213a0403..80f87500ee 100644 --- a/server/lib/settings.ts +++ b/server/lib/settings.ts @@ -97,6 +97,7 @@ export interface MainSettings { tv: Quota; }; hideAvailable: boolean; + hideTags: boolean; localLogin: boolean; newPlexLogin: boolean; region: string; @@ -293,6 +294,7 @@ class Settings { tv: {}, }, hideAvailable: false, + hideTags: false, localLogin: true, newPlexLogin: true, region: '', diff --git a/server/migration/1710274992992-AddHideTagsColumn.ts b/server/migration/1710274992992-AddHideTagsColumn.ts new file mode 100644 index 0000000000..a3b80ebff0 --- /dev/null +++ b/server/migration/1710274992992-AddHideTagsColumn.ts @@ -0,0 +1,31 @@ +import type { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddHideTagsColumn1710274992992 implements MigrationInterface { + name = 'AddHideTagsColumn1710274992992'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "temporary_user_settings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "locale" varchar NOT NULL DEFAULT (''), "region" varchar, "originalLanguage" varchar, "pgpKey" varchar, "discordId" varchar, "pushbulletAccessToken" varchar, "pushoverApplicationToken" varchar, "pushoverUserKey" varchar, "pushoverSound" varchar, "telegramChatId" varchar, "telegramSendSilently" boolean, "watchlistSyncMovies" boolean, "watchlistSyncTv" boolean, "notificationTypes" text, "userId" integer, "hideTags" boolean, CONSTRAINT "REL_986a2b6d3c05eb4091bb8066f7" UNIQUE ("userId"), CONSTRAINT "FK_986a2b6d3c05eb4091bb8066f78" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)` + ); + await queryRunner.query( + `INSERT INTO "temporary_user_settings"("id", "locale", "region", "originalLanguage", "pgpKey", "discordId", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "pushoverSound", "telegramChatId", "telegramSendSilently", "watchlistSyncMovies", "watchlistSyncTv", "notificationTypes", "userId") SELECT "id", "locale", "region", "originalLanguage", "pgpKey", "discordId", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "pushoverSound", "telegramChatId", "telegramSendSilently", "watchlistSyncMovies", "watchlistSyncTv", "notificationTypes", "userId" FROM "user_settings"` + ); + await queryRunner.query(`DROP TABLE "user_settings"`); + await queryRunner.query( + `ALTER TABLE "temporary_user_settings" RENAME TO "user_settings"` + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "user_settings" RENAME TO "temporary_user_settings"` + ); + await queryRunner.query( + `CREATE TABLE "user_settings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "locale" varchar NOT NULL DEFAULT (''), "region" varchar, "originalLanguage" varchar, "pgpKey" varchar, "discordId" varchar, "pushbulletAccessToken" varchar, "pushoverApplicationToken" varchar, "pushoverUserKey" varchar, "pushoverSound" varchar, "telegramChatId" varchar, "telegramSendSilently" boolean, "watchlistSyncMovies" boolean, "watchlistSyncTv" boolean, "notificationTypes" text, "userId" integer, CONSTRAINT "REL_986a2b6d3c05eb4091bb8066f7" UNIQUE ("userId"), CONSTRAINT "FK_986a2b6d3c05eb4091bb8066f78" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)` + ); + await queryRunner.query( + `INSERT INTO "user_settings"("id", "locale", "region", "originalLanguage", "pgpKey", "discordId", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "pushoverSound", "telegramChatId", "telegramSendSilently", "watchlistSyncMovies", "watchlistSyncTv", "notificationTypes", "userId") SELECT "id", "locale", "region", "originalLanguage", "pgpKey", "discordId", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "pushoverSound", "telegramChatId", "telegramSendSilently", "watchlistSyncMovies", "watchlistSyncTv", "notificationTypes", "userId" FROM "temporary_user_settings"` + ); + await queryRunner.query(`DROP TABLE "temporary_user_settings"`); + } +} diff --git a/server/routes/user/usersettings.ts b/server/routes/user/usersettings.ts index c8b3f50bd2..ec55914670 100644 --- a/server/routes/user/usersettings.ts +++ b/server/routes/user/usersettings.ts @@ -65,6 +65,7 @@ userSettingsRoutes.get<{ id: string }, UserSettingsGeneralResponse>( globalTvQuotaLimit: defaultQuotas.tv.quotaLimit, watchlistSyncMovies: user.settings?.watchlistSyncMovies, watchlistSyncTv: user.settings?.watchlistSyncTv, + hideTags: user.settings?.hideTags, }); } catch (e) { next({ status: 500, message: e.message }); @@ -118,6 +119,7 @@ userSettingsRoutes.post< originalLanguage: req.body.originalLanguage, watchlistSyncMovies: req.body.watchlistSyncMovies, watchlistSyncTv: req.body.watchlistSyncTv, + hideTags: req.body.hideTags, }); } else { user.settings.discordId = req.body.discordId; @@ -126,6 +128,7 @@ userSettingsRoutes.post< user.settings.originalLanguage = req.body.originalLanguage; user.settings.watchlistSyncMovies = req.body.watchlistSyncMovies; user.settings.watchlistSyncTv = req.body.watchlistSyncTv; + user.settings.hideTags = req.body.hideTags; } await userRepository.save(user); @@ -138,6 +141,7 @@ userSettingsRoutes.post< originalLanguage: user.settings.originalLanguage, watchlistSyncMovies: user.settings.watchlistSyncMovies, watchlistSyncTv: user.settings.watchlistSyncTv, + hideTags: user.settings.hideTags, }); } catch (e) { next({ status: 500, message: e.message }); diff --git a/src/components/MovieDetails/index.tsx b/src/components/MovieDetails/index.tsx index 11b2a77539..8d828e11dc 100644 --- a/src/components/MovieDetails/index.tsx +++ b/src/components/MovieDetails/index.tsx @@ -464,7 +464,7 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => { )} - {data.keywords.length > 0 && ( + {!user?.settings?.hideTags && data.keywords.length > 0 && (
{data.keywords.map((keyword) => ( {
)} - {data.keywords.length > 0 && ( + {!user?.settings?.hideTags && data.keywords.length > 0 && (
{data.keywords.map((keyword) => ( Plex Watchlist', + hideTags: 'Hide Tags', + hideTagsTip: 'Hide tags in Movie/Series detail page', }); const UserGeneralSettings = () => { @@ -130,6 +132,7 @@ const UserGeneralSettings = () => { tvQuotaDays: data?.tvQuotaDays, watchlistSyncMovies: data?.watchlistSyncMovies, watchlistSyncTv: data?.watchlistSyncTv, + hideTags: data?.hideTags, }} validationSchema={UserGeneralSettingsSchema} enableReinitialize @@ -149,6 +152,7 @@ const UserGeneralSettings = () => { tvQuotaDays: tvQuotaEnabled ? values.tvQuotaDays : null, watchlistSyncMovies: values.watchlistSyncMovies, watchlistSyncTv: values.watchlistSyncTv, + hideTags: values.hideTags, }); if (currentUser?.id === user?.id && setLocale) { @@ -334,6 +338,24 @@ const UserGeneralSettings = () => {
+
+ +
+ { + setFieldValue('hideTags', !values.hideTags); + }} + /> +
+
{currentHasPermission(Permission.MANAGE_USERS) && !hasPermission(Permission.MANAGE_USERS) && ( <> diff --git a/src/hooks/useUser.ts b/src/hooks/useUser.ts index 192b3fe9da..3596383bdd 100644 --- a/src/hooks/useUser.ts +++ b/src/hooks/useUser.ts @@ -33,6 +33,7 @@ export interface UserSettings { notificationTypes: Partial; watchlistSyncMovies?: boolean; watchlistSyncTv?: boolean; + hideTags?: boolean; } interface UserHookResponse { diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json index 10165c9e15..618ce1436a 100644 --- a/src/i18n/locale/en.json +++ b/src/i18n/locale/en.json @@ -1087,6 +1087,8 @@ "components.UserProfile.UserSettings.UserGeneralSettings.enableOverride": "Override Global Limit", "components.UserProfile.UserSettings.UserGeneralSettings.general": "General", "components.UserProfile.UserSettings.UserGeneralSettings.generalsettings": "General Settings", + "components.UserProfile.UserSettings.UserGeneralSettings.hideTags": "Hide Tags", + "components.UserProfile.UserSettings.UserGeneralSettings.hideTagsTip": "Hide tags in Movie/Series detail page", "components.UserProfile.UserSettings.UserGeneralSettings.languageDefault": "Default ({language})", "components.UserProfile.UserSettings.UserGeneralSettings.localuser": "Local User", "components.UserProfile.UserSettings.UserGeneralSettings.movierequestlimit": "Movie Request Limit",