diff --git a/babel.config.js b/babel.config.js
deleted file mode 100644
index f7a1042f..00000000
--- a/babel.config.js
+++ /dev/null
@@ -1,25 +0,0 @@
-module.exports = function (api) {
- api.cache(true);
-
- return {
- presets: [
- [
- 'next/babel',
- {
- 'preset-env': {
- useBuiltIns: 'entry',
- corejs: '3',
- },
- },
- ],
- ],
- plugins: [
- [
- 'react-intl-auto',
- {
- removePrefix: 'src/',
- },
- ],
- ],
- };
-};
diff --git a/package.json b/package.json
index b5c4d993..97505d59 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"@formatjs/intl-locale": "3.1.1",
"@formatjs/intl-pluralrules": "5.1.10",
"@formatjs/intl-utils": "3.8.4",
+ "@formatjs/swc-plugin-experimental": "^0.4.0",
"@headlessui/react": "1.7.12",
"@heroicons/react": "2.0.16",
"@supercharge/request-ip": "1.2.0",
@@ -101,7 +102,6 @@
"zod": "3.20.6"
},
"devDependencies": {
- "@babel/cli": "7.21.0",
"@commitlint/cli": "17.4.4",
"@commitlint/config-conventional": "17.4.4",
"@semantic-release/changelog": "6.0.2",
@@ -135,8 +135,6 @@
"@typescript-eslint/eslint-plugin": "5.54.0",
"@typescript-eslint/parser": "5.54.0",
"autoprefixer": "10.4.13",
- "babel-plugin-react-intl": "8.2.25",
- "babel-plugin-react-intl-auto": "3.3.0",
"commitizen": "4.3.0",
"copyfiles": "2.4.1",
"cy-mobile-commands": "0.3.0",
diff --git a/src/components/AirDateBadge/index.tsx b/src/components/AirDateBadge/index.tsx
index c626aad9..d4e438a6 100644
--- a/src/components/AirDateBadge/index.tsx
+++ b/src/components/AirDateBadge/index.tsx
@@ -1,7 +1,8 @@
import Badge from '@app/components/Common/Badge';
-import { defineMessages, FormattedRelativeTime, useIntl } from 'react-intl';
+import defineMessages from '@app/utils/defineMessages';
+import { FormattedRelativeTime, useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.AirDateBadge', {
airedrelative: 'Aired {relativeTime}',
airsrelative: 'Airing {relativeTime}',
});
diff --git a/src/components/AppDataWarning/index.tsx b/src/components/AppDataWarning/index.tsx
index 21c3dbae..40874d5d 100644
--- a/src/components/AppDataWarning/index.tsx
+++ b/src/components/AppDataWarning/index.tsx
@@ -1,8 +1,9 @@
import Alert from '@app/components/Common/Alert';
-import { defineMessages, useIntl } from 'react-intl';
+import defineMessages from '@app/utils/defineMessages';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.AppDataWarning', {
dockerVolumeMissingDescription:
'The {appDataPath} volume mount was not configured properly. All data will be cleared when the container is stopped or restarted.',
});
diff --git a/src/components/CollectionDetails/index.tsx b/src/components/CollectionDetails/index.tsx
index f2fc1f7f..7afa28e4 100644
--- a/src/components/CollectionDetails/index.tsx
+++ b/src/components/CollectionDetails/index.tsx
@@ -10,6 +10,7 @@ import useSettings from '@app/hooks/useSettings';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import { refreshIntervalHelper } from '@app/utils/refreshIntervalHelper';
import { ArrowDownTrayIcon } from '@heroicons/react/24/outline';
import { MediaStatus } from '@server/constants/media';
@@ -18,10 +19,10 @@ import { uniq } from 'lodash';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useMemo, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.CollectionDetails', {
overview: 'Overview',
numberofmovies: '{count} Movies',
requestcollection: 'Request Collection',
diff --git a/src/components/Discover/CreateSlider/index.tsx b/src/components/Discover/CreateSlider/index.tsx
index 40d26fff..32cca079 100644
--- a/src/components/Discover/CreateSlider/index.tsx
+++ b/src/components/Discover/CreateSlider/index.tsx
@@ -4,6 +4,7 @@ import { sliderTitles } from '@app/components/Discover/constants';
import MediaSlider from '@app/components/MediaSlider';
import { WatchProviderSelector } from '@app/components/Selector';
import { encodeURIExtraParams } from '@app/hooks/useDiscover';
+import defineMessages from '@app/utils/defineMessages';
import type {
TmdbCompanySearchResponse,
TmdbGenre,
@@ -16,12 +17,12 @@ import type { Keyword, ProductionCompany } from '@server/models/common';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useCallback, useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import AsyncSelect from 'react-select/async';
import { useToasts } from 'react-toast-notifications';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.CreateSlider', {
addSlider: 'Add Slider',
editSlider: 'Edit Slider',
slidernameplaceholder: 'Slider Name',
diff --git a/src/components/Discover/DiscoverMovieGenre/index.tsx b/src/components/Discover/DiscoverMovieGenre/index.tsx
index d31921da..281ef4cc 100644
--- a/src/components/Discover/DiscoverMovieGenre/index.tsx
+++ b/src/components/Discover/DiscoverMovieGenre/index.tsx
@@ -4,11 +4,12 @@ import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { MovieResult } from '@server/models/Search';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.DiscoverMovieGenre', {
genreMovies: '{genre} Movies',
});
diff --git a/src/components/Discover/DiscoverMovieKeyword/index.tsx b/src/components/Discover/DiscoverMovieKeyword/index.tsx
index 7ae2e989..830b95df 100644
--- a/src/components/Discover/DiscoverMovieKeyword/index.tsx
+++ b/src/components/Discover/DiscoverMovieKeyword/index.tsx
@@ -4,12 +4,13 @@ import PageTitle from '@app/components/Common/PageTitle';
import useDiscover, { encodeURIExtraParams } from '@app/hooks/useDiscover';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { TmdbKeyword } from '@server/api/themoviedb/interfaces';
import type { MovieResult } from '@server/models/Search';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.DiscoverMovieKeyword', {
keywordMovies: '{keywordTitle} Movies',
});
diff --git a/src/components/Discover/DiscoverMovieLanguage/index.tsx b/src/components/Discover/DiscoverMovieLanguage/index.tsx
index e9a274fa..24fe91ba 100644
--- a/src/components/Discover/DiscoverMovieLanguage/index.tsx
+++ b/src/components/Discover/DiscoverMovieLanguage/index.tsx
@@ -4,11 +4,12 @@ import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { MovieResult } from '@server/models/Search';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.DiscoverMovieLanguage', {
languageMovies: '{language} Movies',
});
diff --git a/src/components/Discover/DiscoverMovies/index.tsx b/src/components/Discover/DiscoverMovies/index.tsx
index 2cc51177..117ecb5b 100644
--- a/src/components/Discover/DiscoverMovies/index.tsx
+++ b/src/components/Discover/DiscoverMovies/index.tsx
@@ -11,14 +11,15 @@ import FilterSlideover from '@app/components/Discover/FilterSlideover';
import useDiscover from '@app/hooks/useDiscover';
import { useUpdateQueryParams } from '@app/hooks/useUpdateQueryParams';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import { BarsArrowDownIcon, FunnelIcon } from '@heroicons/react/24/solid';
import type { SortOptions as TMDBSortOptions } from '@server/api/themoviedb';
import type { MovieResult } from '@server/models/Search';
import { useRouter } from 'next/router';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.DiscoverMovies', {
discovermovies: 'Movies',
activefilters:
'{count, plural, one {# Active Filter} other {# Active Filters}}',
diff --git a/src/components/Discover/DiscoverNetwork/index.tsx b/src/components/Discover/DiscoverNetwork/index.tsx
index 3c15e1a8..2721f949 100644
--- a/src/components/Discover/DiscoverNetwork/index.tsx
+++ b/src/components/Discover/DiscoverNetwork/index.tsx
@@ -4,13 +4,14 @@ import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { TvNetwork } from '@server/models/common';
import type { TvResult } from '@server/models/Search';
import Image from 'next/image';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.DiscoverNetwork', {
networkSeries: '{network} Series',
});
diff --git a/src/components/Discover/DiscoverSliderEdit/index.tsx b/src/components/Discover/DiscoverSliderEdit/index.tsx
index 9a0f3aa7..8fd556fe 100644
--- a/src/components/Discover/DiscoverSliderEdit/index.tsx
+++ b/src/components/Discover/DiscoverSliderEdit/index.tsx
@@ -8,6 +8,7 @@ import CreateSlider from '@app/components/Discover/CreateSlider';
import GenreTag from '@app/components/GenreTag';
import KeywordTag from '@app/components/KeywordTag';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { MagnifyingGlassIcon } from '@heroicons/react/24/outline';
import {
ArrowUturnLeftIcon,
@@ -22,10 +23,10 @@ import type DiscoverSlider from '@server/entity/DiscoverSlider';
import axios from 'axios';
import { useRef, useState } from 'react';
import { useDrag, useDrop } from 'react-aria';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.DiscoverSliderEdit', {
deletesuccess: 'Sucessfully deleted slider.',
deletefail: 'Failed to delete slider.',
remove: 'Remove',
diff --git a/src/components/Discover/DiscoverStudio/index.tsx b/src/components/Discover/DiscoverStudio/index.tsx
index a7f39db7..49b6d333 100644
--- a/src/components/Discover/DiscoverStudio/index.tsx
+++ b/src/components/Discover/DiscoverStudio/index.tsx
@@ -4,13 +4,14 @@ import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { ProductionCompany } from '@server/models/common';
import type { MovieResult } from '@server/models/Search';
import Image from 'next/image';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.DiscoverStudio', {
studioMovies: '{studio} Movies',
});
diff --git a/src/components/Discover/DiscoverTv/index.tsx b/src/components/Discover/DiscoverTv/index.tsx
index 52739367..1a4ce668 100644
--- a/src/components/Discover/DiscoverTv/index.tsx
+++ b/src/components/Discover/DiscoverTv/index.tsx
@@ -11,14 +11,15 @@ import FilterSlideover from '@app/components/Discover/FilterSlideover';
import useDiscover from '@app/hooks/useDiscover';
import { useUpdateQueryParams } from '@app/hooks/useUpdateQueryParams';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import { BarsArrowDownIcon, FunnelIcon } from '@heroicons/react/24/solid';
import type { SortOptions as TMDBSortOptions } from '@server/api/themoviedb';
import type { TvResult } from '@server/models/Search';
import { useRouter } from 'next/router';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.DiscoverTv', {
discovertv: 'Series',
activefilters:
'{count, plural, one {# Active Filter} other {# Active Filters}}',
diff --git a/src/components/Discover/DiscoverTvGenre/index.tsx b/src/components/Discover/DiscoverTvGenre/index.tsx
index 9602fbb8..633a4ad6 100644
--- a/src/components/Discover/DiscoverTvGenre/index.tsx
+++ b/src/components/Discover/DiscoverTvGenre/index.tsx
@@ -4,11 +4,12 @@ import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { TvResult } from '@server/models/Search';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.DiscoverTvGenre', {
genreSeries: '{genre} Series',
});
diff --git a/src/components/Discover/DiscoverTvKeyword/index.tsx b/src/components/Discover/DiscoverTvKeyword/index.tsx
index 0c041138..1deea4e4 100644
--- a/src/components/Discover/DiscoverTvKeyword/index.tsx
+++ b/src/components/Discover/DiscoverTvKeyword/index.tsx
@@ -4,12 +4,13 @@ import PageTitle from '@app/components/Common/PageTitle';
import useDiscover, { encodeURIExtraParams } from '@app/hooks/useDiscover';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { TmdbKeyword } from '@server/api/themoviedb/interfaces';
import type { TvResult } from '@server/models/Search';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.DiscoverTvKeywork', {
keywordSeries: '{keywordTitle} Series',
});
diff --git a/src/components/Discover/DiscoverTvLanguage/index.tsx b/src/components/Discover/DiscoverTvLanguage/index.tsx
index b6c710e9..e2d71a62 100644
--- a/src/components/Discover/DiscoverTvLanguage/index.tsx
+++ b/src/components/Discover/DiscoverTvLanguage/index.tsx
@@ -4,11 +4,12 @@ import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { TvResult } from '@server/models/Search';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.DiscoverTvLanguage', {
languageSeries: '{language} Series',
});
diff --git a/src/components/Discover/DiscoverTvUpcoming.tsx b/src/components/Discover/DiscoverTvUpcoming.tsx
index 2a693964..a6a3be17 100644
--- a/src/components/Discover/DiscoverTvUpcoming.tsx
+++ b/src/components/Discover/DiscoverTvUpcoming.tsx
@@ -3,10 +3,11 @@ import ListView from '@app/components/Common/ListView';
import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { TvResult } from '@server/models/Search';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.DiscoverTvUpcoming', {
upcomingtv: 'Upcoming Series',
});
diff --git a/src/components/Discover/DiscoverWatchlist/index.tsx b/src/components/Discover/DiscoverWatchlist/index.tsx
index 3afbe14b..ab00a27a 100644
--- a/src/components/Discover/DiscoverWatchlist/index.tsx
+++ b/src/components/Discover/DiscoverWatchlist/index.tsx
@@ -4,12 +4,13 @@ import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import { useUser } from '@app/hooks/useUser';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { WatchlistItem } from '@server/interfaces/api/discoverInterfaces';
import Link from 'next/link';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.DiscoverWatchlist', {
discoverwatchlist: 'Your Watchlist',
watchlist: 'Plex Watchlist',
});
diff --git a/src/components/Discover/FilterSlideover/index.tsx b/src/components/Discover/FilterSlideover/index.tsx
index 83d5a2e4..d7029fb2 100644
--- a/src/components/Discover/FilterSlideover/index.tsx
+++ b/src/components/Discover/FilterSlideover/index.tsx
@@ -15,11 +15,12 @@ import {
useBatchUpdateQueryParams,
useUpdateQueryParams,
} from '@app/hooks/useUpdateQueryParams';
+import defineMessages from '@app/utils/defineMessages';
import { XCircleIcon } from '@heroicons/react/24/outline';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import Datepicker from 'react-tailwindcss-datepicker-sct';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.FilterSlideover', {
filters: 'Filters',
activefilters:
'{count, plural, one {# Active Filter} other {# Active Filters}}',
diff --git a/src/components/Discover/MovieGenreList/index.tsx b/src/components/Discover/MovieGenreList/index.tsx
index f19f5770..5e183350 100644
--- a/src/components/Discover/MovieGenreList/index.tsx
+++ b/src/components/Discover/MovieGenreList/index.tsx
@@ -4,11 +4,12 @@ import PageTitle from '@app/components/Common/PageTitle';
import { genreColorMap } from '@app/components/Discover/constants';
import GenreCard from '@app/components/GenreCard';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { GenreSliderItem } from '@server/interfaces/api/discoverInterfaces';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.MovieGenreList', {
moviegenres: 'Movie Genres',
});
diff --git a/src/components/Discover/MovieGenreSlider/index.tsx b/src/components/Discover/MovieGenreSlider/index.tsx
index 23a6cf2d..84ca7a7e 100644
--- a/src/components/Discover/MovieGenreSlider/index.tsx
+++ b/src/components/Discover/MovieGenreSlider/index.tsx
@@ -1,14 +1,15 @@
import { genreColorMap } from '@app/components/Discover/constants';
import GenreCard from '@app/components/GenreCard';
import Slider from '@app/components/Slider';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowRightCircleIcon } from '@heroicons/react/24/outline';
import type { GenreSliderItem } from '@server/interfaces/api/discoverInterfaces';
import Link from 'next/link';
import React from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.MovieGenreSlider', {
moviegenres: 'Movie Genres',
});
diff --git a/src/components/Discover/NetworkSlider/index.tsx b/src/components/Discover/NetworkSlider/index.tsx
index 300219d9..f19cce2c 100644
--- a/src/components/Discover/NetworkSlider/index.tsx
+++ b/src/components/Discover/NetworkSlider/index.tsx
@@ -1,8 +1,9 @@
import CompanyCard from '@app/components/CompanyCard';
import Slider from '@app/components/Slider';
-import { defineMessages, useIntl } from 'react-intl';
+import defineMessages from '@app/utils/defineMessages';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.NetworkSlider', {
networks: 'Networks',
});
diff --git a/src/components/Discover/PlexWatchlistSlider/index.tsx b/src/components/Discover/PlexWatchlistSlider/index.tsx
index 07c0722b..6a8d5717 100644
--- a/src/components/Discover/PlexWatchlistSlider/index.tsx
+++ b/src/components/Discover/PlexWatchlistSlider/index.tsx
@@ -1,13 +1,14 @@
import Slider from '@app/components/Slider';
import TmdbTitleCard from '@app/components/TitleCard/TmdbTitleCard';
import { useUser } from '@app/hooks/useUser';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowRightCircleIcon } from '@heroicons/react/24/outline';
import type { WatchlistItem } from '@server/interfaces/api/discoverInterfaces';
import Link from 'next/link';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.PlexWatchlistSlider', {
plexwatchlist: 'Your Watchlist',
emptywatchlist:
'Media added to your Plex Watchlist will appear here.',
diff --git a/src/components/Discover/RecentlyAddedSlider/index.tsx b/src/components/Discover/RecentlyAddedSlider/index.tsx
index 078f86ba..76f47060 100644
--- a/src/components/Discover/RecentlyAddedSlider/index.tsx
+++ b/src/components/Discover/RecentlyAddedSlider/index.tsx
@@ -1,11 +1,12 @@
import Slider from '@app/components/Slider';
import TmdbTitleCard from '@app/components/TitleCard/TmdbTitleCard';
import { Permission, useUser } from '@app/hooks/useUser';
+import defineMessages from '@app/utils/defineMessages';
import type { MediaResultsResponse } from '@server/interfaces/api/mediaInterfaces';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.RecentlyAddedSlider', {
recentlyAdded: 'Recently Added',
});
diff --git a/src/components/Discover/StudioSlider/index.tsx b/src/components/Discover/StudioSlider/index.tsx
index 3f136142..d1e88d45 100644
--- a/src/components/Discover/StudioSlider/index.tsx
+++ b/src/components/Discover/StudioSlider/index.tsx
@@ -1,8 +1,9 @@
import CompanyCard from '@app/components/CompanyCard';
import Slider from '@app/components/Slider';
-import { defineMessages, useIntl } from 'react-intl';
+import defineMessages from '@app/utils/defineMessages';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.StudioSlider', {
studios: 'Studios',
});
diff --git a/src/components/Discover/Trending.tsx b/src/components/Discover/Trending.tsx
index 5210e7d3..fc6e9090 100644
--- a/src/components/Discover/Trending.tsx
+++ b/src/components/Discover/Trending.tsx
@@ -3,14 +3,15 @@ import ListView from '@app/components/Common/ListView';
import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type {
MovieResult,
PersonResult,
TvResult,
} from '@server/models/Search';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover', {
trending: 'Trending',
});
diff --git a/src/components/Discover/TvGenreList/index.tsx b/src/components/Discover/TvGenreList/index.tsx
index 391c51f2..a2c96bfb 100644
--- a/src/components/Discover/TvGenreList/index.tsx
+++ b/src/components/Discover/TvGenreList/index.tsx
@@ -4,11 +4,12 @@ import PageTitle from '@app/components/Common/PageTitle';
import { genreColorMap } from '@app/components/Discover/constants';
import GenreCard from '@app/components/GenreCard';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { GenreSliderItem } from '@server/interfaces/api/discoverInterfaces';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.TvGenreList', {
seriesgenres: 'Series Genres',
});
diff --git a/src/components/Discover/TvGenreSlider/index.tsx b/src/components/Discover/TvGenreSlider/index.tsx
index 7380bee7..6d733427 100644
--- a/src/components/Discover/TvGenreSlider/index.tsx
+++ b/src/components/Discover/TvGenreSlider/index.tsx
@@ -1,14 +1,15 @@
import { genreColorMap } from '@app/components/Discover/constants';
import GenreCard from '@app/components/GenreCard';
import Slider from '@app/components/Slider';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowRightCircleIcon } from '@heroicons/react/24/outline';
import type { GenreSliderItem } from '@server/interfaces/api/discoverInterfaces';
import Link from 'next/link';
import React from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover.TvGenreSlider', {
tvgenres: 'Series Genres',
});
diff --git a/src/components/Discover/Upcoming.tsx b/src/components/Discover/Upcoming.tsx
index b556e6f9..a358e995 100644
--- a/src/components/Discover/Upcoming.tsx
+++ b/src/components/Discover/Upcoming.tsx
@@ -3,10 +3,11 @@ import ListView from '@app/components/Common/ListView';
import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { MovieResult } from '@server/models/Search';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover', {
upcomingmovies: 'Upcoming Movies',
});
diff --git a/src/components/Discover/constants.ts b/src/components/Discover/constants.ts
index c7013f9c..42d0dab0 100644
--- a/src/components/Discover/constants.ts
+++ b/src/components/Discover/constants.ts
@@ -1,5 +1,5 @@
+import defineMessages from '@app/utils/defineMessages';
import type { ParsedUrlQuery } from 'querystring';
-import { defineMessages } from 'react-intl';
import { z } from 'zod';
type AvailableColors =
@@ -66,7 +66,7 @@ export const genreColorMap: Record = {
10768: colorTones.darkred, // War & Politics
};
-export const sliderTitles = defineMessages({
+export const sliderTitles = defineMessages('components.Discover', {
recentrequests: 'Recent Requests',
popularmovies: 'Popular Movies',
populartv: 'Popular Series',
diff --git a/src/components/Discover/index.tsx b/src/components/Discover/index.tsx
index 38875dbe..d46e9955 100644
--- a/src/components/Discover/index.tsx
+++ b/src/components/Discover/index.tsx
@@ -17,6 +17,7 @@ import MediaSlider from '@app/components/MediaSlider';
import { encodeURIExtraParams } from '@app/hooks/useDiscover';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import {
ArrowDownOnSquareIcon,
@@ -29,11 +30,11 @@ import { DiscoverSliderType } from '@server/constants/discover';
import type DiscoverSlider from '@server/entity/DiscoverSlider';
import axios from 'axios';
import { useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.Discover', {
discover: 'Discover',
emptywatchlist:
'Media added to your Plex Watchlist will appear here.',
diff --git a/src/components/DownloadBlock/index.tsx b/src/components/DownloadBlock/index.tsx
index 6bb04b54..c370e81d 100644
--- a/src/components/DownloadBlock/index.tsx
+++ b/src/components/DownloadBlock/index.tsx
@@ -1,9 +1,10 @@
import Badge from '@app/components/Common/Badge';
import { Permission, useUser } from '@app/hooks/useUser';
+import defineMessages from '@app/utils/defineMessages';
import type { DownloadingItem } from '@server/lib/downloadtracker';
-import { defineMessages, FormattedRelativeTime, useIntl } from 'react-intl';
+import { FormattedRelativeTime, useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.DownloadBlock', {
estimatedtime: 'Estimated {time}',
formattedTitle: '{title}: Season {seasonNumber} Episode {episodeNumber}',
});
diff --git a/src/components/IssueDetails/IssueComment/index.tsx b/src/components/IssueDetails/IssueComment/index.tsx
index 1546746e..f0ec8a5a 100644
--- a/src/components/IssueDetails/IssueComment/index.tsx
+++ b/src/components/IssueDetails/IssueComment/index.tsx
@@ -1,6 +1,7 @@
import Button from '@app/components/Common/Button';
import Modal from '@app/components/Common/Modal';
import { Permission, useUser } from '@app/hooks/useUser';
+import defineMessages from '@app/utils/defineMessages';
import { Menu, Transition } from '@headlessui/react';
import { EllipsisVerticalIcon } from '@heroicons/react/24/solid';
import type { default as IssueCommentType } from '@server/entity/IssueComment';
@@ -9,11 +10,11 @@ import { Field, Form, Formik } from 'formik';
import Image from 'next/image';
import Link from 'next/link';
import { Fragment, useState } from 'react';
-import { defineMessages, FormattedRelativeTime, useIntl } from 'react-intl';
+import { FormattedRelativeTime, useIntl } from 'react-intl';
import ReactMarkdown from 'react-markdown';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.IssueDetails.IssueComment', {
postedby: 'Posted {relativeTime} by {username}',
postedbyedited: 'Posted {relativeTime} by {username} (Edited)',
delete: 'Delete Comment',
diff --git a/src/components/IssueDetails/IssueDescription/index.tsx b/src/components/IssueDetails/IssueDescription/index.tsx
index 7dc8c8d3..e20bf4e9 100644
--- a/src/components/IssueDetails/IssueDescription/index.tsx
+++ b/src/components/IssueDetails/IssueDescription/index.tsx
@@ -1,14 +1,15 @@
import Button from '@app/components/Common/Button';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { Menu, Transition } from '@headlessui/react';
import { EllipsisVerticalIcon } from '@heroicons/react/24/solid';
import { Field, Form, Formik } from 'formik';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import ReactMarkdown from 'react-markdown';
-const messages = defineMessages({
+const messages = defineMessages('components.IssueDetails.IssueDescription', {
description: 'Description',
edit: 'Edit Description',
deleteissue: 'Delete Issue',
diff --git a/src/components/IssueDetails/index.tsx b/src/components/IssueDetails/index.tsx
index 23af2d90..0c6e831f 100644
--- a/src/components/IssueDetails/index.tsx
+++ b/src/components/IssueDetails/index.tsx
@@ -12,6 +12,7 @@ import useSettings from '@app/hooks/useSettings';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import {
ChatBubbleOvalLeftEllipsisIcon,
@@ -33,12 +34,12 @@ import Image from 'next/image';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useState } from 'react';
-import { defineMessages, FormattedRelativeTime, useIntl } from 'react-intl';
+import { FormattedRelativeTime, useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.IssueDetails', {
openedby: '#{issueId} opened {relativeTime} by {username}',
closeissue: 'Close Issue',
closeissueandcomment: 'Close with Comment',
diff --git a/src/components/IssueList/IssueItem/index.tsx b/src/components/IssueList/IssueItem/index.tsx
index 381cd414..b5b16dda 100644
--- a/src/components/IssueList/IssueItem/index.tsx
+++ b/src/components/IssueList/IssueItem/index.tsx
@@ -4,6 +4,7 @@ import CachedImage from '@app/components/Common/CachedImage';
import { issueOptions } from '@app/components/IssueModal/constants';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { EyeIcon } from '@heroicons/react/24/solid';
import { IssueStatus } from '@server/constants/issue';
import { MediaType } from '@server/constants/media';
@@ -13,10 +14,10 @@ import type { TvDetails } from '@server/models/Tv';
import Image from 'next/image';
import Link from 'next/link';
import { useInView } from 'react-intersection-observer';
-import { defineMessages, FormattedRelativeTime, useIntl } from 'react-intl';
+import { FormattedRelativeTime, useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.IssueList.IssueItem', {
openeduserdate: '{date} by {user}',
seasons: '{seasonCount, plural, one {Season} other {Seasons}}',
episodes: '{episodeCount, plural, one {Episode} other {Episodes}}',
diff --git a/src/components/IssueList/index.tsx b/src/components/IssueList/index.tsx
index fe68ed66..5478d79e 100644
--- a/src/components/IssueList/index.tsx
+++ b/src/components/IssueList/index.tsx
@@ -5,6 +5,7 @@ import PageTitle from '@app/components/Common/PageTitle';
import IssueItem from '@app/components/IssueList/IssueItem';
import { useUpdateQueryParams } from '@app/hooks/useUpdateQueryParams';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import {
BarsArrowDownIcon,
ChevronLeftIcon,
@@ -14,10 +15,10 @@ import {
import type { IssueResultsResponse } from '@server/interfaces/api/issueInterfaces';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.IssueList', {
issues: 'Issues',
sortAdded: 'Most Recent',
sortModified: 'Last Modified',
diff --git a/src/components/IssueModal/CreateIssueModal/index.tsx b/src/components/IssueModal/CreateIssueModal/index.tsx
index c50dd2d7..7af3e495 100644
--- a/src/components/IssueModal/CreateIssueModal/index.tsx
+++ b/src/components/IssueModal/CreateIssueModal/index.tsx
@@ -4,6 +4,7 @@ import { issueOptions } from '@app/components/IssueModal/constants';
import useSettings from '@app/hooks/useSettings';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { RadioGroup } from '@headlessui/react';
import { ArrowRightCircleIcon } from '@heroicons/react/24/solid';
import { MediaStatus } from '@server/constants/media';
@@ -13,12 +14,12 @@ import type { TvDetails } from '@server/models/Tv';
import axios from 'axios';
import { Field, Formik } from 'formik';
import Link from 'next/link';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.IssueModal.CreateIssueModal', {
validationMessageRequired: 'You must provide a description',
whatswrong: "What's wrong?",
providedetail:
diff --git a/src/components/IssueModal/constants.ts b/src/components/IssueModal/constants.ts
index 7552c633..0a62e210 100644
--- a/src/components/IssueModal/constants.ts
+++ b/src/components/IssueModal/constants.ts
@@ -1,8 +1,8 @@
+import defineMessages from '@app/utils/defineMessages';
import { IssueType } from '@server/constants/issue';
import type { MessageDescriptor } from 'react-intl';
-import { defineMessages } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.IssueModal', {
issueAudio: 'Audio',
issueVideo: 'Video',
issueSubtitles: 'Subtitle',
diff --git a/src/components/LanguageSelector/index.tsx b/src/components/LanguageSelector/index.tsx
index d8e4cc2f..d7b9853c 100644
--- a/src/components/LanguageSelector/index.tsx
+++ b/src/components/LanguageSelector/index.tsx
@@ -1,13 +1,14 @@
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import type { Language } from '@server/lib/settings';
import { sortBy } from 'lodash';
import { useMemo } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import type { CSSObjectWithLabel } from 'react-select';
import Select from 'react-select';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.LanguageSelector', {
originalLanguageDefault: 'All Languages',
languageServerDefault: 'Default ({language})',
});
diff --git a/src/components/Layout/LanguagePicker/index.tsx b/src/components/Layout/LanguagePicker/index.tsx
index 3ab1f74a..c213fe78 100644
--- a/src/components/Layout/LanguagePicker/index.tsx
+++ b/src/components/Layout/LanguagePicker/index.tsx
@@ -2,12 +2,13 @@ import type { AvailableLocale } from '@app/context/LanguageContext';
import { availableLanguages } from '@app/context/LanguageContext';
import useClickOutside from '@app/hooks/useClickOutside';
import useLocale from '@app/hooks/useLocale';
+import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import { LanguageIcon } from '@heroicons/react/24/solid';
import { useRef, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Layout.LanguagePicker', {
displaylanguage: 'Display Language',
});
diff --git a/src/components/Layout/SearchInput/index.tsx b/src/components/Layout/SearchInput/index.tsx
index 5c2dc167..fa8eb304 100644
--- a/src/components/Layout/SearchInput/index.tsx
+++ b/src/components/Layout/SearchInput/index.tsx
@@ -1,9 +1,10 @@
import useSearchInput from '@app/hooks/useSearchInput';
+import defineMessages from '@app/utils/defineMessages';
import { XCircleIcon } from '@heroicons/react/24/outline';
import { MagnifyingGlassIcon } from '@heroicons/react/24/solid';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Layout.SearchInput', {
searchPlaceholder: 'Search Movies & TV',
});
diff --git a/src/components/Layout/Sidebar/index.tsx b/src/components/Layout/Sidebar/index.tsx
index e8bbc41c..c36d7a7a 100644
--- a/src/components/Layout/Sidebar/index.tsx
+++ b/src/components/Layout/Sidebar/index.tsx
@@ -2,6 +2,7 @@ import UserWarnings from '@app/components/Layout/UserWarnings';
import VersionStatus from '@app/components/Layout/VersionStatus';
import useClickOutside from '@app/hooks/useClickOutside';
import { Permission, useUser } from '@app/hooks/useUser';
+import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import {
ClockIcon,
@@ -17,9 +18,9 @@ import Image from 'next/image';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { Fragment, useRef } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-export const menuMessages = defineMessages({
+export const menuMessages = defineMessages('components.Layout.Sidebar', {
dashboard: 'Discover',
browsemovies: 'Movies',
browsetv: 'Series',
diff --git a/src/components/Layout/UserDropdown/MiniQuotaDisplay/index.tsx b/src/components/Layout/UserDropdown/MiniQuotaDisplay/index.tsx
index abc08dd1..904dc34d 100644
--- a/src/components/Layout/UserDropdown/MiniQuotaDisplay/index.tsx
+++ b/src/components/Layout/UserDropdown/MiniQuotaDisplay/index.tsx
@@ -1,11 +1,12 @@
import Infinity from '@app/assets/infinity.svg';
import { SmallLoadingSpinner } from '@app/components/Common/LoadingSpinner';
import ProgressCircle from '@app/components/Common/ProgressCircle';
+import defineMessages from '@app/utils/defineMessages';
import type { QuotaResponse } from '@server/interfaces/api/userInterfaces';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.UserDropdown.MiniQuotaDisplay', {
movierequests: 'Movie Requests',
seriesrequests: 'Series Requests',
});
diff --git a/src/components/Layout/UserDropdown/index.tsx b/src/components/Layout/UserDropdown/index.tsx
index 7b4c57da..212e1abd 100644
--- a/src/components/Layout/UserDropdown/index.tsx
+++ b/src/components/Layout/UserDropdown/index.tsx
@@ -1,5 +1,6 @@
import MiniQuotaDisplay from '@app/components/Layout/UserDropdown/MiniQuotaDisplay';
import { useUser } from '@app/hooks/useUser';
+import defineMessages from '@app/utils/defineMessages';
import { Menu, Transition } from '@headlessui/react';
import {
ArrowRightOnRectangleIcon,
@@ -11,9 +12,9 @@ import Image from 'next/image';
import type { LinkProps } from 'next/link';
import Link from 'next/link';
import { forwardRef, Fragment } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Layout.UserDropdown', {
myprofile: 'Profile',
settings: 'Settings',
requests: 'Requests',
diff --git a/src/components/Layout/UserWarnings/index.tsx b/src/components/Layout/UserWarnings/index.tsx
index 05180991..42c0a3cc 100644
--- a/src/components/Layout/UserWarnings/index.tsx
+++ b/src/components/Layout/UserWarnings/index.tsx
@@ -1,9 +1,10 @@
import { useUser } from '@app/hooks/useUser';
+import defineMessages from '@app/utils/defineMessages';
import { ExclamationTriangleIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Layout.UserWarnings', {
emailRequired: 'An email address is required.',
emailInvalid: 'Email address is invalid.',
passwordRequired: 'A password is required.',
diff --git a/src/components/Layout/VersionStatus/index.tsx b/src/components/Layout/VersionStatus/index.tsx
index 0429eb05..238e6ce3 100644
--- a/src/components/Layout/VersionStatus/index.tsx
+++ b/src/components/Layout/VersionStatus/index.tsx
@@ -1,3 +1,4 @@
+import defineMessages from '@app/utils/defineMessages';
import {
ArrowUpCircleIcon,
BeakerIcon,
@@ -6,10 +7,10 @@ import {
} from '@heroicons/react/24/outline';
import type { StatusResponse } from '@server/interfaces/api/settingsInterfaces';
import Link from 'next/link';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.Layout.VersionStatus', {
streamdevelop: 'Jellyseerr Develop',
streamstable: 'Jellyseerr Stable',
outofdate: 'Out of Date',
diff --git a/src/components/Login/AddEmailModal.tsx b/src/components/Login/AddEmailModal.tsx
index 2ad55a72..cde0c8bd 100644
--- a/src/components/Login/AddEmailModal.tsx
+++ b/src/components/Login/AddEmailModal.tsx
@@ -1,12 +1,13 @@
import Modal from '@app/components/Common/Modal';
import useSettings from '@app/hooks/useSettings';
+import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import axios from 'axios';
import { Field, Formik } from 'formik';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.Login', {
title: 'Add Email',
description:
'Since this is your first time logging into {applicationName}, you are required to add a valid email address.',
diff --git a/src/components/Login/JellyfinLogin.tsx b/src/components/Login/JellyfinLogin.tsx
index a2f85f81..43b74902 100644
--- a/src/components/Login/JellyfinLogin.tsx
+++ b/src/components/Login/JellyfinLogin.tsx
@@ -1,16 +1,17 @@
import Button from '@app/components/Common/Button';
import Tooltip from '@app/components/Common/Tooltip';
import useSettings from '@app/hooks/useSettings';
+import defineMessages from '@app/utils/defineMessages';
import { InformationCircleIcon } from '@heroicons/react/24/solid';
import { ApiErrorCode } from '@server/constants/error';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import getConfig from 'next/config';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.Login', {
username: 'Username',
password: 'Password',
hostname: '{mediaServerName} URL',
diff --git a/src/components/Login/LocalLogin.tsx b/src/components/Login/LocalLogin.tsx
index 42d85760..a35f30c7 100644
--- a/src/components/Login/LocalLogin.tsx
+++ b/src/components/Login/LocalLogin.tsx
@@ -1,6 +1,7 @@
import Button from '@app/components/Common/Button';
import SensitiveInput from '@app/components/Common/SensitiveInput';
import useSettings from '@app/hooks/useSettings';
+import defineMessages from '@app/utils/defineMessages';
import {
ArrowLeftOnRectangleIcon,
LifebuoyIcon,
@@ -9,10 +10,10 @@ import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import Link from 'next/link';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.Login', {
username: 'Username',
email: 'Email Address',
password: 'Password',
diff --git a/src/components/Login/index.tsx b/src/components/Login/index.tsx
index 2c8778e0..9c967068 100644
--- a/src/components/Login/index.tsx
+++ b/src/components/Login/index.tsx
@@ -6,6 +6,7 @@ import LocalLogin from '@app/components/Login/LocalLogin';
import PlexLoginButton from '@app/components/PlexLoginButton';
import useSettings from '@app/hooks/useSettings';
import { useUser } from '@app/hooks/useUser';
+import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import { XCircleIcon } from '@heroicons/react/24/solid';
import { MediaServerType } from '@server/constants/server';
@@ -14,11 +15,11 @@ import getConfig from 'next/config';
import { useRouter } from 'next/dist/client/router';
import Image from 'next/image';
import { useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
import JellyfinLogin from './JellyfinLogin';
-const messages = defineMessages({
+const messages = defineMessages('components.Login', {
signin: 'Sign In',
signinheader: 'Sign in to continue',
signinwithplex: 'Use your Plex account',
diff --git a/src/components/ManageSlideOver/index.tsx b/src/components/ManageSlideOver/index.tsx
index a7335ceb..785fb71b 100644
--- a/src/components/ManageSlideOver/index.tsx
+++ b/src/components/ManageSlideOver/index.tsx
@@ -8,6 +8,7 @@ import RequestBlock from '@app/components/RequestBlock';
import useSettings from '@app/hooks/useSettings';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { Bars4Icon, ServerIcon } from '@heroicons/react/24/outline';
import {
CheckCircleIcon,
@@ -29,10 +30,10 @@ import axios from 'axios';
import getConfig from 'next/config';
import Image from 'next/image';
import Link from 'next/link';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.ManageSlideOver', {
manageModalTitle: 'Manage {mediaType}',
manageModalIssues: 'Open Issues',
manageModalRequests: 'Requests',
diff --git a/src/components/MediaSlider/ShowMoreCard/index.tsx b/src/components/MediaSlider/ShowMoreCard/index.tsx
index 794ef9e9..d705aabf 100644
--- a/src/components/MediaSlider/ShowMoreCard/index.tsx
+++ b/src/components/MediaSlider/ShowMoreCard/index.tsx
@@ -1,12 +1,13 @@
import TitleCard from '@app/components/TitleCard';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowRightCircleIcon } from '@heroicons/react/24/solid';
import Image from 'next/image';
import Link from 'next/link';
import { useState } from 'react';
import { useInView } from 'react-intersection-observer';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.MediaSlider.ShowMoreCard', {
seemore: 'See More',
});
diff --git a/src/components/MovieDetails/MovieCast/index.tsx b/src/components/MovieDetails/MovieCast/index.tsx
index 0ff95119..54066409 100644
--- a/src/components/MovieDetails/MovieCast/index.tsx
+++ b/src/components/MovieDetails/MovieCast/index.tsx
@@ -3,13 +3,14 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import PageTitle from '@app/components/Common/PageTitle';
import PersonCard from '@app/components/PersonCard';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { MovieDetails } from '@server/models/Movie';
import Link from 'next/link';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.MovieDetails.MovieCast', {
fullcast: 'Full Cast',
});
diff --git a/src/components/MovieDetails/MovieCrew/index.tsx b/src/components/MovieDetails/MovieCrew/index.tsx
index da52d35f..488bf294 100644
--- a/src/components/MovieDetails/MovieCrew/index.tsx
+++ b/src/components/MovieDetails/MovieCrew/index.tsx
@@ -3,13 +3,14 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import PageTitle from '@app/components/Common/PageTitle';
import PersonCard from '@app/components/PersonCard';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { MovieDetails } from '@server/models/Movie';
import Link from 'next/link';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.MovieDetails.MovieCrew', {
fullcrew: 'Full Crew',
});
diff --git a/src/components/MovieDetails/MovieRecommendations.tsx b/src/components/MovieDetails/MovieRecommendations.tsx
index 54bfb217..4cbd607b 100644
--- a/src/components/MovieDetails/MovieRecommendations.tsx
+++ b/src/components/MovieDetails/MovieRecommendations.tsx
@@ -3,14 +3,15 @@ import ListView from '@app/components/Common/ListView';
import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { MovieDetails } from '@server/models/Movie';
import type { MovieResult } from '@server/models/Search';
import Link from 'next/link';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.MovieDetails', {
recommendations: 'Recommendations',
});
diff --git a/src/components/MovieDetails/MovieSimilar.tsx b/src/components/MovieDetails/MovieSimilar.tsx
index efdfb3df..fbb2274a 100644
--- a/src/components/MovieDetails/MovieSimilar.tsx
+++ b/src/components/MovieDetails/MovieSimilar.tsx
@@ -3,14 +3,15 @@ import ListView from '@app/components/Common/ListView';
import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { MovieDetails } from '@server/models/Movie';
import type { MovieResult } from '@server/models/Search';
import Link from 'next/link';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.MovieDetails', {
similar: 'Similar Titles',
});
diff --git a/src/components/MovieDetails/index.tsx b/src/components/MovieDetails/index.tsx
index f826f868..434d29ff 100644
--- a/src/components/MovieDetails/index.tsx
+++ b/src/components/MovieDetails/index.tsx
@@ -27,6 +27,7 @@ import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
import { sortCrewPriority } from '@app/utils/creditHelpers';
+import defineMessages from '@app/utils/defineMessages';
import { refreshIntervalHelper } from '@app/utils/refreshIntervalHelper';
import {
ArrowRightCircleIcon,
@@ -53,10 +54,10 @@ import getConfig from 'next/config';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useEffect, useMemo, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.MovieDetails', {
originaltitle: 'Original Title',
releasedate:
'{releaseCount, plural, one {Release Date} other {Release Dates}}',
diff --git a/src/components/NotificationTypeSelector/index.tsx b/src/components/NotificationTypeSelector/index.tsx
index 984d0b4f..e24eb9b1 100644
--- a/src/components/NotificationTypeSelector/index.tsx
+++ b/src/components/NotificationTypeSelector/index.tsx
@@ -2,11 +2,12 @@ import NotificationType from '@app/components/NotificationTypeSelector/Notificat
import useSettings from '@app/hooks/useSettings';
import type { User } from '@app/hooks/useUser';
import { Permission, useUser } from '@app/hooks/useUser';
+import defineMessages from '@app/utils/defineMessages';
import { sortBy } from 'lodash';
import { useMemo, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.NotificationTypeSelector', {
notificationTypes: 'Notification Types',
mediarequested: 'Request Pending Approval',
mediarequestedDescription:
diff --git a/src/components/PermissionEdit/index.tsx b/src/components/PermissionEdit/index.tsx
index 82971bf0..a220335b 100644
--- a/src/components/PermissionEdit/index.tsx
+++ b/src/components/PermissionEdit/index.tsx
@@ -3,10 +3,11 @@ import PermissionOption from '@app/components/PermissionOption';
import useSettings from '@app/hooks/useSettings';
import type { User } from '@app/hooks/useUser';
import { Permission } from '@app/hooks/useUser';
+import defineMessages from '@app/utils/defineMessages';
import { MediaServerType } from '@server/constants/server';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-export const messages = defineMessages({
+export const messages = defineMessages('components.PermissionEdit', {
admin: 'Admin',
adminDescription:
'Full administrator access. Bypasses all other permission checks.',
diff --git a/src/components/PersonDetails/index.tsx b/src/components/PersonDetails/index.tsx
index 3b79a537..5273d0a3 100644
--- a/src/components/PersonDetails/index.tsx
+++ b/src/components/PersonDetails/index.tsx
@@ -6,16 +6,17 @@ import PageTitle from '@app/components/Common/PageTitle';
import TitleCard from '@app/components/TitleCard';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { PersonCombinedCreditsResponse } from '@server/interfaces/api/personInterfaces';
import type { PersonDetails as PersonDetailsType } from '@server/models/Person';
import { groupBy } from 'lodash';
import { useRouter } from 'next/router';
import { useMemo, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import TruncateMarkup from 'react-truncate-markup';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.PersonDetails', {
birthdate: 'Born {birthdate}',
lifespan: '{birthdate} – {deathdate}',
alsoknownas: 'Also Known As: {names}',
diff --git a/src/components/PlexLoginButton/index.tsx b/src/components/PlexLoginButton/index.tsx
index 36323173..3cf1d3ee 100644
--- a/src/components/PlexLoginButton/index.tsx
+++ b/src/components/PlexLoginButton/index.tsx
@@ -1,10 +1,11 @@
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import PlexOAuth from '@app/utils/plex';
import { ArrowLeftOnRectangleIcon } from '@heroicons/react/24/outline';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.PlexLoginButton', {
signinwithplex: 'Sign In',
signingin: 'Signing In…',
});
diff --git a/src/components/QuotaSelector/index.tsx b/src/components/QuotaSelector/index.tsx
index 7240dbc2..0f0454e2 100644
--- a/src/components/QuotaSelector/index.tsx
+++ b/src/components/QuotaSelector/index.tsx
@@ -1,7 +1,8 @@
+import defineMessages from '@app/utils/defineMessages';
import React, { useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.QuotaSelector', {
movieRequests:
'{quotaLimit} {movies} per {quotaDays} {days}',
tvRequests:
diff --git a/src/components/RegionSelector/index.tsx b/src/components/RegionSelector/index.tsx
index 0a6a0f2a..41383053 100644
--- a/src/components/RegionSelector/index.tsx
+++ b/src/components/RegionSelector/index.tsx
@@ -1,4 +1,5 @@
import useSettings from '@app/hooks/useSettings';
+import defineMessages from '@app/utils/defineMessages';
import { Listbox, Transition } from '@headlessui/react';
import { CheckIcon, ChevronDownIcon } from '@heroicons/react/24/solid';
import type { Region } from '@server/lib/settings';
@@ -6,10 +7,10 @@ import { countries } from 'country-flag-icons';
import 'country-flag-icons/3x2/flags.css';
import { sortBy } from 'lodash';
import { useEffect, useMemo, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.RegionSelector', {
regionDefault: 'All Regions',
regionServerDefault: 'Default ({region})',
});
diff --git a/src/components/RequestBlock/index.tsx b/src/components/RequestBlock/index.tsx
index 3da1d6ad..2fe1d913 100644
--- a/src/components/RequestBlock/index.tsx
+++ b/src/components/RequestBlock/index.tsx
@@ -5,6 +5,7 @@ import RequestModal from '@app/components/RequestModal';
import useRequestOverride from '@app/hooks/useRequestOverride';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import {
CalendarIcon,
CheckIcon,
@@ -19,9 +20,9 @@ import type { MediaRequest } from '@server/entity/MediaRequest';
import axios from 'axios';
import Link from 'next/link';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.RequestBlock', {
seasons: '{seasonCount, plural, one {Season} other {Seasons}}',
requestoverrides: 'Request Overrides',
server: 'Destination Server',
diff --git a/src/components/RequestButton/index.tsx b/src/components/RequestButton/index.tsx
index 56e91810..78efe21f 100644
--- a/src/components/RequestButton/index.tsx
+++ b/src/components/RequestButton/index.tsx
@@ -3,6 +3,7 @@ import RequestModal from '@app/components/RequestModal';
import useSettings from '@app/hooks/useSettings';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownTrayIcon } from '@heroicons/react/24/outline';
import {
CheckIcon,
@@ -14,9 +15,9 @@ import type Media from '@server/entity/Media';
import type { MediaRequest } from '@server/entity/MediaRequest';
import axios from 'axios';
import { useMemo, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.RequestButton', {
viewrequest: 'View Request',
viewrequest4k: 'View 4K Request',
requestmore: 'Request More',
diff --git a/src/components/RequestCard/index.tsx b/src/components/RequestCard/index.tsx
index 63ea6f9d..0f4f0293 100644
--- a/src/components/RequestCard/index.tsx
+++ b/src/components/RequestCard/index.tsx
@@ -7,6 +7,7 @@ import StatusBadge from '@app/components/StatusBadge';
import useDeepLinks from '@app/hooks/useDeepLinks';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { refreshIntervalHelper } from '@app/utils/refreshIntervalHelper';
import { withProperties } from '@app/utils/typeHelpers';
import {
@@ -25,11 +26,11 @@ import Image from 'next/image';
import Link from 'next/link';
import { useEffect, useState } from 'react';
import { useInView } from 'react-intersection-observer';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR, { mutate } from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.RequestCard', {
seasons: '{seasonCount, plural, one {Season} other {Seasons}}',
failedretry: 'Something went wrong while retrying the request.',
mediaerror: '{mediaType} Not Found',
diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx
index 41507356..fb151a76 100644
--- a/src/components/RequestList/RequestItem/index.tsx
+++ b/src/components/RequestList/RequestItem/index.tsx
@@ -7,6 +7,7 @@ import StatusBadge from '@app/components/StatusBadge';
import useDeepLinks from '@app/hooks/useDeepLinks';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { refreshIntervalHelper } from '@app/utils/refreshIntervalHelper';
import {
ArrowPathIcon,
@@ -24,11 +25,11 @@ import Image from 'next/image';
import Link from 'next/link';
import { useState } from 'react';
import { useInView } from 'react-intersection-observer';
-import { defineMessages, FormattedRelativeTime, useIntl } from 'react-intl';
+import { FormattedRelativeTime, useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.RequestList.RequestItem', {
seasons: '{seasonCount, plural, one {Season} other {Seasons}}',
failedretry: 'Something went wrong while retrying the request.',
requested: 'Requested',
diff --git a/src/components/RequestList/index.tsx b/src/components/RequestList/index.tsx
index a381bb15..8d56d56e 100644
--- a/src/components/RequestList/index.tsx
+++ b/src/components/RequestList/index.tsx
@@ -6,6 +6,7 @@ import RequestItem from '@app/components/RequestList/RequestItem';
import { useUpdateQueryParams } from '@app/hooks/useUpdateQueryParams';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import {
BarsArrowDownIcon,
ChevronLeftIcon,
@@ -16,10 +17,10 @@ import type { RequestResultsResponse } from '@server/interfaces/api/requestInter
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.RequestList', {
requests: 'Requests',
showallrequests: 'Show All Requests',
sortAdded: 'Most Recent',
diff --git a/src/components/RequestModal/AdvancedRequester/index.tsx b/src/components/RequestModal/AdvancedRequester/index.tsx
index 48838d0b..18aff5e2 100644
--- a/src/components/RequestModal/AdvancedRequester/index.tsx
+++ b/src/components/RequestModal/AdvancedRequester/index.tsx
@@ -3,6 +3,7 @@ import { SmallLoadingSpinner } from '@app/components/Common/LoadingSpinner';
import type { User } from '@app/hooks/useUser';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { formatBytes } from '@app/utils/numberHelpers';
import { Listbox, Transition } from '@headlessui/react';
import { CheckIcon, ChevronDownIcon } from '@heroicons/react/24/solid';
@@ -15,7 +16,7 @@ import { hasPermission } from '@server/lib/permissions';
import { isEqual } from 'lodash';
import Image from 'next/image';
import { useEffect, useMemo, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import Select from 'react-select';
import useSWR from 'swr';
@@ -24,7 +25,7 @@ type OptionType = {
label: string;
};
-const messages = defineMessages({
+const messages = defineMessages('components.RequestModal.AdvancedRequester', {
advancedoptions: 'Advanced',
destinationserver: 'Destination Server',
qualityprofile: 'Quality Profile',
diff --git a/src/components/RequestModal/CollectionRequestModal.tsx b/src/components/RequestModal/CollectionRequestModal.tsx
index 4101537e..dcafbdc0 100644
--- a/src/components/RequestModal/CollectionRequestModal.tsx
+++ b/src/components/RequestModal/CollectionRequestModal.tsx
@@ -7,6 +7,7 @@ import AdvancedRequester from '@app/components/RequestModal/AdvancedRequester';
import QuotaDisplay from '@app/components/RequestModal/QuotaDisplay';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { MediaRequestStatus, MediaStatus } from '@server/constants/media';
import type { MediaRequest } from '@server/entity/MediaRequest';
import type { QuotaResponse } from '@server/interfaces/api/userInterfaces';
@@ -14,11 +15,11 @@ import { Permission } from '@server/lib/permissions';
import type { Collection } from '@server/models/Collection';
import axios from 'axios';
import { useCallback, useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.RequestModal', {
requestadmin: 'This request will be approved automatically.',
requestSuccess: '{title} requested successfully!',
requestcollectiontitle: 'Request Collection',
diff --git a/src/components/RequestModal/MovieRequestModal.tsx b/src/components/RequestModal/MovieRequestModal.tsx
index 76a12638..1e534842 100644
--- a/src/components/RequestModal/MovieRequestModal.tsx
+++ b/src/components/RequestModal/MovieRequestModal.tsx
@@ -5,6 +5,7 @@ import AdvancedRequester from '@app/components/RequestModal/AdvancedRequester';
import QuotaDisplay from '@app/components/RequestModal/QuotaDisplay';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { MediaStatus } from '@server/constants/media';
import type { MediaRequest } from '@server/entity/MediaRequest';
import type { QuotaResponse } from '@server/interfaces/api/userInterfaces';
@@ -12,11 +13,11 @@ import { Permission } from '@server/lib/permissions';
import type { MovieDetails } from '@server/models/Movie';
import axios from 'axios';
import { useCallback, useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR, { mutate } from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.RequestModal', {
requestadmin: 'This request will be approved automatically.',
requestSuccess: '{title} requested successfully!',
requestCancel: 'Request for {title} canceled.',
diff --git a/src/components/RequestModal/QuotaDisplay/index.tsx b/src/components/RequestModal/QuotaDisplay/index.tsx
index f6da26ad..99ffaab0 100644
--- a/src/components/RequestModal/QuotaDisplay/index.tsx
+++ b/src/components/RequestModal/QuotaDisplay/index.tsx
@@ -1,11 +1,12 @@
import ProgressCircle from '@app/components/Common/ProgressCircle';
+import defineMessages from '@app/utils/defineMessages';
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/solid';
import type { QuotaStatus } from '@server/interfaces/api/userInterfaces';
import Link from 'next/link';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.RequestModal.QuotaDisplay', {
requestsremaining:
'{remaining, plural, =0 {No} other {#}} {type} {remaining, plural, one {request} other {requests}} remaining',
movielimit: '{limit, plural, one {movie} other {movies}}',
diff --git a/src/components/RequestModal/SearchByNameModal/index.tsx b/src/components/RequestModal/SearchByNameModal/index.tsx
index 846434d5..0ef7e55b 100644
--- a/src/components/RequestModal/SearchByNameModal/index.tsx
+++ b/src/components/RequestModal/SearchByNameModal/index.tsx
@@ -1,12 +1,13 @@
import Alert from '@app/components/Common/Alert';
import Modal from '@app/components/Common/Modal';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import type { SonarrSeries } from '@server/api/servarr/sonarr';
import Image from 'next/image';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.RequestModal.SearchByNameModal', {
notvdbiddescription:
'We were unable to automatically match this series. Please select the correct match below.',
nomatches: 'We were unable to find a match for this series.',
diff --git a/src/components/RequestModal/TvRequestModal.tsx b/src/components/RequestModal/TvRequestModal.tsx
index 25c8fd3c..65ee302b 100644
--- a/src/components/RequestModal/TvRequestModal.tsx
+++ b/src/components/RequestModal/TvRequestModal.tsx
@@ -8,6 +8,7 @@ import SearchByNameModal from '@app/components/RequestModal/SearchByNameModal';
import useSettings from '@app/hooks/useSettings';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ANIME_KEYWORD_ID } from '@server/api/themoviedb/constants';
import { MediaRequestStatus, MediaStatus } from '@server/constants/media';
import type { MediaRequest } from '@server/entity/MediaRequest';
@@ -17,11 +18,11 @@ import { Permission } from '@server/lib/permissions';
import type { TvDetails } from '@server/models/Tv';
import axios from 'axios';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR, { mutate } from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.RequestModal', {
requestadmin: 'This request will be approved automatically.',
requestSuccess: '{title} requested successfully!',
requestseriestitle: 'Request Series',
diff --git a/src/components/ResetPassword/RequestResetLink.tsx b/src/components/ResetPassword/RequestResetLink.tsx
index 6209db03..b331bb20 100644
--- a/src/components/ResetPassword/RequestResetLink.tsx
+++ b/src/components/ResetPassword/RequestResetLink.tsx
@@ -2,16 +2,17 @@ import Button from '@app/components/Common/Button';
import ImageFader from '@app/components/Common/ImageFader';
import PageTitle from '@app/components/Common/PageTitle';
import LanguagePicker from '@app/components/Layout/LanguagePicker';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowLeftIcon, EnvelopeIcon } from '@heroicons/react/24/solid';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import Image from 'next/image';
import Link from 'next/link';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.ResetPassword', {
passwordreset: 'Password Reset',
resetpassword: 'Reset your password',
emailresetlink: 'Email Recovery Link',
diff --git a/src/components/ResetPassword/index.tsx b/src/components/ResetPassword/index.tsx
index 325630b4..1923a55c 100644
--- a/src/components/ResetPassword/index.tsx
+++ b/src/components/ResetPassword/index.tsx
@@ -3,6 +3,7 @@ import ImageFader from '@app/components/Common/ImageFader';
import SensitiveInput from '@app/components/Common/SensitiveInput';
import LanguagePicker from '@app/components/Layout/LanguagePicker';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { LifebuoyIcon } from '@heroicons/react/24/outline';
import axios from 'axios';
import { Form, Formik } from 'formik';
@@ -10,10 +11,10 @@ import Image from 'next/image';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.ResetPassword', {
passwordreset: 'Password Reset',
resetpassword: 'Reset your password',
password: 'Password',
diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx
index 22f143f2..9449ab50 100644
--- a/src/components/Search/index.tsx
+++ b/src/components/Search/index.tsx
@@ -3,15 +3,16 @@ import ListView from '@app/components/Common/ListView';
import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type {
MovieResult,
PersonResult,
TvResult,
} from '@server/models/Search';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Search', {
search: 'Search',
searchresults: 'Search Results',
});
diff --git a/src/components/Selector/index.tsx b/src/components/Selector/index.tsx
index 951fddcb..126cdcba 100644
--- a/src/components/Selector/index.tsx
+++ b/src/components/Selector/index.tsx
@@ -4,6 +4,7 @@ import Tooltip from '@app/components/Common/Tooltip';
import RegionSelector from '@app/components/RegionSelector';
import { encodeURIExtraParams } from '@app/hooks/useDiscover';
import useSettings from '@app/hooks/useSettings';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownIcon, ArrowUpIcon } from '@heroicons/react/20/solid';
import { CheckCircleIcon } from '@heroicons/react/24/solid';
import type {
@@ -20,12 +21,12 @@ import type {
import axios from 'axios';
import { orderBy } from 'lodash';
import { useEffect, useMemo, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import type { MultiValue, SingleValue } from 'react-select';
import AsyncSelect from 'react-select/async';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.Selector', {
searchKeywords: 'Search keywords…',
searchGenres: 'Select genres…',
searchStudios: 'Search studios…',
diff --git a/src/components/Settings/CopyButton.tsx b/src/components/Settings/CopyButton.tsx
index c50213d3..485e4027 100644
--- a/src/components/Settings/CopyButton.tsx
+++ b/src/components/Settings/CopyButton.tsx
@@ -1,10 +1,11 @@
+import defineMessages from '@app/utils/defineMessages';
import { ClipboardDocumentIcon } from '@heroicons/react/24/solid';
import { useEffect } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useClipboard from 'react-use-clipboard';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings', {
copied: 'Copied API key to clipboard.',
});
diff --git a/src/components/Settings/Notifications/NotificationsDiscord.tsx b/src/components/Settings/Notifications/NotificationsDiscord.tsx
index 421e76e5..b6ab16b5 100644
--- a/src/components/Settings/Notifications/NotificationsDiscord.tsx
+++ b/src/components/Settings/Notifications/NotificationsDiscord.tsx
@@ -3,16 +3,17 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
import useSettings from '@app/hooks/useSettings';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon, BeakerIcon } from '@heroicons/react/24/outline';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings.Notifications', {
agentenabled: 'Enable Agent',
botUsername: 'Bot Username',
botAvatarUrl: 'Bot Avatar URL',
diff --git a/src/components/Settings/Notifications/NotificationsEmail.tsx b/src/components/Settings/Notifications/NotificationsEmail.tsx
index eb3a34d5..9ff04e6c 100644
--- a/src/components/Settings/Notifications/NotificationsEmail.tsx
+++ b/src/components/Settings/Notifications/NotificationsEmail.tsx
@@ -3,16 +3,17 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import SensitiveInput from '@app/components/Common/SensitiveInput';
import SettingsBadge from '@app/components/Settings/SettingsBadge';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon, BeakerIcon } from '@heroicons/react/24/outline';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR, { mutate } from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings.Notifications', {
validationSmtpHostRequired: 'You must provide a valid hostname or IP address',
validationSmtpPortRequired: 'You must provide a valid port number',
agentenabled: 'Enable Agent',
diff --git a/src/components/Settings/Notifications/NotificationsGotify/index.tsx b/src/components/Settings/Notifications/NotificationsGotify/index.tsx
index 390d2ed9..6288991f 100644
--- a/src/components/Settings/Notifications/NotificationsGotify/index.tsx
+++ b/src/components/Settings/Notifications/NotificationsGotify/index.tsx
@@ -2,29 +2,33 @@ import Button from '@app/components/Common/Button';
import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon, BeakerIcon } from '@heroicons/react/24/solid';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
- agentenabled: 'Enable Agent',
- url: 'Server URL',
- token: 'Application Token',
- validationUrlRequired: 'You must provide a valid URL',
- validationUrlTrailingSlash: 'URL must not end in a trailing slash',
- validationTokenRequired: 'You must provide an application token',
- gotifysettingssaved: 'Gotify notification settings saved successfully!',
- gotifysettingsfailed: 'Gotify notification settings failed to save.',
- toastGotifyTestSending: 'Sending Gotify test notification…',
- toastGotifyTestSuccess: 'Gotify test notification sent!',
- toastGotifyTestFailed: 'Gotify test notification failed to send.',
- validationTypes: 'You must select at least one notification type',
-});
+const messages = defineMessages(
+ 'components.Settings.Notifications.NotificationsGotify',
+ {
+ agentenabled: 'Enable Agent',
+ url: 'Server URL',
+ token: 'Application Token',
+ validationUrlRequired: 'You must provide a valid URL',
+ validationUrlTrailingSlash: 'URL must not end in a trailing slash',
+ validationTokenRequired: 'You must provide an application token',
+ gotifysettingssaved: 'Gotify notification settings saved successfully!',
+ gotifysettingsfailed: 'Gotify notification settings failed to save.',
+ toastGotifyTestSending: 'Sending Gotify test notification…',
+ toastGotifyTestSuccess: 'Gotify test notification sent!',
+ toastGotifyTestFailed: 'Gotify test notification failed to send.',
+ validationTypes: 'You must select at least one notification type',
+ }
+);
const NotificationsGotify = () => {
const intl = useIntl();
diff --git a/src/components/Settings/Notifications/NotificationsLunaSea/index.tsx b/src/components/Settings/Notifications/NotificationsLunaSea/index.tsx
index 390cac3d..fd7c3edc 100644
--- a/src/components/Settings/Notifications/NotificationsLunaSea/index.tsx
+++ b/src/components/Settings/Notifications/NotificationsLunaSea/index.tsx
@@ -2,30 +2,35 @@ import Button from '@app/components/Common/Button';
import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon, BeakerIcon } from '@heroicons/react/24/outline';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
- agentenabled: 'Enable Agent',
- webhookUrl: 'Webhook URL',
- webhookUrlTip:
- 'Your user- or device-based notification webhook URL',
- validationWebhookUrl: 'You must provide a valid URL',
- profileName: 'Profile Name',
- profileNameTip: 'Only required if not using the default profile',
- settingsSaved: 'LunaSea notification settings saved successfully!',
- settingsFailed: 'LunaSea notification settings failed to save.',
- toastLunaSeaTestSending: 'Sending LunaSea test notification…',
- toastLunaSeaTestSuccess: 'LunaSea test notification sent!',
- toastLunaSeaTestFailed: 'LunaSea test notification failed to send.',
- validationTypes: 'You must select at least one notification type',
-});
+const messages = defineMessages(
+ 'components.Notifications.NotificationsLunaSea',
+ {
+ agentenabled: 'Enable Agent',
+ webhookUrl: 'Webhook URL',
+ webhookUrlTip:
+ 'Your user- or device-based notification webhook URL',
+ validationWebhookUrl: 'You must provide a valid URL',
+ profileName: 'Profile Name',
+ profileNameTip:
+ 'Only required if not using the default profile',
+ settingsSaved: 'LunaSea notification settings saved successfully!',
+ settingsFailed: 'LunaSea notification settings failed to save.',
+ toastLunaSeaTestSending: 'Sending LunaSea test notification…',
+ toastLunaSeaTestSuccess: 'LunaSea test notification sent!',
+ toastLunaSeaTestFailed: 'LunaSea test notification failed to send.',
+ validationTypes: 'You must select at least one notification type',
+ }
+);
const NotificationsLunaSea = () => {
const intl = useIntl();
diff --git a/src/components/Settings/Notifications/NotificationsPushbullet/index.tsx b/src/components/Settings/Notifications/NotificationsPushbullet/index.tsx
index 00cd179a..1be09597 100644
--- a/src/components/Settings/Notifications/NotificationsPushbullet/index.tsx
+++ b/src/components/Settings/Notifications/NotificationsPushbullet/index.tsx
@@ -3,30 +3,35 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import SensitiveInput from '@app/components/Common/SensitiveInput';
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon, BeakerIcon } from '@heroicons/react/24/outline';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
- agentEnabled: 'Enable Agent',
- accessToken: 'Access Token',
- accessTokenTip:
- 'Create a token from your Account Settings',
- validationAccessTokenRequired: 'You must provide an access token',
- channelTag: 'Channel Tag',
- pushbulletSettingsSaved:
- 'Pushbullet notification settings saved successfully!',
- pushbulletSettingsFailed: 'Pushbullet notification settings failed to save.',
- toastPushbulletTestSending: 'Sending Pushbullet test notification…',
- toastPushbulletTestSuccess: 'Pushbullet test notification sent!',
- toastPushbulletTestFailed: 'Pushbullet test notification failed to send.',
- validationTypes: 'You must select at least one notification type',
-});
+const messages = defineMessages(
+ 'components.Notifications.NotificationsPushbullet',
+ {
+ agentEnabled: 'Enable Agent',
+ accessToken: 'Access Token',
+ accessTokenTip:
+ 'Create a token from your Account Settings',
+ validationAccessTokenRequired: 'You must provide an access token',
+ channelTag: 'Channel Tag',
+ pushbulletSettingsSaved:
+ 'Pushbullet notification settings saved successfully!',
+ pushbulletSettingsFailed:
+ 'Pushbullet notification settings failed to save.',
+ toastPushbulletTestSending: 'Sending Pushbullet test notification…',
+ toastPushbulletTestSuccess: 'Pushbullet test notification sent!',
+ toastPushbulletTestFailed: 'Pushbullet test notification failed to send.',
+ validationTypes: 'You must select at least one notification type',
+ }
+);
const NotificationsPushbullet = () => {
const intl = useIntl();
diff --git a/src/components/Settings/Notifications/NotificationsPushover/index.tsx b/src/components/Settings/Notifications/NotificationsPushover/index.tsx
index 325dbd31..f62a6706 100644
--- a/src/components/Settings/Notifications/NotificationsPushover/index.tsx
+++ b/src/components/Settings/Notifications/NotificationsPushover/index.tsx
@@ -2,35 +2,39 @@ import Button from '@app/components/Common/Button';
import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon, BeakerIcon } from '@heroicons/react/24/outline';
import type { PushoverSound } from '@server/api/pushover';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
- agentenabled: 'Enable Agent',
- accessToken: 'Application API Token',
- accessTokenTip:
- 'Register an application for use with Jellyseerr',
- userToken: 'User or Group Key',
- userTokenTip:
- 'Your 30-character user or group identifier',
- sound: 'Notification Sound',
- deviceDefault: 'Device Default',
- validationAccessTokenRequired: 'You must provide a valid application token',
- validationUserTokenRequired: 'You must provide a valid user or group key',
- pushoversettingssaved: 'Pushover notification settings saved successfully!',
- pushoversettingsfailed: 'Pushover notification settings failed to save.',
- toastPushoverTestSending: 'Sending Pushover test notification…',
- toastPushoverTestSuccess: 'Pushover test notification sent!',
- toastPushoverTestFailed: 'Pushover test notification failed to send.',
- validationTypes: 'You must select at least one notification type',
-});
+const messages = defineMessages(
+ 'components.Settings.Notifications.NotificationsPushover',
+ {
+ agentenabled: 'Enable Agent',
+ accessToken: 'Application API Token',
+ accessTokenTip:
+ 'Register an application for use with Jellyseerr',
+ userToken: 'User or Group Key',
+ userTokenTip:
+ 'Your 30-character user or group identifier',
+ sound: 'Notification Sound',
+ deviceDefault: 'Device Default',
+ validationAccessTokenRequired: 'You must provide a valid application token',
+ validationUserTokenRequired: 'You must provide a valid user or group key',
+ pushoversettingssaved: 'Pushover notification settings saved successfully!',
+ pushoversettingsfailed: 'Pushover notification settings failed to save.',
+ toastPushoverTestSending: 'Sending Pushover test notification…',
+ toastPushoverTestSuccess: 'Pushover test notification sent!',
+ toastPushoverTestFailed: 'Pushover test notification failed to send.',
+ validationTypes: 'You must select at least one notification type',
+ }
+);
const NotificationsPushover = () => {
const intl = useIntl();
diff --git a/src/components/Settings/Notifications/NotificationsSlack/index.tsx b/src/components/Settings/Notifications/NotificationsSlack/index.tsx
index ac31d3c1..24ea7847 100644
--- a/src/components/Settings/Notifications/NotificationsSlack/index.tsx
+++ b/src/components/Settings/Notifications/NotificationsSlack/index.tsx
@@ -2,28 +2,32 @@ import Button from '@app/components/Common/Button';
import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon, BeakerIcon } from '@heroicons/react/24/outline';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
- agentenabled: 'Enable Agent',
- webhookUrl: 'Webhook URL',
- webhookUrlTip:
- 'Create an Incoming Webhook integration',
- slacksettingssaved: 'Slack notification settings saved successfully!',
- slacksettingsfailed: 'Slack notification settings failed to save.',
- toastSlackTestSending: 'Sending Slack test notification…',
- toastSlackTestSuccess: 'Slack test notification sent!',
- toastSlackTestFailed: 'Slack test notification failed to send.',
- validationWebhookUrl: 'You must provide a valid URL',
- validationTypes: 'You must select at least one notification type',
-});
+const messages = defineMessages(
+ 'components.Settings.Notifications.NotificationsSlack',
+ {
+ agentenabled: 'Enable Agent',
+ webhookUrl: 'Webhook URL',
+ webhookUrlTip:
+ 'Create an Incoming Webhook integration',
+ slacksettingssaved: 'Slack notification settings saved successfully!',
+ slacksettingsfailed: 'Slack notification settings failed to save.',
+ toastSlackTestSending: 'Sending Slack test notification…',
+ toastSlackTestSuccess: 'Slack test notification sent!',
+ toastSlackTestFailed: 'Slack test notification failed to send.',
+ validationWebhookUrl: 'You must provide a valid URL',
+ validationTypes: 'You must select at least one notification type',
+ }
+);
const NotificationsSlack = () => {
const intl = useIntl();
diff --git a/src/components/Settings/Notifications/NotificationsTelegram.tsx b/src/components/Settings/Notifications/NotificationsTelegram.tsx
index 6907906a..a4e8f31a 100644
--- a/src/components/Settings/Notifications/NotificationsTelegram.tsx
+++ b/src/components/Settings/Notifications/NotificationsTelegram.tsx
@@ -3,16 +3,17 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import SensitiveInput from '@app/components/Common/SensitiveInput';
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon, BeakerIcon } from '@heroicons/react/24/outline';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings.Notifications', {
agentenabled: 'Enable Agent',
botUsername: 'Bot Username',
botUsernameTip:
diff --git a/src/components/Settings/Notifications/NotificationsWebPush/index.tsx b/src/components/Settings/Notifications/NotificationsWebPush/index.tsx
index a5627ed3..542d4157 100644
--- a/src/components/Settings/Notifications/NotificationsWebPush/index.tsx
+++ b/src/components/Settings/Notifications/NotificationsWebPush/index.tsx
@@ -2,24 +2,28 @@ import Alert from '@app/components/Common/Alert';
import Button from '@app/components/Common/Button';
import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon, BeakerIcon } from '@heroicons/react/24/outline';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR, { mutate } from 'swr';
-const messages = defineMessages({
- agentenabled: 'Enable Agent',
- webpushsettingssaved: 'Web push notification settings saved successfully!',
- webpushsettingsfailed: 'Web push notification settings failed to save.',
- toastWebPushTestSending: 'Sending web push test notification…',
- toastWebPushTestSuccess: 'Web push test notification sent!',
- toastWebPushTestFailed: 'Web push test notification failed to send.',
- httpsRequirement:
- 'In order to receive web push notifications, Jellyseerr must be served over HTTPS.',
-});
+const messages = defineMessages(
+ 'components.Notifications.NotificationsWebPush',
+ {
+ agentenabled: 'Enable Agent',
+ webpushsettingssaved: 'Web push notification settings saved successfully!',
+ webpushsettingsfailed: 'Web push notification settings failed to save.',
+ toastWebPushTestSending: 'Sending web push test notification…',
+ toastWebPushTestSuccess: 'Web push test notification sent!',
+ toastWebPushTestFailed: 'Web push test notification failed to send.',
+ httpsRequirement:
+ 'In order to receive web push notifications, Jellyseerr must be served over HTTPS.',
+ }
+);
const NotificationsWebPush = () => {
const intl = useIntl();
diff --git a/src/components/Settings/Notifications/NotificationsWebhook/index.tsx b/src/components/Settings/Notifications/NotificationsWebhook/index.tsx
index d6309943..44f9dfa0 100644
--- a/src/components/Settings/Notifications/NotificationsWebhook/index.tsx
+++ b/src/components/Settings/Notifications/NotificationsWebhook/index.tsx
@@ -2,6 +2,7 @@ import Button from '@app/components/Common/Button';
import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon, BeakerIcon } from '@heroicons/react/24/outline';
import {
ArrowPathIcon,
@@ -12,7 +13,7 @@ import { Field, Form, Formik } from 'formik';
import dynamic from 'next/dynamic';
import Link from 'next/link';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
@@ -66,23 +67,26 @@ const defaultPayload = {
'{{extra}}': [],
};
-const messages = defineMessages({
- agentenabled: 'Enable Agent',
- webhookUrl: 'Webhook URL',
- authheader: 'Authorization Header',
- validationJsonPayloadRequired: 'You must provide a valid JSON payload',
- webhooksettingssaved: 'Webhook notification settings saved successfully!',
- webhooksettingsfailed: 'Webhook notification settings failed to save.',
- toastWebhookTestSending: 'Sending webhook test notification…',
- toastWebhookTestSuccess: 'Webhook test notification sent!',
- toastWebhookTestFailed: 'Webhook test notification failed to send.',
- resetPayload: 'Reset to Default',
- resetPayloadSuccess: 'JSON payload reset successfully!',
- customJson: 'JSON Payload',
- templatevariablehelp: 'Template Variable Help',
- validationWebhookUrl: 'You must provide a valid URL',
- validationTypes: 'You must select at least one notification type',
-});
+const messages = defineMessages(
+ 'components.Settings.Notifications.NotificationsWebhook',
+ {
+ agentenabled: 'Enable Agent',
+ webhookUrl: 'Webhook URL',
+ authheader: 'Authorization Header',
+ validationJsonPayloadRequired: 'You must provide a valid JSON payload',
+ webhooksettingssaved: 'Webhook notification settings saved successfully!',
+ webhooksettingsfailed: 'Webhook notification settings failed to save.',
+ toastWebhookTestSending: 'Sending webhook test notification…',
+ toastWebhookTestSuccess: 'Webhook test notification sent!',
+ toastWebhookTestFailed: 'Webhook test notification failed to send.',
+ resetPayload: 'Reset to Default',
+ resetPayloadSuccess: 'JSON payload reset successfully!',
+ customJson: 'JSON Payload',
+ templatevariablehelp: 'Template Variable Help',
+ validationWebhookUrl: 'You must provide a valid URL',
+ validationTypes: 'You must select at least one notification type',
+ }
+);
const NotificationsWebhook = () => {
const intl = useIntl();
diff --git a/src/components/Settings/RadarrModal/index.tsx b/src/components/Settings/RadarrModal/index.tsx
index 4ebc7a8b..1a4fb1b4 100644
--- a/src/components/Settings/RadarrModal/index.tsx
+++ b/src/components/Settings/RadarrModal/index.tsx
@@ -1,12 +1,13 @@
import Modal from '@app/components/Common/Modal';
import SensitiveInput from '@app/components/Common/SensitiveInput';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import type { RadarrSettings } from '@server/lib/settings';
import axios from 'axios';
import { Field, Formik } from 'formik';
import { useCallback, useEffect, useRef, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import Select from 'react-select';
import { useToasts } from 'react-toast-notifications';
import * as Yup from 'yup';
@@ -16,7 +17,7 @@ type OptionType = {
label: string;
};
-const messages = defineMessages({
+const messages = defineMessages('components.Settings.RadarrModal', {
createradarr: 'Add New Radarr Server',
create4kradarr: 'Add New 4K Radarr Server',
editradarr: 'Edit Radarr Server',
diff --git a/src/components/Settings/SettingsAbout/Releases/index.tsx b/src/components/Settings/SettingsAbout/Releases/index.tsx
index 390c264a..116b2d77 100644
--- a/src/components/Settings/SettingsAbout/Releases/index.tsx
+++ b/src/components/Settings/SettingsAbout/Releases/index.tsx
@@ -3,11 +3,12 @@ import Button from '@app/components/Common/Button';
import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import Modal from '@app/components/Common/Modal';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import { DocumentTextIcon } from '@heroicons/react/24/outline';
import dynamic from 'next/dynamic';
import { Fragment, useState } from 'react';
-import { defineMessages, FormattedRelativeTime, useIntl } from 'react-intl';
+import { FormattedRelativeTime, useIntl } from 'react-intl';
import useSWR from 'swr';
// dyanmic is having trouble extracting the props for react-markdown here so we are just ignoring it since its really
@@ -17,7 +18,7 @@ const ReactMarkdown = dynamic(() => import('react-markdown'), {
ssr: false,
});
-const messages = defineMessages({
+const messages = defineMessages('components.Settings.SettingsAbout.Releases', {
releases: 'Releases',
releasedataMissing: 'Release data is currently unavailable.',
versionChangelog: '{version} Changelog',
diff --git a/src/components/Settings/SettingsAbout/index.tsx b/src/components/Settings/SettingsAbout/index.tsx
index e5830ebc..194e89a1 100644
--- a/src/components/Settings/SettingsAbout/index.tsx
+++ b/src/components/Settings/SettingsAbout/index.tsx
@@ -6,15 +6,16 @@ import PageTitle from '@app/components/Common/PageTitle';
import Releases from '@app/components/Settings/SettingsAbout/Releases';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import { InformationCircleIcon } from '@heroicons/react/24/solid';
import type {
SettingsAboutResponse,
StatusResponse,
} from '@server/interfaces/api/settingsInterfaces';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings.SettingsAbout', {
about: 'About',
overseerrinformation: 'About Jellyseerr',
version: 'Version',
diff --git a/src/components/Settings/SettingsBadge.tsx b/src/components/Settings/SettingsBadge.tsx
index 3b26bef2..26e38729 100644
--- a/src/components/Settings/SettingsBadge.tsx
+++ b/src/components/Settings/SettingsBadge.tsx
@@ -1,9 +1,10 @@
import Badge from '@app/components/Common/Badge';
import Tooltip from '@app/components/Common/Tooltip';
import globalMessages from '@app/i18n/globalMessages';
-import { defineMessages, useIntl } from 'react-intl';
+import defineMessages from '@app/utils/defineMessages';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings', {
advancedTooltip:
'Incorrectly configuring this setting may result in broken functionality',
experimentalTooltip:
diff --git a/src/components/Settings/SettingsJellyfin.tsx b/src/components/Settings/SettingsJellyfin.tsx
index f02652b9..682fb9a3 100644
--- a/src/components/Settings/SettingsJellyfin.tsx
+++ b/src/components/Settings/SettingsJellyfin.tsx
@@ -3,6 +3,7 @@ import Button from '@app/components/Common/Button';
import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import LibraryItem from '@app/components/Settings/LibraryItem';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import { ApiErrorCode } from '@server/constants/error';
import type { JellyfinSettings } from '@server/lib/settings';
@@ -10,12 +11,12 @@ import axios from 'axios';
import { Field, Formik } from 'formik';
import getConfig from 'next/config';
import { useState } from 'react';
-import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
+import { FormattedMessage, useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings', {
jellyfinsettings: '{mediaServerName} Settings',
jellyfinsettingsDescription:
'Configure the settings for your {mediaServerName} server. {mediaServerName} scans your {mediaServerName} libraries to see what content is available.',
diff --git a/src/components/Settings/SettingsJobsCache/index.tsx b/src/components/Settings/SettingsJobsCache/index.tsx
index 1686fce2..abe70fab 100644
--- a/src/components/Settings/SettingsJobsCache/index.tsx
+++ b/src/components/Settings/SettingsJobsCache/index.tsx
@@ -8,6 +8,7 @@ import Table from '@app/components/Common/Table';
import useLocale from '@app/hooks/useLocale';
import useSettings from '@app/hooks/useSettings';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { formatBytes } from '@app/utils/numberHelpers';
import { Transition } from '@headlessui/react';
import { PlayIcon, StopIcon, TrashIcon } from '@heroicons/react/24/outline';
@@ -22,64 +23,67 @@ import axios from 'axios';
import cronstrue from 'cronstrue/i18n';
import { Fragment, useReducer, useState } from 'react';
import type { MessageDescriptor } from 'react-intl';
-import { defineMessages, FormattedRelativeTime, useIntl } from 'react-intl';
+import { FormattedRelativeTime, useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
-const messages: { [messageName: string]: MessageDescriptor } = defineMessages({
- jobsandcache: 'Jobs & Cache',
- jobs: 'Jobs',
- jobsDescription:
- 'Jellyseerr performs certain maintenance tasks as regularly-scheduled jobs, but they can also be manually triggered below. Manually running a job will not alter its schedule.',
- jobname: 'Job Name',
- jobtype: 'Type',
- nextexecution: 'Next Execution',
- runnow: 'Run Now',
- canceljob: 'Cancel Job',
- jobstarted: '{jobname} started.',
- jobcancelled: '{jobname} canceled.',
- process: 'Process',
- command: 'Command',
- cache: 'Cache',
- cacheDescription:
- 'Jellyseerr caches requests to external API endpoints to optimize performance and avoid making unnecessary API calls.',
- cacheflushed: '{cachename} cache flushed.',
- cachename: 'Cache Name',
- cachehits: 'Hits',
- cachemisses: 'Misses',
- cachekeys: 'Total Keys',
- cacheksize: 'Key Size',
- cachevsize: 'Value Size',
- flushcache: 'Flush Cache',
- unknownJob: 'Unknown Job',
- 'plex-recently-added-scan': 'Plex Recently Added Scan',
- 'plex-full-scan': 'Plex Full Library Scan',
- 'plex-watchlist-sync': 'Plex Watchlist Sync',
- 'jellyfin-recently-added-scan': 'Jellyfin Recently Added Scan',
- 'jellyfin-full-scan': 'Jellyfin Full Library Scan',
- 'availability-sync': 'Media Availability Sync',
- 'radarr-scan': 'Radarr Scan',
- 'sonarr-scan': 'Sonarr Scan',
- 'download-sync': 'Download Sync',
- 'download-sync-reset': 'Download Sync Reset',
- 'image-cache-cleanup': 'Image Cache Cleanup',
- editJobSchedule: 'Modify Job',
- jobScheduleEditSaved: 'Job edited successfully!',
- jobScheduleEditFailed: 'Something went wrong while saving the job.',
- editJobScheduleCurrent: 'Current Frequency',
- editJobSchedulePrompt: 'New Frequency',
- editJobScheduleSelectorHours:
- 'Every {jobScheduleHours, plural, one {hour} other {{jobScheduleHours} hours}}',
- editJobScheduleSelectorMinutes:
- 'Every {jobScheduleMinutes, plural, one {minute} other {{jobScheduleMinutes} minutes}}',
- editJobScheduleSelectorSeconds:
- 'Every {jobScheduleSeconds, plural, one {second} other {{jobScheduleSeconds} seconds}}',
- imagecache: 'Image Cache',
- imagecacheDescription:
- 'When enabled in settings, Jellyseerr will proxy and cache images from pre-configured external sources. Cached images are saved into your config folder. You can find the files in {appDataPath}/cache/images.',
- imagecachecount: 'Images Cached',
- imagecachesize: 'Total Cache Size',
-});
+const messages: { [messageName: string]: MessageDescriptor } = defineMessages(
+ 'components.Settings.SettingsJobsCache',
+ {
+ jobsandcache: 'Jobs & Cache',
+ jobs: 'Jobs',
+ jobsDescription:
+ 'Jellyseerr performs certain maintenance tasks as regularly-scheduled jobs, but they can also be manually triggered below. Manually running a job will not alter its schedule.',
+ jobname: 'Job Name',
+ jobtype: 'Type',
+ nextexecution: 'Next Execution',
+ runnow: 'Run Now',
+ canceljob: 'Cancel Job',
+ jobstarted: '{jobname} started.',
+ jobcancelled: '{jobname} canceled.',
+ process: 'Process',
+ command: 'Command',
+ cache: 'Cache',
+ cacheDescription:
+ 'Jellyseerr caches requests to external API endpoints to optimize performance and avoid making unnecessary API calls.',
+ cacheflushed: '{cachename} cache flushed.',
+ cachename: 'Cache Name',
+ cachehits: 'Hits',
+ cachemisses: 'Misses',
+ cachekeys: 'Total Keys',
+ cacheksize: 'Key Size',
+ cachevsize: 'Value Size',
+ flushcache: 'Flush Cache',
+ unknownJob: 'Unknown Job',
+ 'plex-recently-added-scan': 'Plex Recently Added Scan',
+ 'plex-full-scan': 'Plex Full Library Scan',
+ 'plex-watchlist-sync': 'Plex Watchlist Sync',
+ 'jellyfin-recently-added-scan': 'Jellyfin Recently Added Scan',
+ 'jellyfin-full-scan': 'Jellyfin Full Library Scan',
+ 'availability-sync': 'Media Availability Sync',
+ 'radarr-scan': 'Radarr Scan',
+ 'sonarr-scan': 'Sonarr Scan',
+ 'download-sync': 'Download Sync',
+ 'download-sync-reset': 'Download Sync Reset',
+ 'image-cache-cleanup': 'Image Cache Cleanup',
+ editJobSchedule: 'Modify Job',
+ jobScheduleEditSaved: 'Job edited successfully!',
+ jobScheduleEditFailed: 'Something went wrong while saving the job.',
+ editJobScheduleCurrent: 'Current Frequency',
+ editJobSchedulePrompt: 'New Frequency',
+ editJobScheduleSelectorHours:
+ 'Every {jobScheduleHours, plural, one {hour} other {{jobScheduleHours} hours}}',
+ editJobScheduleSelectorMinutes:
+ 'Every {jobScheduleMinutes, plural, one {minute} other {{jobScheduleMinutes} minutes}}',
+ editJobScheduleSelectorSeconds:
+ 'Every {jobScheduleSeconds, plural, one {second} other {{jobScheduleSeconds} seconds}}',
+ imagecache: 'Image Cache',
+ imagecacheDescription:
+ 'When enabled in settings, Jellyseerr will proxy and cache images from pre-configured external sources. Cached images are saved into your config folder. You can find the files in {appDataPath}/cache/images.',
+ imagecachecount: 'Images Cached',
+ imagecachesize: 'Total Cache Size',
+ }
+);
interface Job {
id: JobId;
diff --git a/src/components/Settings/SettingsLayout.tsx b/src/components/Settings/SettingsLayout.tsx
index 88368e3e..3d201ff0 100644
--- a/src/components/Settings/SettingsLayout.tsx
+++ b/src/components/Settings/SettingsLayout.tsx
@@ -3,11 +3,12 @@ import type { SettingsRoute } from '@app/components/Common/SettingsTabs';
import SettingsTabs from '@app/components/Common/SettingsTabs';
import useSettings from '@app/hooks/useSettings';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { MediaServerType } from '@server/constants/server';
import getConfig from 'next/config';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings', {
menuGeneralSettings: 'General',
menuUsers: 'Users',
menuPlexSettings: 'Plex',
diff --git a/src/components/Settings/SettingsLogs/index.tsx b/src/components/Settings/SettingsLogs/index.tsx
index 9402b133..df819d4c 100644
--- a/src/components/Settings/SettingsLogs/index.tsx
+++ b/src/components/Settings/SettingsLogs/index.tsx
@@ -9,6 +9,7 @@ import useDebouncedState from '@app/hooks/useDebouncedState';
import { useUpdateQueryParams } from '@app/hooks/useUpdateQueryParams';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import {
ChevronLeftIcon,
@@ -27,11 +28,11 @@ import type {
import copy from 'copy-to-clipboard';
import { useRouter } from 'next/router';
import { Fragment, useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings.SettingsLogs', {
logs: 'Logs',
logsDescription:
'You can also view these logs directly via stdout, or in {appDataPath}/logs/overseerr.log.',
diff --git a/src/components/Settings/SettingsMain/index.tsx b/src/components/Settings/SettingsMain/index.tsx
index b9f285ce..c34b6488 100644
--- a/src/components/Settings/SettingsMain/index.tsx
+++ b/src/components/Settings/SettingsMain/index.tsx
@@ -12,18 +12,19 @@ import { availableLanguages } from '@app/context/LanguageContext';
import useLocale from '@app/hooks/useLocale';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import { ArrowPathIcon } from '@heroicons/react/24/solid';
import type { UserSettingsGeneralResponse } from '@server/interfaces/api/userSettingsInterfaces';
import type { MainSettings } from '@server/lib/settings';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR, { mutate } from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings.SettingsMain', {
general: 'General',
generalsettings: 'General Settings',
generalsettingsDescription:
diff --git a/src/components/Settings/SettingsNotifications.tsx b/src/components/Settings/SettingsNotifications.tsx
index 0523e150..38e3f376 100644
--- a/src/components/Settings/SettingsNotifications.tsx
+++ b/src/components/Settings/SettingsNotifications.tsx
@@ -9,10 +9,11 @@ import PageTitle from '@app/components/Common/PageTitle';
import type { SettingsRoute } from '@app/components/Common/SettingsTabs';
import SettingsTabs from '@app/components/Common/SettingsTabs';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { BoltIcon, CloudIcon, EnvelopeIcon } from '@heroicons/react/24/solid';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings', {
notifications: 'Notifications',
notificationsettings: 'Notification Settings',
notificationAgentSettingsDescription:
diff --git a/src/components/Settings/SettingsPlex.tsx b/src/components/Settings/SettingsPlex.tsx
index 69d98889..d88fe85d 100644
--- a/src/components/Settings/SettingsPlex.tsx
+++ b/src/components/Settings/SettingsPlex.tsx
@@ -7,6 +7,7 @@ import SensitiveInput from '@app/components/Common/SensitiveInput';
import LibraryItem from '@app/components/Settings/LibraryItem';
import SettingsBadge from '@app/components/Settings/SettingsBadge';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import {
ArrowPathIcon,
@@ -19,12 +20,12 @@ import axios from 'axios';
import { Field, Formik } from 'formik';
import { orderBy } from 'lodash';
import { useMemo, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings', {
plex: 'Plex',
plexsettings: 'Plex Settings',
plexsettingsDescription:
diff --git a/src/components/Settings/SettingsServices.tsx b/src/components/Settings/SettingsServices.tsx
index 92810749..7dc12281 100644
--- a/src/components/Settings/SettingsServices.tsx
+++ b/src/components/Settings/SettingsServices.tsx
@@ -9,15 +9,16 @@ import PageTitle from '@app/components/Common/PageTitle';
import RadarrModal from '@app/components/Settings/RadarrModal';
import SonarrModal from '@app/components/Settings/SonarrModal';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import { PencilIcon, PlusIcon, TrashIcon } from '@heroicons/react/24/solid';
import type { RadarrSettings, SonarrSettings } from '@server/lib/settings';
import axios from 'axios';
import { Fragment, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR, { mutate } from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings', {
services: 'Services',
radarrsettings: 'Radarr Settings',
sonarrsettings: 'Sonarr Settings',
diff --git a/src/components/Settings/SettingsUsers/index.tsx b/src/components/Settings/SettingsUsers/index.tsx
index ff6126c5..78b3b177 100644
--- a/src/components/Settings/SettingsUsers/index.tsx
+++ b/src/components/Settings/SettingsUsers/index.tsx
@@ -5,17 +5,18 @@ import PermissionEdit from '@app/components/PermissionEdit';
import QuotaSelector from '@app/components/QuotaSelector';
import useSettings from '@app/hooks/useSettings';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import { MediaServerType } from '@server/constants/server';
import type { MainSettings } from '@server/lib/settings';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import getConfig from 'next/config';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR, { mutate } from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.Settings.SettingsUsers', {
users: 'Users',
userSettings: 'User Settings',
userSettingsDescription: 'Configure global and default user settings.',
diff --git a/src/components/Settings/SonarrModal/index.tsx b/src/components/Settings/SonarrModal/index.tsx
index 729a40a7..333aee24 100644
--- a/src/components/Settings/SonarrModal/index.tsx
+++ b/src/components/Settings/SonarrModal/index.tsx
@@ -1,12 +1,13 @@
import Modal from '@app/components/Common/Modal';
import SensitiveInput from '@app/components/Common/SensitiveInput';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import type { SonarrSettings } from '@server/lib/settings';
import axios from 'axios';
import { Field, Formik } from 'formik';
import { useCallback, useEffect, useRef, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import type { OnChangeValue } from 'react-select';
import Select from 'react-select';
import { useToasts } from 'react-toast-notifications';
@@ -17,7 +18,7 @@ type OptionType = {
label: string;
};
-const messages = defineMessages({
+const messages = defineMessages('components.Settings.SonarrModal', {
createsonarr: 'Add New Sonarr Server',
create4ksonarr: 'Add New 4K Sonarr Server',
editsonarr: 'Edit Sonarr Server',
diff --git a/src/components/Setup/LoginWithPlex.tsx b/src/components/Setup/LoginWithPlex.tsx
index 12f9ee47..37acfe48 100644
--- a/src/components/Setup/LoginWithPlex.tsx
+++ b/src/components/Setup/LoginWithPlex.tsx
@@ -1,10 +1,11 @@
import PlexLoginButton from '@app/components/PlexLoginButton';
import { useUser } from '@app/hooks/useUser';
+import defineMessages from '@app/utils/defineMessages';
import axios from 'axios';
import { useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Setup', {
welcome: 'Welcome to Jellyseerr',
signinMessage: 'Get started by signing in with your Plex account',
});
diff --git a/src/components/Setup/SetupLogin.tsx b/src/components/Setup/SetupLogin.tsx
index e8716ea5..cd13ba53 100644
--- a/src/components/Setup/SetupLogin.tsx
+++ b/src/components/Setup/SetupLogin.tsx
@@ -2,13 +2,14 @@ import Accordion from '@app/components/Common/Accordion';
import JellyfinLogin from '@app/components/Login/JellyfinLogin';
import PlexLoginButton from '@app/components/PlexLoginButton';
import { useUser } from '@app/hooks/useUser';
+import defineMessages from '@app/utils/defineMessages';
import { MediaServerType } from '@server/constants/server';
import axios from 'axios';
import getConfig from 'next/config';
import { useEffect, useState } from 'react';
-import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
+import { FormattedMessage, useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.Setup', {
welcome: 'Welcome to Jellyseerr',
signinMessage: 'Get started by signing in',
signinWithJellyfin: 'Use your {mediaServerName} account',
diff --git a/src/components/Setup/index.tsx b/src/components/Setup/index.tsx
index cca7bb25..a62a11a2 100644
--- a/src/components/Setup/index.tsx
+++ b/src/components/Setup/index.tsx
@@ -9,16 +9,17 @@ import SettingsPlex from '@app/components/Settings/SettingsPlex';
import SettingsServices from '@app/components/Settings/SettingsServices';
import SetupSteps from '@app/components/Setup/SetupSteps';
import useLocale from '@app/hooks/useLocale';
+import defineMessages from '@app/utils/defineMessages';
import { MediaServerType } from '@server/constants/server';
import axios from 'axios';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR, { mutate } from 'swr';
import SetupLogin from './SetupLogin';
-const messages = defineMessages({
+const messages = defineMessages('components.Setup', {
setup: 'Setup',
finish: 'Finish Setup',
finishing: 'Finishing…',
diff --git a/src/components/StatusBadge/index.tsx b/src/components/StatusBadge/index.tsx
index 58e722bd..e7cbbbba 100644
--- a/src/components/StatusBadge/index.tsx
+++ b/src/components/StatusBadge/index.tsx
@@ -5,13 +5,14 @@ import DownloadBlock from '@app/components/DownloadBlock';
import useSettings from '@app/hooks/useSettings';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { MediaStatus } from '@server/constants/media';
import { MediaServerType } from '@server/constants/server';
import type { DownloadingItem } from '@server/lib/downloadtracker';
import getConfig from 'next/config';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.StatusBadge', {
status: '{status}',
status4k: '4K {status}',
playonplex: 'Play on {mediaServerName}',
diff --git a/src/components/StatusChecker/index.tsx b/src/components/StatusChecker/index.tsx
index 41377393..9ec17c98 100644
--- a/src/components/StatusChecker/index.tsx
+++ b/src/components/StatusChecker/index.tsx
@@ -2,13 +2,14 @@ import Modal from '@app/components/Common/Modal';
import useSettings from '@app/hooks/useSettings';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import type { StatusResponse } from '@server/interfaces/api/settingsInterfaces';
import { Fragment, useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.StatusChecker', {
appUpdated: '{applicationTitle} Updated',
appUpdatedDescription:
'Please click the button below to reload the application.',
diff --git a/src/components/TitleCard/ErrorCard.tsx b/src/components/TitleCard/ErrorCard.tsx
index f3c69a65..54ed1c87 100644
--- a/src/components/TitleCard/ErrorCard.tsx
+++ b/src/components/TitleCard/ErrorCard.tsx
@@ -1,8 +1,9 @@
import Button from '@app/components/Common/Button';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { CheckIcon, TrashIcon } from '@heroicons/react/24/solid';
import axios from 'axios';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { mutate } from 'swr';
interface ErrorCardProps {
@@ -13,7 +14,7 @@ interface ErrorCardProps {
canExpand?: boolean;
}
-const messages = defineMessages({
+const messages = defineMessages('components.TitleCard', {
mediaerror: '{mediaType} Not Found',
tmdbid: 'TMDB ID',
tvdbid: 'TheTVDB ID',
diff --git a/src/components/TitleCard/index.tsx b/src/components/TitleCard/index.tsx
index e4828459..e9ae1322 100644
--- a/src/components/TitleCard/index.tsx
+++ b/src/components/TitleCard/index.tsx
@@ -8,6 +8,7 @@ import Placeholder from '@app/components/TitleCard/Placeholder';
import { useIsTouch } from '@app/hooks/useIsTouch';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { withProperties } from '@app/utils/typeHelpers';
import { Transition } from '@headlessui/react';
import {
@@ -21,7 +22,7 @@ import type { MediaType } from '@server/models/Search';
import axios from 'axios';
import Link from 'next/link';
import { Fragment, useCallback, useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import { mutate } from 'swr';
@@ -40,7 +41,7 @@ interface TitleCardProps {
mutateParent?: () => void;
}
-const messages = defineMessages({
+const messages = defineMessages('components.TitleCard', {
addToWatchList: 'Add to watchlist',
watchlistSuccess:
'{title} added to watchlist successfully!',
diff --git a/src/components/TvDetails/Season/index.tsx b/src/components/TvDetails/Season/index.tsx
index 05c5be3a..75c56b01 100644
--- a/src/components/TvDetails/Season/index.tsx
+++ b/src/components/TvDetails/Season/index.tsx
@@ -1,11 +1,12 @@
import AirDateBadge from '@app/components/AirDateBadge';
import LoadingSpinner from '@app/components/Common/LoadingSpinner';
+import defineMessages from '@app/utils/defineMessages';
import type { SeasonWithEpisodes } from '@server/models/Tv';
import Image from 'next/image';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.TvDetails.Season', {
somethingwentwrong: 'Something went wrong while retrieving season data.',
noepisodes: 'Episode list unavailable.',
});
diff --git a/src/components/TvDetails/TvCast/index.tsx b/src/components/TvDetails/TvCast/index.tsx
index 993f0b1c..63269cc2 100644
--- a/src/components/TvDetails/TvCast/index.tsx
+++ b/src/components/TvDetails/TvCast/index.tsx
@@ -3,13 +3,14 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import PageTitle from '@app/components/Common/PageTitle';
import PersonCard from '@app/components/PersonCard';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { TvDetails } from '@server/models/Tv';
import Link from 'next/link';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.TvDetails.TvCast', {
fullseriescast: 'Full Series Cast',
});
diff --git a/src/components/TvDetails/TvCrew/index.tsx b/src/components/TvDetails/TvCrew/index.tsx
index 4251de72..a3775d9f 100644
--- a/src/components/TvDetails/TvCrew/index.tsx
+++ b/src/components/TvDetails/TvCrew/index.tsx
@@ -3,13 +3,14 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import PageTitle from '@app/components/Common/PageTitle';
import PersonCard from '@app/components/PersonCard';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { TvDetails } from '@server/models/Tv';
import Link from 'next/link';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.TvDetails.TvCrew', {
fullseriescrew: 'Full Series Crew',
});
diff --git a/src/components/TvDetails/TvRecommendations.tsx b/src/components/TvDetails/TvRecommendations.tsx
index 8b64532d..4ecde5cf 100644
--- a/src/components/TvDetails/TvRecommendations.tsx
+++ b/src/components/TvDetails/TvRecommendations.tsx
@@ -3,14 +3,15 @@ import ListView from '@app/components/Common/ListView';
import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { TvResult } from '@server/models/Search';
import type { TvDetails } from '@server/models/Tv';
import Link from 'next/link';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.TvDetails', {
recommendations: 'Recommendations',
});
diff --git a/src/components/TvDetails/TvSimilar.tsx b/src/components/TvDetails/TvSimilar.tsx
index 2f0cd666..c6afd9b3 100644
--- a/src/components/TvDetails/TvSimilar.tsx
+++ b/src/components/TvDetails/TvSimilar.tsx
@@ -3,14 +3,15 @@ import ListView from '@app/components/Common/ListView';
import PageTitle from '@app/components/Common/PageTitle';
import useDiscover from '@app/hooks/useDiscover';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { TvResult } from '@server/models/Search';
import type { TvDetails } from '@server/models/Tv';
import Link from 'next/link';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.TvDetails', {
similar: 'Similar Series',
});
diff --git a/src/components/TvDetails/index.tsx b/src/components/TvDetails/index.tsx
index 82f1d889..1b21a4a3 100644
--- a/src/components/TvDetails/index.tsx
+++ b/src/components/TvDetails/index.tsx
@@ -30,6 +30,7 @@ import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
import { sortCrewPriority } from '@app/utils/creditHelpers';
+import defineMessages from '@app/utils/defineMessages';
import { refreshIntervalHelper } from '@app/utils/refreshIntervalHelper';
import { Disclosure, Transition } from '@headlessui/react';
import {
@@ -53,10 +54,10 @@ import getConfig from 'next/config';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useEffect, useMemo, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.TvDetails', {
firstAirDate: 'First Air Date',
nextAirDate: 'Next Air Date',
originallanguage: 'Original Language',
diff --git a/src/components/UserList/BulkEditModal.tsx b/src/components/UserList/BulkEditModal.tsx
index 148c9c7b..4001a1e3 100644
--- a/src/components/UserList/BulkEditModal.tsx
+++ b/src/components/UserList/BulkEditModal.tsx
@@ -3,9 +3,10 @@ import PermissionEdit from '@app/components/PermissionEdit';
import type { User } from '@app/hooks/useUser';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import axios from 'axios';
import { useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
interface BulkEditProps {
@@ -16,7 +17,7 @@ interface BulkEditProps {
onSaving?: (isSaving: boolean) => void;
}
-const messages = defineMessages({
+const messages = defineMessages('components.UserList', {
userssaved: 'User permissions saved successfully!',
userfail: 'Something went wrong while saving user permissions.',
edituser: 'Edit User Permissions',
diff --git a/src/components/UserList/JellyfinImportModal.tsx b/src/components/UserList/JellyfinImportModal.tsx
index ea975eba..2f1f1e8d 100644
--- a/src/components/UserList/JellyfinImportModal.tsx
+++ b/src/components/UserList/JellyfinImportModal.tsx
@@ -2,12 +2,13 @@ import Alert from '@app/components/Common/Alert';
import Modal from '@app/components/Common/Modal';
import useSettings from '@app/hooks/useSettings';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import type { UserResultsResponse } from '@server/interfaces/api/userInterfaces';
import axios from 'axios';
import getConfig from 'next/config';
import Image from 'next/image';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
@@ -17,7 +18,7 @@ interface JellyfinImportProps {
children?: React.ReactNode;
}
-const messages = defineMessages({
+const messages = defineMessages('components.UserList', {
importfromJellyfin: 'Import {mediaServerName} Users',
importfromJellyfinerror:
'Something went wrong while importing {mediaServerName} users.',
diff --git a/src/components/UserList/PlexImportModal.tsx b/src/components/UserList/PlexImportModal.tsx
index ae3293b9..9caf5452 100644
--- a/src/components/UserList/PlexImportModal.tsx
+++ b/src/components/UserList/PlexImportModal.tsx
@@ -2,10 +2,11 @@ import Alert from '@app/components/Common/Alert';
import Modal from '@app/components/Common/Modal';
import useSettings from '@app/hooks/useSettings';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import axios from 'axios';
import Image from 'next/image';
import { useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
@@ -14,7 +15,7 @@ interface PlexImportProps {
onComplete?: () => void;
}
-const messages = defineMessages({
+const messages = defineMessages('components.UserList', {
importfromplex: 'Import Plex Users',
importfromplexerror: 'Something went wrong while importing Plex users.',
importedfromplex:
diff --git a/src/components/UserList/index.tsx b/src/components/UserList/index.tsx
index 60ae5a0c..c8829e40 100644
--- a/src/components/UserList/index.tsx
+++ b/src/components/UserList/index.tsx
@@ -14,6 +14,7 @@ import { useUpdateQueryParams } from '@app/hooks/useUpdateQueryParams';
import type { User } from '@app/hooks/useUser';
import { Permission, UserType, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import {
BarsArrowDownIcon,
@@ -33,13 +34,13 @@ import Image from 'next/image';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
import JellyfinImportModal from './JellyfinImportModal';
-const messages = defineMessages({
+const messages = defineMessages('components.UserList', {
users: 'Users',
userlist: 'User List',
importfrommediaserver: 'Import {mediaServerName} Users',
diff --git a/src/components/UserProfile/ProfileHeader/index.tsx b/src/components/UserProfile/ProfileHeader/index.tsx
index 540a7961..a9bc0db0 100644
--- a/src/components/UserProfile/ProfileHeader/index.tsx
+++ b/src/components/UserProfile/ProfileHeader/index.tsx
@@ -1,12 +1,13 @@
import Button from '@app/components/Common/Button';
import type { User } from '@app/hooks/useUser';
import { Permission, useUser } from '@app/hooks/useUser';
+import defineMessages from '@app/utils/defineMessages';
import { CogIcon, UserIcon } from '@heroicons/react/24/solid';
import Image from 'next/image';
import Link from 'next/link';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.UserProfile.ProfileHeader', {
settings: 'Edit Settings',
profile: 'View Profile',
joindate: 'Joined {joindate}',
diff --git a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
index b6371e7d..cff15038 100644
--- a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
@@ -12,6 +12,7 @@ import useSettings from '@app/hooks/useSettings';
import { Permission, UserType, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import type { UserSettingsGeneralResponse } from '@server/interfaces/api/userSettingsInterfaces';
import axios from 'axios';
@@ -19,50 +20,53 @@ import { Field, Form, Formik } from 'formik';
import getConfig from 'next/config';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
- general: 'General',
- generalsettings: 'General Settings',
- displayName: 'Display Name',
- email: 'Email',
- save: 'Save Changes',
- saving: 'Saving…',
- mediaServerUser: '{mediaServerName} User',
- accounttype: 'Account Type',
- plexuser: 'Plex User',
- localuser: 'Local User',
- role: 'Role',
- owner: 'Owner',
- admin: 'Admin',
- user: 'User',
- toastSettingsSuccess: 'Settings saved successfully!',
- toastSettingsFailure: 'Something went wrong while saving settings.',
- region: 'Discover Region',
- regionTip: 'Filter content by regional availability',
- originallanguage: 'Discover Language',
- originallanguageTip: 'Filter content by original language',
- movierequestlimit: 'Movie Request Limit',
- seriesrequestlimit: 'Series Request Limit',
- enableOverride: 'Override Global Limit',
- applanguage: 'Display Language',
- languageDefault: 'Default ({language})',
- discordId: 'Discord User ID',
- discordIdTip:
- 'The multi-digit ID number associated with your Discord user account',
- validationemailrequired: 'Email required',
- validationemailformat: 'Valid email required',
- validationDiscordId: 'You must provide a valid Discord user ID',
- plexwatchlistsyncmovies: 'Auto-Request Movies',
- plexwatchlistsyncmoviestip:
- 'Automatically request movies on your Plex Watchlist',
- plexwatchlistsyncseries: 'Auto-Request Series',
- plexwatchlistsyncseriestip:
- 'Automatically request series on your Plex Watchlist',
-});
+const messages = defineMessages(
+ 'components.UserProfile.UserSettings.UserGeneralSettings',
+ {
+ general: 'General',
+ generalsettings: 'General Settings',
+ displayName: 'Display Name',
+ email: 'Email',
+ save: 'Save Changes',
+ saving: 'Saving…',
+ mediaServerUser: '{mediaServerName} User',
+ accounttype: 'Account Type',
+ plexuser: 'Plex User',
+ localuser: 'Local User',
+ role: 'Role',
+ owner: 'Owner',
+ admin: 'Admin',
+ user: 'User',
+ toastSettingsSuccess: 'Settings saved successfully!',
+ toastSettingsFailure: 'Something went wrong while saving settings.',
+ region: 'Discover Region',
+ regionTip: 'Filter content by regional availability',
+ originallanguage: 'Discover Language',
+ originallanguageTip: 'Filter content by original language',
+ movierequestlimit: 'Movie Request Limit',
+ seriesrequestlimit: 'Series Request Limit',
+ enableOverride: 'Override Global Limit',
+ applanguage: 'Display Language',
+ languageDefault: 'Default ({language})',
+ discordId: 'Discord User ID',
+ discordIdTip:
+ 'The multi-digit ID number associated with your Discord user account',
+ validationemailrequired: 'Email required',
+ validationemailformat: 'Valid email required',
+ validationDiscordId: 'You must provide a valid Discord user ID',
+ plexwatchlistsyncmovies: 'Auto-Request Movies',
+ plexwatchlistsyncmoviestip:
+ 'Automatically request movies on your Plex Watchlist',
+ plexwatchlistsyncseries: 'Auto-Request Series',
+ plexwatchlistsyncseriestip:
+ 'Automatically request series on your Plex Watchlist',
+ }
+);
const UserGeneralSettings = () => {
const intl = useIntl();
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx
index 841e5f77..01650ac0 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx
@@ -3,24 +3,28 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
- discordsettingssaved: 'Discord notification settings saved successfully!',
- discordsettingsfailed: 'Discord notification settings failed to save.',
- discordId: 'User ID',
- discordIdTip:
- 'The multi-digit ID number associated with your user account',
- validationDiscordId: 'You must provide a valid user ID',
-});
+const messages = defineMessages(
+ 'components.UserProfile.UserSettings.UserNotificationSettings',
+ {
+ discordsettingssaved: 'Discord notification settings saved successfully!',
+ discordsettingsfailed: 'Discord notification settings failed to save.',
+ discordId: 'User ID',
+ discordIdTip:
+ 'The multi-digit ID number associated with your user account',
+ validationDiscordId: 'You must provide a valid user ID',
+ }
+);
const UserNotificationsDiscord = () => {
const intl = useIntl();
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsEmail.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsEmail.tsx
index 137c7f65..c1196d5a 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsEmail.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsEmail.tsx
@@ -8,24 +8,28 @@ import { OpenPgpLink } from '@app/components/Settings/Notifications/Notification
import SettingsBadge from '@app/components/Settings/SettingsBadge';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
import axios from 'axios';
import { Form, Formik } from 'formik';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
- emailsettingssaved: 'Email notification settings saved successfully!',
- emailsettingsfailed: 'Email notification settings failed to save.',
- pgpPublicKey: 'PGP Public Key',
- pgpPublicKeyTip:
- 'Encrypt email messages using OpenPGP',
- validationPgpPublicKey: 'You must provide a valid PGP public key',
-});
+const messages = defineMessages(
+ 'components.UserProfile.UserSettings.UserNotificationSettings',
+ {
+ emailsettingssaved: 'Email notification settings saved successfully!',
+ emailsettingsfailed: 'Email notification settings failed to save.',
+ pgpPublicKey: 'PGP Public Key',
+ pgpPublicKeyTip:
+ 'Encrypt email messages using OpenPGP',
+ validationPgpPublicKey: 'You must provide a valid PGP public key',
+ }
+);
const UserEmailSettings = () => {
const intl = useIntl();
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushbullet.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushbullet.tsx
index feadd1ac..0a18ad25 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushbullet.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushbullet.tsx
@@ -4,24 +4,29 @@ import SensitiveInput from '@app/components/Common/SensitiveInput';
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
import axios from 'axios';
import { Form, Formik } from 'formik';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
- pushbulletsettingssaved:
- 'Pushbullet notification settings saved successfully!',
- pushbulletsettingsfailed: 'Pushbullet notification settings failed to save.',
- pushbulletAccessToken: 'Access Token',
- pushbulletAccessTokenTip:
- 'Create a token from your Account Settings',
- validationPushbulletAccessToken: 'You must provide an access token',
-});
+const messages = defineMessages(
+ 'components.UserProfile.UserSettings.UserNotificationSettings',
+ {
+ pushbulletsettingssaved:
+ 'Pushbullet notification settings saved successfully!',
+ pushbulletsettingsfailed:
+ 'Pushbullet notification settings failed to save.',
+ pushbulletAccessToken: 'Access Token',
+ pushbulletAccessTokenTip:
+ 'Create a token from your Account Settings',
+ validationPushbulletAccessToken: 'You must provide an access token',
+ }
+);
const UserPushbulletSettings = () => {
const intl = useIntl();
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushover.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushover.tsx
index 2c991efb..7ab9204d 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushover.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushover.tsx
@@ -4,31 +4,35 @@ import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
import useSettings from '@app/hooks/useSettings';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import type { PushoverSound } from '@server/api/pushover';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
- pushoversettingssaved: 'Pushover notification settings saved successfully!',
- pushoversettingsfailed: 'Pushover notification settings failed to save.',
- pushoverApplicationToken: 'Application API Token',
- pushoverApplicationTokenTip:
- 'Register an application for use with {applicationTitle}',
- pushoverUserKey: 'User or Group Key',
- pushoverUserKeyTip:
- 'Your 30-character user or group identifier',
- sound: 'Notification Sound',
- deviceDefault: 'Device Default',
- validationPushoverApplicationToken:
- 'You must provide a valid application token',
- validationPushoverUserKey: 'You must provide a valid user or group key',
-});
+const messages = defineMessages(
+ 'components.UserProfile.UserSettings.UserNotificationSettings',
+ {
+ pushoversettingssaved: 'Pushover notification settings saved successfully!',
+ pushoversettingsfailed: 'Pushover notification settings failed to save.',
+ pushoverApplicationToken: 'Application API Token',
+ pushoverApplicationTokenTip:
+ 'Register an application for use with {applicationTitle}',
+ pushoverUserKey: 'User or Group Key',
+ pushoverUserKeyTip:
+ 'Your 30-character user or group identifier',
+ sound: 'Notification Sound',
+ deviceDefault: 'Device Default',
+ validationPushoverApplicationToken:
+ 'You must provide a valid application token',
+ validationPushoverUserKey: 'You must provide a valid user or group key',
+ }
+);
const UserPushoverSettings = () => {
const intl = useIntl();
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsTelegram.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsTelegram.tsx
index 94109713..c12131ce 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsTelegram.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsTelegram.tsx
@@ -3,26 +3,30 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
- telegramsettingssaved: 'Telegram notification settings saved successfully!',
- telegramsettingsfailed: 'Telegram notification settings failed to save.',
- telegramChatId: 'Chat ID',
- telegramChatIdTipLong:
- 'Start a chat, add @get_id_bot, and issue the /my_id command',
- sendSilently: 'Send Silently',
- sendSilentlyDescription: 'Send notifications with no sound',
- validationTelegramChatId: 'You must provide a valid chat ID',
-});
+const messages = defineMessages(
+ 'components.UserProfile.UserNotificationSettings',
+ {
+ telegramsettingssaved: 'Telegram notification settings saved successfully!',
+ telegramsettingsfailed: 'Telegram notification settings failed to save.',
+ telegramChatId: 'Chat ID',
+ telegramChatIdTipLong:
+ 'Start a chat, add @get_id_bot, and issue the /my_id command',
+ sendSilently: 'Send Silently',
+ sendSilentlyDescription: 'Send notifications with no sound',
+ validationTelegramChatId: 'You must provide a valid chat ID',
+ }
+);
const UserTelegramSettings = () => {
const intl = useIntl();
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush.tsx
index 2c940d29..9ea65cef 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush.tsx
@@ -5,19 +5,23 @@ import NotificationTypeSelector, {
} from '@app/components/NotificationTypeSelector';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
import axios from 'axios';
import { Form, Formik } from 'formik';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR, { mutate } from 'swr';
-const messages = defineMessages({
- webpushsettingssaved: 'Web push notification settings saved successfully!',
- webpushsettingsfailed: 'Web push notification settings failed to save.',
-});
+const messages = defineMessages(
+ 'components.UserProfile.UserSettings.UserNotificationSettings',
+ {
+ webpushsettingssaved: 'Web push notification settings saved successfully!',
+ webpushsettingsfailed: 'Web push notification settings failed to save.',
+ }
+);
const UserWebPushSettings = () => {
const intl = useIntl();
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/index.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/index.tsx
index b93c6da6..a57a3f5d 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/index.tsx
@@ -9,18 +9,22 @@ import SettingsTabs from '@app/components/Common/SettingsTabs';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import { CloudIcon, EnvelopeIcon } from '@heroicons/react/24/solid';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
- notifications: 'Notifications',
- notificationsettings: 'Notification Settings',
- email: 'Email',
- webpush: 'Web Push',
-});
+const messages = defineMessages(
+ 'components.UserProfile.UserSettings.UserNotificationSettings',
+ {
+ notifications: 'Notifications',
+ notificationsettings: 'Notification Settings',
+ email: 'Email',
+ webpush: 'Web Push',
+ }
+);
type UserNotificationSettingsProps = {
children: React.ReactNode;
diff --git a/src/components/UserProfile/UserSettings/UserPasswordChange/index.tsx b/src/components/UserProfile/UserSettings/UserPasswordChange/index.tsx
index bf65e844..b37e3888 100644
--- a/src/components/UserProfile/UserSettings/UserPasswordChange/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserPasswordChange/index.tsx
@@ -6,37 +6,41 @@ import SensitiveInput from '@app/components/Common/SensitiveInput';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import axios from 'axios';
import { Form, Formik } from 'formik';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import * as Yup from 'yup';
-const messages = defineMessages({
- password: 'Password',
- currentpassword: 'Current Password',
- newpassword: 'New Password',
- confirmpassword: 'Confirm Password',
- toastSettingsSuccess: 'Password saved successfully!',
- toastSettingsFailure: 'Something went wrong while saving the password.',
- toastSettingsFailureVerifyCurrent:
- 'Something went wrong while saving the password. Was your current password entered correctly?',
- validationCurrentPassword: 'You must provide your current password',
- validationNewPassword: 'You must provide a new password',
- validationNewPasswordLength:
- 'Password is too short; should be a minimum of 8 characters',
- validationConfirmPassword: 'You must confirm the new password',
- validationConfirmPasswordSame: 'Passwords must match',
- noPasswordSet:
- 'This user account currently does not have a password set. Configure a password below to enable this account to sign in as a "local user."',
- noPasswordSetOwnAccount:
- 'Your account currently does not have a password set. Configure a password below to enable sign-in as a "local user" using your email address.',
- nopermissionDescription:
- "You do not have permission to modify this user's password.",
-});
+const messages = defineMessages(
+ 'components.UserProfile.UserSettings.UserPasswordChange',
+ {
+ password: 'Password',
+ currentpassword: 'Current Password',
+ newpassword: 'New Password',
+ confirmpassword: 'Confirm Password',
+ toastSettingsSuccess: 'Password saved successfully!',
+ toastSettingsFailure: 'Something went wrong while saving the password.',
+ toastSettingsFailureVerifyCurrent:
+ 'Something went wrong while saving the password. Was your current password entered correctly?',
+ validationCurrentPassword: 'You must provide your current password',
+ validationNewPassword: 'You must provide a new password',
+ validationNewPasswordLength:
+ 'Password is too short; should be a minimum of 8 characters',
+ validationConfirmPassword: 'You must confirm the new password',
+ validationConfirmPasswordSame: 'Passwords must match',
+ noPasswordSet:
+ 'This user account currently does not have a password set. Configure a password below to enable this account to sign in as a "local user."',
+ noPasswordSetOwnAccount:
+ 'Your account currently does not have a password set. Configure a password below to enable sign-in as a "local user" using your email address.',
+ nopermissionDescription:
+ "You do not have permission to modify this user's password.",
+ }
+);
const UserPasswordChange = () => {
const intl = useIntl();
diff --git a/src/components/UserProfile/UserSettings/UserPermissions/index.tsx b/src/components/UserProfile/UserSettings/UserPermissions/index.tsx
index 889edaf7..0503445e 100644
--- a/src/components/UserProfile/UserSettings/UserPermissions/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserPermissions/index.tsx
@@ -6,20 +6,24 @@ import PermissionEdit from '@app/components/PermissionEdit';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import axios from 'axios';
import { Form, Formik } from 'formik';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
-const messages = defineMessages({
- toastSettingsSuccess: 'Permissions saved successfully!',
- toastSettingsFailure: 'Something went wrong while saving settings.',
- permissions: 'Permissions',
- unauthorizedDescription: 'You cannot modify your own permissions.',
-});
+const messages = defineMessages(
+ 'components.UserProfile.UserSettings.UserPermissions',
+ {
+ toastSettingsSuccess: 'Permissions saved successfully!',
+ toastSettingsFailure: 'Something went wrong while saving settings.',
+ permissions: 'Permissions',
+ unauthorizedDescription: 'You cannot modify your own permissions.',
+ }
+);
const UserPermissions = () => {
const intl = useIntl();
diff --git a/src/components/UserProfile/UserSettings/index.tsx b/src/components/UserProfile/UserSettings/index.tsx
index eb162807..72d237b9 100644
--- a/src/components/UserProfile/UserSettings/index.tsx
+++ b/src/components/UserProfile/UserSettings/index.tsx
@@ -8,13 +8,14 @@ import useSettings from '@app/hooks/useSettings';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
import { hasPermission, Permission } from '@server/lib/permissions';
import { useRouter } from 'next/router';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.UserProfile.UserSettings', {
menuGeneralSettings: 'General',
menuChangePass: 'Password',
menuNotifications: 'Notifications',
diff --git a/src/components/UserProfile/index.tsx b/src/components/UserProfile/index.tsx
index 0aaa974b..3eec76ef 100644
--- a/src/components/UserProfile/index.tsx
+++ b/src/components/UserProfile/index.tsx
@@ -8,6 +8,7 @@ import TmdbTitleCard from '@app/components/TitleCard/TmdbTitleCard';
import ProfileHeader from '@app/components/UserProfile/ProfileHeader';
import { Permission, UserType, useUser } from '@app/hooks/useUser';
import Error from '@app/pages/_error';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowRightCircleIcon } from '@heroicons/react/24/outline';
import type { WatchlistResponse } from '@server/interfaces/api/discoverInterfaces';
import type {
@@ -20,10 +21,10 @@ import type { TvDetails } from '@server/models/Tv';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useCallback, useEffect, useState } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
import useSWR from 'swr';
-const messages = defineMessages({
+const messages = defineMessages('components.UserProfile', {
recentrequests: 'Recent Requests',
limit: '{remaining} of {limit}',
requestsperdays: '{limit} remaining',
diff --git a/src/i18n/globalMessages.ts b/src/i18n/globalMessages.ts
index ca66a891..d797087d 100644
--- a/src/i18n/globalMessages.ts
+++ b/src/i18n/globalMessages.ts
@@ -1,6 +1,6 @@
-import { defineMessages } from 'react-intl';
+import defineMessages from '@app/utils/defineMessages';
-const globalMessages = defineMessages({
+const globalMessages = defineMessages('i18n', {
available: 'Available',
partiallyavailable: 'Partially Available',
processing: 'Processing',
diff --git a/src/pages/404.tsx b/src/pages/404.tsx
index d5c88dd1..bd2df676 100644
--- a/src/pages/404.tsx
+++ b/src/pages/404.tsx
@@ -1,9 +1,10 @@
import PageTitle from '@app/components/Common/PageTitle';
+import defineMessages from '@app/utils/defineMessages';
import { ArrowRightCircleIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
-const messages = defineMessages({
+const messages = defineMessages('components.pages', {
errormessagewithcode: '{statusCode} - {error}',
pagenotfound: 'Page Not Found',
returnHome: 'Return Home',
diff --git a/src/pages/_error.tsx b/src/pages/_error.tsx
index e50a8b52..a31cac91 100644
--- a/src/pages/_error.tsx
+++ b/src/pages/_error.tsx
@@ -1,15 +1,16 @@
import PageTitle from '@app/components/Common/PageTitle';
+import defineMessages from '@app/utils/defineMessages';
import type { Undefinable } from '@app/utils/typeHelpers';
import { ArrowRightCircleIcon } from '@heroicons/react/24/outline';
import type { NextPage } from 'next';
import Link from 'next/link';
-import { defineMessages, useIntl } from 'react-intl';
+import { useIntl } from 'react-intl';
interface ErrorProps {
statusCode?: number;
}
-const messages = defineMessages({
+const messages = defineMessages('components.pages', {
errormessagewithcode: '{statusCode} - {error}',
internalservererror: 'Internal Server Error',
serviceunavailable: 'Service Unavailable',
diff --git a/src/utils/defineMessages.ts b/src/utils/defineMessages.ts
new file mode 100644
index 00000000..69a04a7d
--- /dev/null
+++ b/src/utils/defineMessages.ts
@@ -0,0 +1,18 @@
+import { defineMessages as intlDefineMessages } from 'react-intl';
+
+export default function defineMessages(
+ prefix: string,
+ messages: Record
+) {
+ const modifiedMessages: Record<
+ string,
+ { id: string; defaultMessage: string }
+ > = {};
+ for (const key of Object.keys(messages)) {
+ modifiedMessages[key] = {
+ id: prefix + '.' + key,
+ defaultMessage: messages[key],
+ };
+ }
+ return intlDefineMessages(modifiedMessages);
+}
diff --git a/yarn.lock b/yarn.lock
index 29864695..1f66079f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -20,22 +20,6 @@
call-me-maybe "^1.0.1"
js-yaml "^4.1.0"
-"@babel/cli@7.21.0":
- version "7.21.0"
- resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.21.0.tgz#1868eb70e9824b427fc607610cce8e9e7889e7e1"
- integrity sha512-xi7CxyS8XjSyiwUGCfwf+brtJxjW1/ZTcBUkP10xawIEXLX5HzLn+3aXkgxozcP2UhRhtKTmQurw9Uaes7jZrA==
- dependencies:
- "@jridgewell/trace-mapping" "^0.3.17"
- commander "^4.0.1"
- convert-source-map "^1.1.0"
- fs-readdir-recursive "^1.1.0"
- glob "^7.2.0"
- make-dir "^2.1.0"
- slash "^2.0.0"
- optionalDependencies:
- "@nicolo-ribaudo/chokidar-2" "2.1.8-no-fsevents.3"
- chokidar "^3.4.0"
-
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.24.7":
version "7.24.7"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465"
@@ -1046,7 +1030,7 @@
"@babel/parser" "^7.24.7"
"@babel/types" "^7.24.7"
-"@babel/traverse@^7.24.7", "@babel/traverse@^7.9.0":
+"@babel/traverse@^7.24.7":
version "7.24.7"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.7.tgz#de2b900163fa741721ba382163fe46a936c40cf5"
integrity sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==
@@ -1062,7 +1046,7 @@
debug "^4.3.1"
globals "^11.1.0"
-"@babel/types@^7.0.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.24.7", "@babel/types@^7.4.4", "@babel/types@^7.6.1", "@babel/types@^7.9.0", "@babel/types@^7.9.5", "@babel/types@^7.9.6":
+"@babel/types@^7.0.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.24.7", "@babel/types@^7.4.4", "@babel/types@^7.6.1", "@babel/types@^7.9.5", "@babel/types@^7.9.6":
version "7.24.7"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.7.tgz#6027fe12bc1aa724cd32ab113fb7f1988f1f66f2"
integrity sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==
@@ -1717,14 +1701,10 @@
intl-messageformat "10.5.14"
tslib "^2.4.0"
-"@formatjs/ts-transformer@2.13.0", "@formatjs/ts-transformer@^2.6.0":
- version "2.13.0"
- resolved "https://registry.yarnpkg.com/@formatjs/ts-transformer/-/ts-transformer-2.13.0.tgz#df47b35cdd209269d282a411f1646e0498aa8fdc"
- integrity sha512-mu7sHXZk1NWZrQ3eUqugpSYo8x5/tXkrI4uIbFqCEC0eNgQaIcoKgVeDFgDAcgG+cEme2atAUYSFF+DFWC4org==
- dependencies:
- intl-messageformat-parser "6.1.2"
- tslib "^2.0.1"
- typescript "^4.0"
+"@formatjs/swc-plugin-experimental@^0.4.0":
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/@formatjs/swc-plugin-experimental/-/swc-plugin-experimental-0.4.0.tgz#a51cd902a5466c7e18d5633d4c92a052c59b08c6"
+ integrity sha512-LMepVQLKpWbU29rBXoNgJilr+nmRq7x9Uz1Oh5bL32EX4dg7bSLGWiPYv/X2wKjmFNLs1zD7YFebwsVmNds6hA==
"@formatjs/ts-transformer@3.12.0":
version "3.12.0"
@@ -1739,6 +1719,15 @@
tslib "^2.4.0"
typescript "^4.7"
+"@formatjs/ts-transformer@^2.6.0":
+ version "2.13.0"
+ resolved "https://registry.yarnpkg.com/@formatjs/ts-transformer/-/ts-transformer-2.13.0.tgz#df47b35cdd209269d282a411f1646e0498aa8fdc"
+ integrity sha512-mu7sHXZk1NWZrQ3eUqugpSYo8x5/tXkrI4uIbFqCEC0eNgQaIcoKgVeDFgDAcgG+cEme2atAUYSFF+DFWC4org==
+ dependencies:
+ intl-messageformat-parser "6.1.2"
+ tslib "^2.0.1"
+ typescript "^4.0"
+
"@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
@@ -1865,7 +1854,7 @@
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
-"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25":
+"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25":
version "0.3.25"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0"
integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==
@@ -2012,11 +2001,6 @@
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.4.tgz#e65a1c6539a671f97bb86d5183d6e3a1733c29c7"
integrity sha512-tkLrjBzqFTP8DVrAAQmZelEahfR9OxWpFR++vAI9FBhCiIxtwHwBHC23SBHCTURBtwB4kc/x44imVOnkKGNVGg==
-"@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3":
- version "2.1.8-no-fsevents.3"
- resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz#323d72dd25103d0c4fbdce89dadf574a787b1f9b"
- integrity sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==
-
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@@ -3937,7 +3921,7 @@
resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f"
integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==
-"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
+"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6", "@types/json-schema@^7.0.9":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
@@ -4472,7 +4456,7 @@ ajv-keywords@^5.1.0:
dependencies:
fast-deep-equal "^3.1.3"
-ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.12.6:
+ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.6:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
@@ -4948,31 +4932,6 @@ babel-plugin-polyfill-regenerator@^0.6.1:
dependencies:
"@babel/helper-define-polyfill-provider" "^0.6.2"
-babel-plugin-react-intl-auto@3.3.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-react-intl-auto/-/babel-plugin-react-intl-auto-3.3.0.tgz#75c6ba8a1eb442f43c2ab85f1a75f4cc1e0d7857"
- integrity sha512-08ZyGWtKrQY/rMNfdvrWPBsjqx+8CirqV4/JUM46FAS2aU98Mi/uWM60K6Wg6Zapdyqs3fCbQ8S4OfqMPsBiqQ==
- dependencies:
- "@babel/core" "^7.9.0"
- "@babel/traverse" "^7.9.0"
- "@babel/types" "^7.9.0"
- murmurhash3js "^3.0.1"
-
-babel-plugin-react-intl@8.2.25:
- version "8.2.25"
- resolved "https://registry.yarnpkg.com/babel-plugin-react-intl/-/babel-plugin-react-intl-8.2.25.tgz#7b6adaa2bc291ac7b9f87bf51f1c2ea8974ffe84"
- integrity sha512-vqzRwqxMKHBKEpzWIIabxUXSBYd8urOkk49nQdzgEt55tLIuDc1XdHceeMNaeJt9VRLYZUiL5vpYpnvrntUNMQ==
- dependencies:
- "@babel/core" "^7.9.0"
- "@babel/helper-plugin-utils" "^7.8.3"
- "@babel/types" "^7.9.5"
- "@formatjs/ts-transformer" "2.13.0"
- "@types/babel__core" "^7.1.7"
- "@types/schema-utils" "^2.4.0"
- intl-messageformat-parser "6.1.2"
- schema-utils "^3.0.0"
- tslib "^2.0.1"
-
babel-plugin-react-intl@^7.0.0:
version "7.9.4"
resolved "https://registry.yarnpkg.com/babel-plugin-react-intl/-/babel-plugin-react-intl-7.9.4.tgz#1fc9ab50470d41b934df50d8f436578ee1732cb0"
@@ -5429,7 +5388,7 @@ cheerio@^1.0.0-rc.3:
parse5 "^7.0.0"
parse5-htmlparser2-tree-adapter "^7.0.0"
-chokidar@^3.4.0, chokidar@^3.5.2, chokidar@^3.5.3:
+chokidar@^3.5.2, chokidar@^3.5.3:
version "3.6.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
@@ -5661,11 +5620,6 @@ commander@^2.19.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
-commander@^4.0.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
- integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
-
commander@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
@@ -5868,7 +5822,7 @@ conventional-commits-parser@^4.0.0:
meow "^8.1.2"
split2 "^3.2.2"
-convert-source-map@^1.1.0, convert-source-map@^1.5.0:
+convert-source-map@^1.5.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f"
integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==
@@ -7793,11 +7747,6 @@ fs-minipass@^2.0.0, fs-minipass@^2.1.0:
dependencies:
minipass "^3.0.0"
-fs-readdir-recursive@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
- integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==
-
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@@ -7985,7 +7934,7 @@ glob@10.3.10:
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
path-scurry "^1.10.1"
-glob@7.2.3, glob@^7.0.5, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0:
+glob@7.2.3, glob@^7.0.5, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
@@ -9849,14 +9798,6 @@ mailsplit@5.4.0:
libmime "5.2.0"
libqp "2.0.1"
-make-dir@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
- integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==
- dependencies:
- pify "^4.0.1"
- semver "^5.6.0"
-
make-dir@^3.0.0, make-dir@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
@@ -10563,11 +10504,6 @@ multimatch@5:
arrify "^2.0.1"
minimatch "^3.0.4"
-murmurhash3js@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/murmurhash3js/-/murmurhash3js-3.0.1.tgz#3e983e5b47c2a06f43a713174e7e435ca044b998"
- integrity sha512-KL8QYUaxq7kUbcl0Yto51rMcYt7E/4N4BG3/c96Iqw1PQrTRspu8Cpx4TZ4Nunib1d4bEkIH3gjCYlP2RLBdow==
-
mustache@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64"
@@ -12835,15 +12771,6 @@ schema-utils@^2.6.6:
ajv "^6.12.4"
ajv-keywords "^3.5.2"
-schema-utils@^3.0.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe"
- integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==
- dependencies:
- "@types/json-schema" "^7.0.8"
- ajv "^6.12.5"
- ajv-keywords "^3.5.2"
-
secure-random-password@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/secure-random-password/-/secure-random-password-0.2.3.tgz#cc99714a824328f251b11b35b557b685c09717db"
@@ -12923,7 +12850,7 @@ semver-regex@^3.1.2:
resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.4.tgz#13053c0d4aa11d070a2f2872b6b1e3ae1e1971b4"
integrity sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==
-"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
+"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.7.1:
version "5.7.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
@@ -13098,11 +13025,6 @@ simple-update-notifier@^1.0.7:
dependencies:
semver "~7.0.0"
-slash@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
- integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==
-
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"