feat(usersettings): add separate setting for streaming region (#993)

* feat: add separate setting for streaming region

Currently, the "Currently Streaming On" information is based on the Discover Region setting. This PR
adds a new setting to specify which region should be used to display the streaming region.

re #890

* fix: add missing newline

* fix: rename migration function
This commit is contained in:
Gauthier
2024-12-08 17:19:11 +01:00
committed by GitHub
parent 84fd884052
commit 89831f7090
23 changed files with 243 additions and 78 deletions

View File

@@ -222,14 +222,14 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
});
}
const region = user?.settings?.region
? user.settings.region
: settings.currentSettings.region
? settings.currentSettings.region
const discoverRegion = user?.settings?.discoverRegion
? user.settings.discoverRegion
: settings.currentSettings.discoverRegion
? settings.currentSettings.discoverRegion
: 'US';
const releases = data.releases.results.find(
(r) => r.iso_3166_1 === region
(r) => r.iso_3166_1 === discoverRegion
)?.release_dates;
// Release date types:
@@ -282,9 +282,15 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
);
}
const streamingRegion = user?.settings?.streamingRegion
? user.settings.streamingRegion
: settings.currentSettings.streamingRegion
? settings.currentSettings.streamingRegion
: 'US';
const streamingProviders =
data?.watchProviders?.find((provider) => provider.iso_3166_1 === region)
?.flatrate ?? [];
data?.watchProviders?.find(
(provider) => provider.iso_3166_1 === streamingRegion
)?.flatrate ?? [];
function getAvalaibleMediaServerName() {
if (settings.currentSettings.mediaServerType === MediaServerType.EMBY) {

View File

@@ -21,6 +21,7 @@ interface RegionSelectorProps {
isUserSetting?: boolean;
disableAll?: boolean;
watchProviders?: boolean;
regionType?: 'discover' | 'streaming';
onChange?: (fieldName: string, region: string) => void;
}
@@ -30,6 +31,7 @@ const RegionSelector = ({
isUserSetting = false,
disableAll = false,
watchProviders = false,
regionType = 'discover',
onChange,
}: RegionSelectorProps) => {
const { currentSettings } = useSettings();
@@ -63,6 +65,11 @@ const RegionSelector = ({
sortedRegions?.find((region) => region.iso_3166_1 === regionCode)?.name ??
regionCode;
const regionValue =
regionType === 'discover'
? currentSettings.discoverRegion
: currentSettings.streamingRegion;
useEffect(() => {
if (regions && value) {
if (value === 'all') {
@@ -97,14 +104,12 @@ const RegionSelector = ({
countries.includes(selectedRegion?.iso_3166_1)) ||
(isUserSetting &&
!selectedRegion &&
currentSettings.region &&
countries.includes(currentSettings.region))) && (
regionValue &&
countries.includes(regionValue))) && (
<span className="mr-2 h-4 overflow-hidden text-base leading-4">
<span
className={`flag:${
selectedRegion
? selectedRegion.iso_3166_1
: currentSettings.region
selectedRegion ? selectedRegion.iso_3166_1 : regionValue
}`}
/>
</span>
@@ -114,8 +119,8 @@ const RegionSelector = ({
? regionName(selectedRegion.iso_3166_1)
: isUserSetting && selectedRegion?.iso_3166_1 !== 'all'
? intl.formatMessage(messages.regionServerDefault, {
region: currentSettings.region
? regionName(currentSettings.region)
region: regionValue
? regionName(regionValue)
: intl.formatMessage(messages.regionDefault),
})
: intl.formatMessage(messages.regionDefault)}
@@ -148,8 +153,8 @@ const RegionSelector = ({
<span className="mr-2 text-base">
<span
className={
countries.includes(currentSettings.region)
? `flag:${currentSettings.region}`
countries.includes(regionValue)
? `flag:${regionValue}`
: 'pr-6'
}
/>
@@ -160,8 +165,8 @@ const RegionSelector = ({
} block truncate`}
>
{intl.formatMessage(messages.regionServerDefault, {
region: currentSettings.region
? regionName(currentSettings.region)
region: regionValue
? regionName(regionValue)
: intl.formatMessage(messages.regionDefault),
})}
</span>

View File

@@ -374,7 +374,11 @@ export const WatchProviderSelector = ({
const { currentSettings } = useSettings();
const [showMore, setShowMore] = useState(false);
const [watchRegion, setWatchRegion] = useState(
region ? region : currentSettings.region ? currentSettings.region : 'US'
region
? region
: currentSettings.discoverRegion
? currentSettings.discoverRegion
: 'US'
);
const [activeProvider, setActiveProvider] = useState<number[]>(
activeProviders ?? []

View File

@@ -31,10 +31,12 @@ const messages = defineMessages('components.Settings.SettingsMain', {
apikey: 'API Key',
applicationTitle: 'Application Title',
applicationurl: 'Application URL',
region: 'Discover Region',
regionTip: 'Filter content by regional availability',
discoverRegion: 'Discover Region',
discoverRegionTip: 'Filter content by regional availability',
originallanguage: 'Discover Language',
originallanguageTip: 'Filter content by original language',
streamingRegion: 'Streaming Region',
streamingRegionTip: 'Show streaming sites by regional availability',
toastApiKeySuccess: 'New API key generated successfully!',
toastApiKeyFailure: 'Something went wrong while generating a new API key.',
toastSettingsSuccess: 'Settings saved successfully!',
@@ -152,8 +154,9 @@ const SettingsMain = () => {
csrfProtection: data?.csrfProtection,
hideAvailable: data?.hideAvailable,
locale: data?.locale ?? 'en',
region: data?.region,
discoverRegion: data?.discoverRegion,
originalLanguage: data?.originalLanguage,
streamingRegion: data?.streamingRegion,
partialRequestsEnabled: data?.partialRequestsEnabled,
trustProxy: data?.trustProxy,
cacheImages: data?.cacheImages,
@@ -181,7 +184,8 @@ const SettingsMain = () => {
csrfProtection: values.csrfProtection,
hideAvailable: values.hideAvailable,
locale: values.locale,
region: values.region,
discoverRegion: values.discoverRegion,
streamingRegion: values.streamingRegion,
originalLanguage: values.originalLanguage,
partialRequestsEnabled: values.partialRequestsEnabled,
trustProxy: values.trustProxy,
@@ -402,17 +406,17 @@ const SettingsMain = () => {
</div>
</div>
<div className="form-row">
<label htmlFor="region" className="text-label">
<span>{intl.formatMessage(messages.region)}</span>
<label htmlFor="discoverRegion" className="text-label">
<span>{intl.formatMessage(messages.discoverRegion)}</span>
<span className="label-tip">
{intl.formatMessage(messages.regionTip)}
{intl.formatMessage(messages.discoverRegionTip)}
</span>
</label>
<div className="form-input-area">
<div className="form-input-field">
<RegionSelector
value={values.region ?? ''}
name="region"
value={values.discoverRegion ?? ''}
name="discoverRegion"
onChange={setFieldValue}
/>
</div>
@@ -434,6 +438,25 @@ const SettingsMain = () => {
</div>
</div>
</div>
<div className="form-row">
<label htmlFor="streamingRegion" className="text-label">
<span>{intl.formatMessage(messages.streamingRegion)}</span>
<span className="label-tip">
{intl.formatMessage(messages.streamingRegionTip)}
</span>
</label>
<div className="form-input-area">
<div className="form-input-field">
<RegionSelector
value={values.streamingRegion || 'US'}
name="streamingRegion"
onChange={setFieldValue}
regionType="streaming"
disableAll
/>
</div>
</div>
</div>
<div className="form-row">
<label htmlFor="hideAvailable" className="checkbox-label">
<span className="mr-2">

View File

@@ -222,15 +222,15 @@ const TvDetails = ({ tv }: TvDetailsProps) => {
});
}
const region = user?.settings?.region
? user.settings.region
: settings.currentSettings.region
? settings.currentSettings.region
const discoverRegion = user?.settings?.discoverRegion
? user.settings.discoverRegion
: settings.currentSettings.discoverRegion
? settings.currentSettings.discoverRegion
: 'US';
const seriesAttributes: React.ReactNode[] = [];
const contentRating = data.contentRatings.results.find(
(r) => r.iso_3166_1 === region
(r) => r.iso_3166_1 === discoverRegion
)?.rating;
if (contentRating) {
seriesAttributes.push(
@@ -312,9 +312,15 @@ const TvDetails = ({ tv }: TvDetailsProps) => {
(showHasSpecials ? seasonCount + 1 : seasonCount) <=
getAllRequestedSeasons(true).length;
const streamingRegion = user?.settings?.streamingRegion
? user.settings.streamingRegion
: settings.currentSettings.streamingRegion
? settings.currentSettings.streamingRegion
: 'US';
const streamingProviders =
data?.watchProviders?.find((provider) => provider.iso_3166_1 === region)
?.flatrate ?? [];
data?.watchProviders?.find(
(provider) => provider.iso_3166_1 === streamingRegion
)?.flatrate ?? [];
function getAvalaibleMediaServerName() {
if (settings.currentSettings.mediaServerType === MediaServerType.EMBY) {

View File

@@ -48,8 +48,12 @@ const messages = defineMessages(
'Another user already has this username. You must set an email',
region: 'Discover Region',
regionTip: 'Filter content by regional availability',
discoverRegion: 'Discover Region',
discoverRegionTip: 'Filter content by regional availability',
originallanguage: 'Discover Language',
originallanguageTip: 'Filter content by original language',
streamingRegion: 'Streaming Region',
streamingRegionTip: 'Show streaming sites by regional availability',
movierequestlimit: 'Movie Request Limit',
seriesrequestlimit: 'Series Request Limit',
enableOverride: 'Override Global Limit',
@@ -144,7 +148,8 @@ const UserGeneralSettings = () => {
email: data?.email?.includes('@') ? data.email : '',
discordId: data?.discordId ?? '',
locale: data?.locale,
region: data?.region,
discoverRegion: data?.discoverRegion,
streamingRegion: data?.streamingRegion,
originalLanguage: data?.originalLanguage,
movieQuotaLimit: data?.movieQuotaLimit,
movieQuotaDays: data?.movieQuotaDays,
@@ -168,7 +173,8 @@ const UserGeneralSettings = () => {
values.email || user?.jellyfinUsername || user?.plexUsername,
discordId: values.discordId,
locale: values.locale,
region: values.region,
discoverRegion: values.discoverRegion,
streamingRegion: values.streamingRegion,
originalLanguage: values.originalLanguage,
movieQuotaLimit: movieQuotaEnabled
? values.movieQuotaLimit
@@ -400,17 +406,17 @@ const UserGeneralSettings = () => {
</div>
</div>
<div className="form-row">
<label htmlFor="displayName" className="text-label">
<span>{intl.formatMessage(messages.region)}</span>
<label htmlFor="discoverRegion" className="text-label">
<span>{intl.formatMessage(messages.discoverRegion)}</span>
<span className="label-tip">
{intl.formatMessage(messages.regionTip)}
{intl.formatMessage(messages.discoverRegionTip)}
</span>
</label>
<div className="form-input-area">
<div className="form-input-field">
<RegionSelector
name="region"
value={values.region ?? ''}
name="discoverRegion"
value={values.discoverRegion ?? ''}
isUserSetting
onChange={setFieldValue}
/>
@@ -435,6 +441,26 @@ const UserGeneralSettings = () => {
</div>
</div>
</div>
<div className="form-row">
<label htmlFor="streamingRegionTip" className="text-label">
<span>{intl.formatMessage(messages.streamingRegion)}</span>
<span className="label-tip">
{intl.formatMessage(messages.streamingRegionTip)}
</span>
</label>
<div className="form-input-area">
<div className="form-input-field">
<RegionSelector
name="streamingRegion"
value={values.streamingRegion || ''}
isUserSetting
onChange={setFieldValue}
regionType="streaming"
disableAll
/>
</div>
</div>
</div>
{currentHasPermission(Permission.MANAGE_USERS) &&
!hasPermission(Permission.MANAGE_USERS) && (
<>