mirror of
https://github.com/fallenbagel/jellyseerr.git
synced 2026-01-04 13:48:27 -05:00
Merge pull request #103 from boring-dragon/develop
feat: conditional media server name to add emby
This commit is contained in:
@@ -366,13 +366,18 @@ const IssueDetails: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<PlayIcon />
|
<PlayIcon />
|
||||||
<span>
|
<span>
|
||||||
{intl.formatMessage(messages.playonplex, {
|
{process.env.JELLYFIN_TYPE == 'emby'
|
||||||
mediaServerName:
|
? intl.formatMessage(messages.playonplex, {
|
||||||
settings.currentSettings.mediaServerType ===
|
mediaServerName: 'Emby',
|
||||||
|
})
|
||||||
|
: settings.currentSettings.mediaServerType ===
|
||||||
MediaServerType.PLEX
|
MediaServerType.PLEX
|
||||||
? 'Plex'
|
? intl.formatMessage(messages.playonplex, {
|
||||||
: 'Jellyfin',
|
mediaServerName: 'Plex',
|
||||||
})}
|
})
|
||||||
|
: intl.formatMessage(messages.playonplex, {
|
||||||
|
mediaServerName: 'Jellyfin',
|
||||||
|
})}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
@@ -407,13 +412,18 @@ const IssueDetails: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<PlayIcon />
|
<PlayIcon />
|
||||||
<span>
|
<span>
|
||||||
{intl.formatMessage(messages.play4konplex, {
|
{process.env.JELLYFIN_TYPE == 'emby'
|
||||||
mediaServerName:
|
? intl.formatMessage(messages.play4konplex, {
|
||||||
settings.currentSettings.mediaServerType ===
|
mediaServerName: 'Emby',
|
||||||
|
})
|
||||||
|
: settings.currentSettings.mediaServerType ===
|
||||||
MediaServerType.PLEX
|
MediaServerType.PLEX
|
||||||
? 'Plex'
|
? intl.formatMessage(messages.play4konplex, {
|
||||||
: 'Jellyfin',
|
mediaServerName: 'Plex',
|
||||||
})}
|
})
|
||||||
|
: intl.formatMessage(messages.play4konplex, {
|
||||||
|
mediaServerName: 'Jellyfin',
|
||||||
|
})}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
@@ -618,13 +628,18 @@ const IssueDetails: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<PlayIcon />
|
<PlayIcon />
|
||||||
<span>
|
<span>
|
||||||
{intl.formatMessage(messages.playonplex, {
|
{process.env.JELLYFIN_TYPE == 'emby'
|
||||||
mediaServerName:
|
? intl.formatMessage(messages.playonplex, {
|
||||||
settings.currentSettings.mediaServerType ===
|
mediaServerName: 'Emby',
|
||||||
|
})
|
||||||
|
: settings.currentSettings.mediaServerType ===
|
||||||
MediaServerType.PLEX
|
MediaServerType.PLEX
|
||||||
? 'Plex'
|
? intl.formatMessage(messages.playonplex, {
|
||||||
: 'Jellyfin',
|
mediaServerName: 'Plex',
|
||||||
})}
|
})
|
||||||
|
: intl.formatMessage(messages.playonplex, {
|
||||||
|
mediaServerName: 'Jellyfin',
|
||||||
|
})}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
@@ -659,13 +674,18 @@ const IssueDetails: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<PlayIcon />
|
<PlayIcon />
|
||||||
<span>
|
<span>
|
||||||
{intl.formatMessage(messages.play4konplex, {
|
{process.env.JELLYFIN_TYPE == 'emby'
|
||||||
mediaServerName:
|
? intl.formatMessage(messages.play4konplex, {
|
||||||
settings.currentSettings.mediaServerType ===
|
mediaServerName: 'Emby',
|
||||||
|
})
|
||||||
|
: settings.currentSettings.mediaServerType ===
|
||||||
MediaServerType.PLEX
|
MediaServerType.PLEX
|
||||||
? 'Plex'
|
? intl.formatMessage(messages.play4konplex, {
|
||||||
: 'Jellyfin',
|
mediaServerName: 'Plex',
|
||||||
})}
|
})
|
||||||
|
: intl.formatMessage(messages.play4konplex, {
|
||||||
|
mediaServerName: 'Jellyfin',
|
||||||
|
})}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ import useSettings from '../../hooks/useSettings';
|
|||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
username: 'Username',
|
username: 'Username',
|
||||||
password: 'Password',
|
password: 'Password',
|
||||||
host: 'Jellyfin URL',
|
host: '{mediaServerName} URL',
|
||||||
email: 'Email',
|
email: 'Email',
|
||||||
validationhostrequired: 'Jellyfin URL required',
|
validationhostrequired: '{mediaServerName} URL required',
|
||||||
validationhostformat: 'Valid URL required',
|
validationhostformat: 'Valid URL required',
|
||||||
validationemailrequired: 'Email required',
|
validationemailrequired: 'Email required',
|
||||||
validationemailformat: 'Valid email required',
|
validationemailformat: 'Valid email required',
|
||||||
@@ -46,9 +46,17 @@ const JellyfinLogin: React.FC<JellyfinLoginProps> = ({
|
|||||||
host: Yup.string()
|
host: Yup.string()
|
||||||
.matches(
|
.matches(
|
||||||
/^(?:(?:(?:https?):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/,
|
/^(?:(?:(?:https?):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/,
|
||||||
intl.formatMessage(messages.validationhostformat)
|
intl.formatMessage(messages.validationhostformat, {
|
||||||
|
mediaServerName:
|
||||||
|
process.env.JELLYFIN_TYPE == 'emby' ? 'Emby' : 'Jellyfin',
|
||||||
|
})
|
||||||
)
|
)
|
||||||
.required(intl.formatMessage(messages.validationhostrequired)),
|
.required(
|
||||||
|
intl.formatMessage(messages.validationhostrequired, {
|
||||||
|
mediaServerName:
|
||||||
|
process.env.JELLYFIN_TYPE == 'emby' ? 'Emby' : 'Jellyfin',
|
||||||
|
})
|
||||||
|
),
|
||||||
email: Yup.string()
|
email: Yup.string()
|
||||||
.email(intl.formatMessage(messages.validationemailformat))
|
.email(intl.formatMessage(messages.validationemailformat))
|
||||||
.required(intl.formatMessage(messages.validationemailrequired)),
|
.required(intl.formatMessage(messages.validationemailrequired)),
|
||||||
@@ -97,7 +105,10 @@ const JellyfinLogin: React.FC<JellyfinLoginProps> = ({
|
|||||||
<Form>
|
<Form>
|
||||||
<div className="sm:border-t sm:border-gray-800">
|
<div className="sm:border-t sm:border-gray-800">
|
||||||
<label htmlFor="host" className="text-label">
|
<label htmlFor="host" className="text-label">
|
||||||
{intl.formatMessage(messages.host)}
|
{intl.formatMessage(messages.host, {
|
||||||
|
mediaServerName:
|
||||||
|
process.env.JELLYFIN_TYPE == 'emby' ? 'Emby' : 'Jellyfin',
|
||||||
|
})}
|
||||||
</label>
|
</label>
|
||||||
<div className="mt-1 mb-2 sm:col-span-2 sm:mt-0">
|
<div className="mt-1 mb-2 sm:col-span-2 sm:mt-0">
|
||||||
<div className="flex rounded-md shadow-sm">
|
<div className="flex rounded-md shadow-sm">
|
||||||
@@ -105,7 +116,12 @@ const JellyfinLogin: React.FC<JellyfinLoginProps> = ({
|
|||||||
id="host"
|
id="host"
|
||||||
name="host"
|
name="host"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder={intl.formatMessage(messages.host)}
|
placeholder={intl.formatMessage(messages.host, {
|
||||||
|
mediaServerName:
|
||||||
|
process.env.JELLYFIN_TYPE == 'emby'
|
||||||
|
? 'Emby'
|
||||||
|
: 'Jellyfin',
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{errors.host && touched.host && (
|
{errors.host && touched.host && (
|
||||||
|
|||||||
@@ -130,10 +130,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
|
|
||||||
if (data.mediaInfo?.mediaUrl) {
|
if (data.mediaInfo?.mediaUrl) {
|
||||||
mediaLinks.push({
|
mediaLinks.push({
|
||||||
text:
|
text: getAvalaibleMediaServerName(),
|
||||||
settings.currentSettings.mediaServerType === MediaServerType.JELLYFIN
|
|
||||||
? intl.formatMessage(messages.play, { mediaServerName: 'Jellyfin' })
|
|
||||||
: intl.formatMessage(messages.play, { mediaServerName: 'Plex' }),
|
|
||||||
url: data.mediaInfo?.mediaUrl,
|
url: data.mediaInfo?.mediaUrl,
|
||||||
svg: <PlayIcon />,
|
svg: <PlayIcon />,
|
||||||
});
|
});
|
||||||
@@ -146,10 +143,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
})
|
})
|
||||||
) {
|
) {
|
||||||
mediaLinks.push({
|
mediaLinks.push({
|
||||||
text:
|
text: getAvalaible4kMediaServerName(),
|
||||||
settings.currentSettings.mediaServerType === MediaServerType.JELLYFIN
|
|
||||||
? intl.formatMessage(messages.play4k, { mediaServerName: 'Jellyfin' })
|
|
||||||
: intl.formatMessage(messages.play4k, { mediaServerName: 'Plex' }),
|
|
||||||
url: data.mediaInfo?.mediaUrl4k,
|
url: data.mediaInfo?.mediaUrl4k,
|
||||||
svg: <PlayIcon />,
|
svg: <PlayIcon />,
|
||||||
});
|
});
|
||||||
@@ -228,6 +222,30 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
data?.watchProviders?.find((provider) => provider.iso_3166_1 === region)
|
data?.watchProviders?.find((provider) => provider.iso_3166_1 === region)
|
||||||
?.flatrate ?? [];
|
?.flatrate ?? [];
|
||||||
|
|
||||||
|
function getAvalaibleMediaServerName() {
|
||||||
|
if (process.env.JELLYFIN_TYPE === 'emby') {
|
||||||
|
return intl.formatMessage(messages.play, { mediaServerName: 'Emby' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.currentSettings.mediaServerType === MediaServerType.PLEX) {
|
||||||
|
return intl.formatMessage(messages.play, { mediaServerName: 'Plex' });
|
||||||
|
}
|
||||||
|
|
||||||
|
return intl.formatMessage(messages.play, { mediaServerName: 'Jellyfin' });
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAvalaible4kMediaServerName() {
|
||||||
|
if (process.env.JELLYFIN_TYPE === 'emby') {
|
||||||
|
return intl.formatMessage(messages.play4k, { mediaServerName: 'Emby' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.currentSettings.mediaServerType === MediaServerType.PLEX) {
|
||||||
|
return intl.formatMessage(messages.play4k, { mediaServerName: 'Plex' });
|
||||||
|
}
|
||||||
|
|
||||||
|
return intl.formatMessage(messages.play4k, { mediaServerName: 'Jellyfin' });
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="media-page"
|
className="media-page"
|
||||||
|
|||||||
@@ -14,28 +14,28 @@ import LoadingSpinner from '../Common/LoadingSpinner';
|
|||||||
import LibraryItem from './LibraryItem';
|
import LibraryItem from './LibraryItem';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
jellyfinsettings: 'Jellyfin Settings',
|
jellyfinsettings: '{mediaServerName} Settings',
|
||||||
jellyfinsettingsDescription:
|
jellyfinsettingsDescription:
|
||||||
'Configure the settings for your Jellyfin server. Jellyfin scans your Jellyfin libraries to see what content is available.',
|
'Configure the settings for your {mediaServerName} server. {mediaServerName} scans your {mediaServerName} libraries to see what content is available.',
|
||||||
timeout: 'Timeout',
|
timeout: 'Timeout',
|
||||||
save: 'Save Changes',
|
save: 'Save Changes',
|
||||||
saving: 'Saving…',
|
saving: 'Saving…',
|
||||||
jellyfinlibraries: 'Jellyfin Libraries',
|
jellyfinlibraries: '{mediaServerName} Libraries',
|
||||||
jellyfinlibrariesDescription:
|
jellyfinlibrariesDescription:
|
||||||
'The libraries Jellyfin scans for titles. Click the button below if no libraries are listed.',
|
'The libraries {mediaServerName} scans for titles. Click the button below if no libraries are listed.',
|
||||||
jellyfinSettingsFailure:
|
jellyfinSettingsFailure:
|
||||||
'Something went wrong while saving Jellyfin settings.',
|
'Something went wrong while saving {mediaServerName} settings.',
|
||||||
jellyfinSettingsSuccess: 'Jellyfin settings saved successfully!',
|
jellyfinSettingsSuccess: '{mediaServerName} settings saved successfully!',
|
||||||
jellyfinSettings: 'Jellyfin Settings',
|
jellyfinSettings: '{mediaServerName} Settings',
|
||||||
jellyfinSettingsDescription:
|
jellyfinSettingsDescription:
|
||||||
'Optionally configure an external player endpoint for your jellyfin server that is different to the internal URL used during setup',
|
'Optionally configure an external player endpoint for your {mediaServerName} server that is different to the internal URL used during setup',
|
||||||
externalUrl: 'External URL',
|
externalUrl: 'External URL',
|
||||||
validationUrl: 'You must provide a valid URL',
|
validationUrl: 'You must provide a valid URL',
|
||||||
syncing: 'Syncing',
|
syncing: 'Syncing',
|
||||||
syncJellyfin: 'Sync Libraries',
|
syncJellyfin: 'Sync Libraries',
|
||||||
manualscanJellyfin: 'Manual Library Scan',
|
manualscanJellyfin: 'Manual Library Scan',
|
||||||
manualscanDescriptionJellyfin:
|
manualscanDescriptionJellyfin:
|
||||||
"Normally, this will only be run once every 24 hours. Jellyfin will check your Jellyfin server's recently added more aggressively. If this is your first time configuring Jellyfin, a one-time full manual library scan is recommended!",
|
"Normally, this will only be run once every 24 hours. {mediaServerName} will check your {mediaServerName} server's recently added more aggressively. If this is your first time configuring {mediaServerName}, a one-time full manual library scan is recommended!",
|
||||||
notrunning: 'Not Running',
|
notrunning: 'Not Running',
|
||||||
currentlibrary: 'Current Library: {name}',
|
currentlibrary: 'Current Library: {name}',
|
||||||
librariesRemaining: 'Libraries Remaining: {count}',
|
librariesRemaining: 'Libraries Remaining: {count}',
|
||||||
@@ -161,10 +161,22 @@ const SettingsJellyfin: React.FC<SettingsJellyfinProps> = ({
|
|||||||
<>
|
<>
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<h3 className="heading">
|
<h3 className="heading">
|
||||||
<FormattedMessage {...messages.jellyfinlibraries} />
|
{process.env.JELLYFIN_TYPE == 'emby'
|
||||||
|
? intl.formatMessage(messages.jellyfinlibraries, {
|
||||||
|
mediaServerName: 'Emby',
|
||||||
|
})
|
||||||
|
: intl.formatMessage(messages.jellyfinlibraries, {
|
||||||
|
mediaServerName: 'Jellyfin',
|
||||||
|
})}
|
||||||
</h3>
|
</h3>
|
||||||
<p className="description">
|
<p className="description">
|
||||||
<FormattedMessage {...messages.jellyfinlibrariesDescription} />
|
{process.env.JELLYFIN_TYPE == 'emby'
|
||||||
|
? intl.formatMessage(messages.jellyfinlibrariesDescription, {
|
||||||
|
mediaServerName: 'Emby',
|
||||||
|
})
|
||||||
|
: intl.formatMessage(messages.jellyfinlibrariesDescription, {
|
||||||
|
mediaServerName: 'Jellyfin',
|
||||||
|
})}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="section">
|
<div className="section">
|
||||||
@@ -201,7 +213,13 @@ const SettingsJellyfin: React.FC<SettingsJellyfinProps> = ({
|
|||||||
<FormattedMessage {...messages.manualscanJellyfin} />
|
<FormattedMessage {...messages.manualscanJellyfin} />
|
||||||
</h3>
|
</h3>
|
||||||
<p className="description">
|
<p className="description">
|
||||||
<FormattedMessage {...messages.manualscanDescriptionJellyfin} />
|
{process.env.JELLYFIN_TYPE == 'emby'
|
||||||
|
? intl.formatMessage(messages.manualscanDescriptionJellyfin, {
|
||||||
|
mediaServerName: 'Emby',
|
||||||
|
})
|
||||||
|
: intl.formatMessage(messages.manualscanDescriptionJellyfin, {
|
||||||
|
mediaServerName: 'Jellyfin',
|
||||||
|
})}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="section">
|
<div className="section">
|
||||||
@@ -305,10 +323,22 @@ const SettingsJellyfin: React.FC<SettingsJellyfinProps> = ({
|
|||||||
<>
|
<>
|
||||||
<div className="mt-10 mb-6">
|
<div className="mt-10 mb-6">
|
||||||
<h3 className="heading">
|
<h3 className="heading">
|
||||||
{intl.formatMessage(messages.jellyfinSettings)}
|
{process.env.JELLYFIN_TYPE == 'emby'
|
||||||
|
? intl.formatMessage(messages.jellyfinSettings, {
|
||||||
|
mediaServerName: 'Emby',
|
||||||
|
})
|
||||||
|
: intl.formatMessage(messages.jellyfinSettings, {
|
||||||
|
mediaServerName: 'Jellyfin',
|
||||||
|
})}
|
||||||
</h3>
|
</h3>
|
||||||
<p className="description">
|
<p className="description">
|
||||||
{intl.formatMessage(messages.jellyfinSettingsDescription)}
|
{process.env.JELLYFIN_TYPE == 'emby'
|
||||||
|
? intl.formatMessage(messages.jellyfinSettingsDescription, {
|
||||||
|
mediaServerName: 'Emby',
|
||||||
|
})
|
||||||
|
: intl.formatMessage(messages.jellyfinSettingsDescription, {
|
||||||
|
mediaServerName: 'Jellyfin',
|
||||||
|
})}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Formik
|
<Formik
|
||||||
@@ -322,15 +352,27 @@ const SettingsJellyfin: React.FC<SettingsJellyfinProps> = ({
|
|||||||
externalHostname: values.jellyfinExternalUrl,
|
externalHostname: values.jellyfinExternalUrl,
|
||||||
} as JellyfinSettings);
|
} as JellyfinSettings);
|
||||||
|
|
||||||
addToast(intl.formatMessage(messages.jellyfinSettingsSuccess), {
|
addToast(
|
||||||
autoDismiss: true,
|
intl.formatMessage(messages.jellyfinSettingsSuccess, {
|
||||||
appearance: 'success',
|
mediaServerName:
|
||||||
});
|
process.env.JELLYFIN_TYPE == 'emby' ? 'Emby' : 'Jellyfin',
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
autoDismiss: true,
|
||||||
|
appearance: 'success',
|
||||||
|
}
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
addToast(intl.formatMessage(messages.jellyfinSettingsFailure), {
|
addToast(
|
||||||
autoDismiss: true,
|
intl.formatMessage(messages.jellyfinSettingsFailure, {
|
||||||
appearance: 'error',
|
mediaServerName:
|
||||||
});
|
process.env.JELLYFIN_TYPE == 'emby' ? 'Emby' : 'Jellyfin',
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
autoDismiss: true,
|
||||||
|
appearance: 'error',
|
||||||
|
}
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
revalidate();
|
revalidate();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const messages = defineMessages({
|
|||||||
menuGeneralSettings: 'General',
|
menuGeneralSettings: 'General',
|
||||||
menuUsers: 'Users',
|
menuUsers: 'Users',
|
||||||
menuPlexSettings: 'Plex',
|
menuPlexSettings: 'Plex',
|
||||||
menuJellyfinSettings: 'Jellyfin',
|
menuJellyfinSettings: '{mediaServerName}',
|
||||||
menuServices: 'Services',
|
menuServices: 'Services',
|
||||||
menuNotifications: 'Notifications',
|
menuNotifications: 'Notifications',
|
||||||
menuLogs: 'Logs',
|
menuLogs: 'Logs',
|
||||||
@@ -18,7 +18,6 @@ const messages = defineMessages({
|
|||||||
|
|
||||||
const SettingsLayout: React.FC = ({ children }) => {
|
const SettingsLayout: React.FC = ({ children }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const settingsRoutes: SettingsRoute[] = [
|
const settingsRoutes: SettingsRoute[] = [
|
||||||
{
|
{
|
||||||
text: intl.formatMessage(messages.menuGeneralSettings),
|
text: intl.formatMessage(messages.menuGeneralSettings),
|
||||||
@@ -36,7 +35,7 @@ const SettingsLayout: React.FC = ({ children }) => {
|
|||||||
regex: /^\/settings\/plex/,
|
regex: /^\/settings\/plex/,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: intl.formatMessage(messages.menuJellyfinSettings),
|
text: getAvalaibleMediaServerName(),
|
||||||
route: '/settings/jellyfin',
|
route: '/settings/jellyfin',
|
||||||
regex: /^\/settings\/jellyfin/,
|
regex: /^\/settings\/jellyfin/,
|
||||||
},
|
},
|
||||||
@@ -76,6 +75,17 @@ const SettingsLayout: React.FC = ({ children }) => {
|
|||||||
<div className="mt-10 text-white">{children}</div>
|
<div className="mt-10 text-white">{children}</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
function getAvalaibleMediaServerName() {
|
||||||
|
if (process.env.JELLYFIN_TYPE === 'emby') {
|
||||||
|
return intl.formatMessage(messages.menuJellyfinSettings, {
|
||||||
|
mediaServerName: 'Emby',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return intl.formatMessage(messages.menuJellyfinSettings, {
|
||||||
|
mediaServerName: 'Jellyfin',
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SettingsLayout;
|
export default SettingsLayout;
|
||||||
|
|||||||
@@ -131,16 +131,20 @@ const SettingsUsers: React.FC = () => {
|
|||||||
<label htmlFor="newPlexLogin" className="checkbox-label">
|
<label htmlFor="newPlexLogin" className="checkbox-label">
|
||||||
{intl.formatMessage(messages.newPlexLogin, {
|
{intl.formatMessage(messages.newPlexLogin, {
|
||||||
mediaServerName:
|
mediaServerName:
|
||||||
settings.currentSettings.mediaServerType ===
|
process.env.JELLYFIN_TYPE == 'emby'
|
||||||
MediaServerType.PLEX
|
? 'Emby'
|
||||||
|
: settings.currentSettings.mediaServerType ===
|
||||||
|
MediaServerType.PLEX
|
||||||
? 'Plex'
|
? 'Plex'
|
||||||
: 'Jellyfin',
|
: 'Jellyfin',
|
||||||
})}
|
})}
|
||||||
<span className="label-tip">
|
<span className="label-tip">
|
||||||
{intl.formatMessage(messages.newPlexLoginTip, {
|
{intl.formatMessage(messages.newPlexLoginTip, {
|
||||||
mediaServerName:
|
mediaServerName:
|
||||||
settings.currentSettings.mediaServerType ===
|
process.env.JELLYFIN_TYPE == 'emby'
|
||||||
MediaServerType.PLEX
|
? 'Emby'
|
||||||
|
: settings.currentSettings.mediaServerType ===
|
||||||
|
MediaServerType.PLEX
|
||||||
? 'Plex'
|
? 'Plex'
|
||||||
: 'Jellyfin',
|
: 'Jellyfin',
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import { useUser } from '../../hooks/useUser';
|
|||||||
import PlexLoginButton from '../PlexLoginButton';
|
import PlexLoginButton from '../PlexLoginButton';
|
||||||
import JellyfinLogin from '../Login/JellyfinLogin';
|
import JellyfinLogin from '../Login/JellyfinLogin';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { defineMessages, FormattedMessage } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
import Accordion from '../Common/Accordion';
|
import Accordion from '../Common/Accordion';
|
||||||
import { MediaServerType } from '../../../server/constants/server';
|
import { MediaServerType } from '../../../server/constants/server';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
welcome: 'Welcome to Overseerr',
|
welcome: 'Welcome to Overseerr',
|
||||||
signinMessage: 'Get started by signing in',
|
signinMessage: 'Get started by signing in',
|
||||||
signinWithJellyfin: 'Use your Jellyfin account',
|
signinWithJellyfin: 'Use your {mediaServerName} account',
|
||||||
signinWithPlex: 'Use your Plex account',
|
signinWithPlex: 'Use your Plex account',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ const SetupLogin: React.FC<LoginWithMediaServerProps> = ({ onComplete }) => {
|
|||||||
MediaServerType.NOT_CONFIGURED
|
MediaServerType.NOT_CONFIGURED
|
||||||
);
|
);
|
||||||
const { user, revalidate } = useUser();
|
const { user, revalidate } = useUser();
|
||||||
|
const intl = useIntl();
|
||||||
// Effect that is triggered when the `authToken` comes back from the Plex OAuth
|
// Effect that is triggered when the `authToken` comes back from the Plex OAuth
|
||||||
// We take the token and attempt to login. If we get a success message, we will
|
// We take the token and attempt to login. If we get a success message, we will
|
||||||
// ask swr to revalidate the user which _shouid_ come back with a valid user.
|
// ask swr to revalidate the user which _shouid_ come back with a valid user.
|
||||||
@@ -91,7 +91,13 @@ const SetupLogin: React.FC<LoginWithMediaServerProps> = ({ onComplete }) => {
|
|||||||
}`}
|
}`}
|
||||||
onClick={() => handleClick(1)}
|
onClick={() => handleClick(1)}
|
||||||
>
|
>
|
||||||
<FormattedMessage {...messages.signinWithJellyfin} />
|
{process.env.JELLYFIN_TYPE == 'emby'
|
||||||
|
? intl.formatMessage(messages.signinWithJellyfin, {
|
||||||
|
mediaServerName: 'Emby',
|
||||||
|
})
|
||||||
|
: intl.formatMessage(messages.signinWithJellyfin, {
|
||||||
|
mediaServerName: 'Jellyfin',
|
||||||
|
})}
|
||||||
</button>
|
</button>
|
||||||
<AccordionContent isOpen={openIndexes.includes(1)}>
|
<AccordionContent isOpen={openIndexes.includes(1)}>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -124,10 +124,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
})
|
})
|
||||||
) {
|
) {
|
||||||
mediaLinks.push({
|
mediaLinks.push({
|
||||||
text:
|
text: getAvalaibleMediaServerName(),
|
||||||
settings.currentSettings.mediaServerType === MediaServerType.JELLYFIN
|
|
||||||
? intl.formatMessage(messages.play, { mediaServerName: 'Jellyfin' })
|
|
||||||
: intl.formatMessage(messages.play, { mediaServerName: 'Plex' }),
|
|
||||||
url: data.mediaInfo?.mediaUrl,
|
url: data.mediaInfo?.mediaUrl,
|
||||||
svg: <PlayIcon />,
|
svg: <PlayIcon />,
|
||||||
});
|
});
|
||||||
@@ -141,10 +138,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
})
|
})
|
||||||
) {
|
) {
|
||||||
mediaLinks.push({
|
mediaLinks.push({
|
||||||
text:
|
text: getAvalaible4kMediaServerName(),
|
||||||
settings.currentSettings.mediaServerType === MediaServerType.JELLYFIN
|
|
||||||
? intl.formatMessage(messages.play4k, { mediaServerName: 'Jellyfin' })
|
|
||||||
: intl.formatMessage(messages.play4k, { mediaServerName: 'Plex' }),
|
|
||||||
url: data.mediaInfo?.mediaUrl4k,
|
url: data.mediaInfo?.mediaUrl4k,
|
||||||
svg: <PlayIcon />,
|
svg: <PlayIcon />,
|
||||||
});
|
});
|
||||||
@@ -228,6 +222,30 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
data?.watchProviders?.find((provider) => provider.iso_3166_1 === region)
|
data?.watchProviders?.find((provider) => provider.iso_3166_1 === region)
|
||||||
?.flatrate ?? [];
|
?.flatrate ?? [];
|
||||||
|
|
||||||
|
function getAvalaibleMediaServerName() {
|
||||||
|
if (process.env.JELLYFIN_TYPE === 'emby') {
|
||||||
|
return intl.formatMessage(messages.play, { mediaServerName: 'Emby' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.currentSettings.mediaServerType === MediaServerType.PLEX) {
|
||||||
|
return intl.formatMessage(messages.play, { mediaServerName: 'Plex' });
|
||||||
|
}
|
||||||
|
|
||||||
|
return intl.formatMessage(messages.play, { mediaServerName: 'Jellyfin' });
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAvalaible4kMediaServerName() {
|
||||||
|
if (process.env.JELLYFIN_TYPE === 'emby') {
|
||||||
|
return intl.formatMessage(messages.play4k, { mediaServerName: 'Emby' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.currentSettings.mediaServerType === MediaServerType.PLEX) {
|
||||||
|
return intl.formatMessage(messages.play4k, { mediaServerName: 'Plex' });
|
||||||
|
}
|
||||||
|
|
||||||
|
return intl.formatMessage(messages.play4k, { mediaServerName: 'Jellyfin' });
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="media-page"
|
className="media-page"
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ interface JellyfinImportProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
importfromJellyfin: 'Import Jellyfin Users',
|
importfromJellyfin: 'Import {mediaServerName} Users',
|
||||||
importfromJellyfinerror:
|
importfromJellyfinerror:
|
||||||
'Something went wrong while importing Jellyfin users.',
|
'Something went wrong while importing {mediaServerName} users.',
|
||||||
importedfromJellyfin:
|
importedfromJellyfin:
|
||||||
'<strong>{userCount}</strong> Jellyfin {userCount, plural, one {user} other {users}} imported successfully!',
|
'<strong>{userCount}</strong> {mediaServerName} {userCount, plural, one {user} other {users}} imported successfully!',
|
||||||
user: 'User',
|
user: 'User',
|
||||||
noJellyfinuserstoimport: 'There are no Jellyfin users to import.',
|
noJellyfinuserstoimport: 'There are no {mediaServerName} users to import.',
|
||||||
newJellyfinsigninenabled:
|
newJellyfinsigninenabled:
|
||||||
'The <strong>Enable New Jellyfin Sign-In</strong> setting is currently enabled. Jellyfin users with library access do not need to be imported in order to sign in.',
|
'The <strong>Enable New {mediaServerName} Sign-In</strong> setting is currently enabled. {mediaServerName} users with library access do not need to be imported in order to sign in.',
|
||||||
});
|
});
|
||||||
|
|
||||||
const JellyfinImportModal: React.FC<JellyfinImportProps> = ({
|
const JellyfinImportModal: React.FC<JellyfinImportProps> = ({
|
||||||
@@ -66,6 +66,8 @@ const JellyfinImportModal: React.FC<JellyfinImportProps> = ({
|
|||||||
strong: function strong(msg) {
|
strong: function strong(msg) {
|
||||||
return <strong>{msg}</strong>;
|
return <strong>{msg}</strong>;
|
||||||
},
|
},
|
||||||
|
mediaServerName:
|
||||||
|
process.env.JELLYFIN_TYPE == 'emby' ? 'Emby' : 'Jellyfin',
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
autoDismiss: true,
|
autoDismiss: true,
|
||||||
@@ -77,10 +79,16 @@ const JellyfinImportModal: React.FC<JellyfinImportProps> = ({
|
|||||||
onComplete();
|
onComplete();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
addToast(intl.formatMessage(messages.importfromJellyfinerror), {
|
addToast(
|
||||||
autoDismiss: true,
|
intl.formatMessage(messages.importfromJellyfinerror, {
|
||||||
appearance: 'error',
|
mediaServerName:
|
||||||
});
|
process.env.JELLYFIN_TYPE == 'emby' ? 'Emby' : 'Jellyfin',
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
autoDismiss: true,
|
||||||
|
appearance: 'error',
|
||||||
|
}
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setImporting(false);
|
setImporting(false);
|
||||||
}
|
}
|
||||||
@@ -110,7 +118,10 @@ const JellyfinImportModal: React.FC<JellyfinImportProps> = ({
|
|||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
loading={!data && !error}
|
loading={!data && !error}
|
||||||
title={intl.formatMessage(messages.importfromJellyfin)}
|
title={intl.formatMessage(messages.importfromJellyfin, {
|
||||||
|
mediaServerName:
|
||||||
|
process.env.JELLYFIN_TYPE == 'emby' ? 'Emby' : 'Jellyfin',
|
||||||
|
})}
|
||||||
iconSvg={<InboxInIcon />}
|
iconSvg={<InboxInIcon />}
|
||||||
onOk={() => {
|
onOk={() => {
|
||||||
importUsers();
|
importUsers();
|
||||||
@@ -126,6 +137,8 @@ const JellyfinImportModal: React.FC<JellyfinImportProps> = ({
|
|||||||
{settings.currentSettings.newPlexLogin && (
|
{settings.currentSettings.newPlexLogin && (
|
||||||
<Alert
|
<Alert
|
||||||
title={intl.formatMessage(messages.newJellyfinsigninenabled, {
|
title={intl.formatMessage(messages.newJellyfinsigninenabled, {
|
||||||
|
mediaServerName:
|
||||||
|
process.env.JELLYFIN_TYPE == 'emby' ? 'Emby' : 'Jellyfin',
|
||||||
strong: function strong(msg) {
|
strong: function strong(msg) {
|
||||||
return (
|
return (
|
||||||
<strong className="font-semibold text-white">{msg}</strong>
|
<strong className="font-semibold text-white">{msg}</strong>
|
||||||
@@ -240,7 +253,10 @@ const JellyfinImportModal: React.FC<JellyfinImportProps> = ({
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<Alert
|
<Alert
|
||||||
title={intl.formatMessage(messages.noJellyfinuserstoimport)}
|
title={intl.formatMessage(messages.noJellyfinuserstoimport, {
|
||||||
|
mediaServerName:
|
||||||
|
process.env.JELLYFIN_TYPE == 'emby' ? 'Emby' : 'Jellyfin',
|
||||||
|
})}
|
||||||
type="info"
|
type="info"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -503,13 +503,18 @@ const UserList: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<InboxInIcon />
|
<InboxInIcon />
|
||||||
<span>
|
<span>
|
||||||
{intl.formatMessage(messages.importfromplex, {
|
{process.env.JELLYFIN_TYPE == 'emby'
|
||||||
mediaServerName:
|
? intl.formatMessage(messages.importfromplex, {
|
||||||
settings.currentSettings.mediaServerType ===
|
mediaServerName: 'Emby',
|
||||||
|
})
|
||||||
|
: settings.currentSettings.mediaServerType ===
|
||||||
MediaServerType.PLEX
|
MediaServerType.PLEX
|
||||||
? 'Plex'
|
? intl.formatMessage(messages.importfromplex, {
|
||||||
: 'Jellyfin',
|
mediaServerName: 'Plex',
|
||||||
})}
|
})
|
||||||
|
: intl.formatMessage(messages.importfromplex, {
|
||||||
|
mediaServerName: 'Jellyfin',
|
||||||
|
})}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -636,17 +641,23 @@ const UserList: React.FC = () => {
|
|||||||
<Badge badgeType="warning">
|
<Badge badgeType="warning">
|
||||||
{intl.formatMessage(messages.plexuser)}
|
{intl.formatMessage(messages.plexuser)}
|
||||||
</Badge>
|
</Badge>
|
||||||
) : (
|
) : user.userType === UserType.LOCAL ? (
|
||||||
<Badge badgeType="default">
|
<Badge badgeType="default">
|
||||||
|
{intl.formatMessage(messages.localuser)}
|
||||||
|
</Badge>
|
||||||
|
) : process.env.JELLYFIN_TYPE == 'emby' ? (
|
||||||
|
<Badge badgeType="success">
|
||||||
{intl.formatMessage(messages.mediaServerUser, {
|
{intl.formatMessage(messages.mediaServerUser, {
|
||||||
mediaServerName:
|
mediaServerName: 'Emby',
|
||||||
settings.currentSettings.mediaServerType ===
|
|
||||||
MediaServerType.PLEX
|
|
||||||
? 'Plex'
|
|
||||||
: 'Jellyfin',
|
|
||||||
})}
|
})}
|
||||||
</Badge>
|
</Badge>
|
||||||
)}
|
) : user.userType === UserType.JELLYFIN ? (
|
||||||
|
<Badge badgeType="default">
|
||||||
|
{intl.formatMessage(messages.mediaServerUser, {
|
||||||
|
mediaServerName: 'Jellyfin',
|
||||||
|
})}
|
||||||
|
</Badge>
|
||||||
|
) : null}
|
||||||
</Table.TD>
|
</Table.TD>
|
||||||
<Table.TD>
|
<Table.TD>
|
||||||
{user.id === 1
|
{user.id === 1
|
||||||
|
|||||||
Reference in New Issue
Block a user