add external url settings

This commit is contained in:
CyferShepard
2024-12-15 16:11:50 +02:00
parent 667fca658a
commit 2a4db92f83
20 changed files with 134 additions and 19 deletions

View File

@@ -312,6 +312,45 @@ router.post("/setconfig", async (req, res) => {
console.log(error);
}
});
router.post("/setExternalUrl", async (req, res) => {
try {
const { ExternalUrl } = req.body;
if (ExternalUrl === undefined) {
res.status(400);
res.send("ExternalUrl is required for configuration");
return;
}
const config = await new configClass().getConfig();
const validation = await API.validateSettings(ExternalUrl, config.JF_API_KEY);
if (validation.isValid === false) {
res.status(validation.status);
res.send(validation);
return;
}
try {
const settings = config.settings || {};
settings.EXTERNAL_URL = ExternalUrl;
const query = 'UPDATE app_config SET settings=$1 where "ID"=1';
await db.query(query, [settings]);
config.settings = settings;
res.send(config);
} catch (error) {
res.status(503);
res.send({ error: "Error: " + error });
}
} catch (error) {
console.log(error);
res.status(503);
res.send({ error: "Error: " + error });
}
});
router.post("/setPreferredAdmin", async (req, res) => {
try {
const { userid, username } = req.body;

View File

@@ -177,6 +177,7 @@
"SIZE": "Size",
"JELLYFIN_URL": "Jellyfin URL",
"EMBY_URL": "Emby URL",
"EXTERNAL_URL": "External URL",
"API_KEY": "API Key",
"API_KEYS": "API Keys",
"KEY_NAME": "Key Name",

View File

@@ -177,6 +177,7 @@
"SIZE": "Taille",
"JELLYFIN_URL": "URL du serveur Jellyfin",
"EMBY_URL": "URL du serveur Emby",
"EXTERNAL_URL": "External URL",
"API_KEY": "Clé API",
"API_KEYS": "Clés API",
"KEY_NAME": "Nom de la clé",

View File

@@ -177,6 +177,7 @@
"SIZE": "大小",
"JELLYFIN_URL": "Jellyfin URL",
"EMBY_URL": "Emby URL",
"EXTERNAL_URL": "External URL",
"API_KEY": "API 密钥",
"API_KEYS": "API 密钥",
"KEY_NAME": "密钥名称",

View File

@@ -257,7 +257,7 @@ function ItemInfo() {
<Link
className="px-2"
to={
config.hostUrl +
(config.settings?.EXTERNAL_URL ?? config.hostUrl) +
`/web/index.html#!/${config.IS_JELLYFIN ? "details" : "item"}?id=` +
(data.EpisodeId || data.Id) +
(config.settings.ServerID ? "&serverId=" + config.settings.ServerID : "")

View File

@@ -71,7 +71,7 @@ function MoreItems(props) {
<div className="last-played-container">
{data.sort((a,b) => a.IndexNumber-b.IndexNumber).map((item) => (
<MoreItemCards data={item} base_url={config.hostUrl} key={item.Id}/>
<MoreItemCards data={item} base_url={config.settings?.EXTERNAL_URL ?? config.hostUrl} key={item.Id}/>
))}
</div>

View File

@@ -62,7 +62,7 @@ function LibraryLastWatched(props) {
<h1 className="my-3"><Trans i18nKey="LAST_WATCHED"/></h1>
<div className="last-played-container">
{data.map((item) => (
<LastWatchedCard data={item} base_url={config.hostUrl} key={item.Id+item.SeasonNumber+item.EpisodeNumber}/>
<LastWatchedCard data={item} base_url={config.settings?.EXTERNAL_URL ?? config.hostUrl} key={item.Id+item.SeasonNumber+item.EpisodeNumber}/>
))}
</div>

View File

@@ -212,7 +212,7 @@ function LibraryItems(props) {
}
})
.map((item) => (
<MoreItemCards data={item} base_url={config.hostUrl} key={item.Id + item.SeasonNumber + item.EpisodeNumber} />
<MoreItemCards data={item} base_url={config.settings?.EXTERNAL_URL ?? config.hostUrl} key={item.Id + item.SeasonNumber + item.EpisodeNumber} />
))}
</div>
</div>

View File

@@ -26,9 +26,12 @@ export default function SettingsConfig() {
const [selectedLanguage, setSelectedLanguage] = useState(localStorage.getItem("i18nextLng") ?? "en-US");
const [showKey, setKeyState] = useState(false);
const [formValues, setFormValues] = useState({});
const [formValuesExternal, setFormValuesExternal] = useState({});
const [isSubmitted, setisSubmitted] = useState("");
const [isSubmittedExternal, setisSubmittedExternal] = useState("");
const [loadSate, setloadSate] = useState("Loading");
const [submissionMessage, setsubmissionMessage] = useState("");
const [submissionMessageExternal, setsubmissionMessageExternal] = useState("");
const token = localStorage.getItem("token");
const [twelve_hr, set12hr] = useState(localStorage.getItem("12hr") === "true");
@@ -45,6 +48,7 @@ export default function SettingsConfig() {
Config.getConfig()
.then((config) => {
setFormValues({ JF_HOST: config.hostUrl });
setFormValuesExternal({ ExternalUrl: config.settings?.EXTERNAL_URL });
setConfig(config);
setSelectedAdmin(config.settings?.preferred_admin);
setloadSate("Loaded");
@@ -94,13 +98,42 @@ export default function SettingsConfig() {
setisSubmitted("Failed");
setsubmissionMessage(`Error Updating Configuration: ${errorMessage}`);
});
Config.setConfig();
Config.setConfig();
}
async function handleFormSubmitExternal(event) {
event.preventDefault();
setisSubmittedExternal("");
axios
.post("/api/setExternalUrl/", formValuesExternal, {
headers: {
Authorization: `Bearer ${config.token}`,
"Content-Type": "application/json",
},
})
.then((response) => {
console.log("Config updated successfully:", response.data);
setisSubmittedExternal("Success");
setsubmissionMessageExternal("Successfully updated configuration");
})
.catch((error) => {
let errorMessage = error.response.data.errorMessage;
console.log("Error updating config:", errorMessage);
setisSubmittedExternal("Failed");
setsubmissionMessageExternal(`Error Updating Configuration: ${errorMessage}`);
});
Config.setConfig();
}
function handleFormChange(event) {
setFormValues({ ...formValues, [event.target.name]: event.target.value });
}
function handleFormChangeExternal(event) {
setFormValuesExternal({ ...formValuesExternal, [event.target.name]: event.target.value });
}
function updateAdmin(event) {
const username = event.target.textContent;
const userid = event.target.getAttribute("value");
@@ -130,7 +163,7 @@ export default function SettingsConfig() {
setisSubmitted("Failed");
setsubmissionMessage("Error Updating Configuration: ", error);
});
Config.setConfig();
Config.setConfig();
}
function updateLanguage(event) {
@@ -160,8 +193,11 @@ export default function SettingsConfig() {
<Form onSubmit={handleFormSubmit} className="settings-form">
<Form.Group as={Row} className="mb-3">
<Form.Label column className="">
{config.settings?.IS_JELLYFIN ? <Trans i18nKey={"SETTINGS_PAGE.JELLYFIN_URL"} /> : <Trans i18nKey={"SETTINGS_PAGE.EMBY_URL"} /> }
{config.settings?.IS_JELLYFIN ? (
<Trans i18nKey={"SETTINGS_PAGE.JELLYFIN_URL"} />
) : (
<Trans i18nKey={"SETTINGS_PAGE.EMBY_URL"} />
)}
</Form.Label>
<Col sm="10">
<Form.Control
@@ -208,6 +244,39 @@ export default function SettingsConfig() {
</Button>
</div>
</Form>
<Form onSubmit={handleFormSubmitExternal} className="settings-form">
<Form.Group as={Row} className="mb-3">
<Form.Label column className="">
<Trans i18nKey={"SETTINGS_PAGE.EXTERNAL_URL"} />
</Form.Label>
<Col sm="10">
<Form.Control
id="ExternalUrl"
name="ExternalUrl"
value={formValuesExternal.ExternalUrl || ""}
onChange={handleFormChangeExternal}
placeholder="http://example.jellyfin.server"
/>
</Col>
</Form.Group>
{isSubmittedExternal !== "" ? (
isSubmittedExternal === "Failed" ? (
<Alert variant="danger">{submissionMessageExternal}</Alert>
) : (
<Alert variant="success">{submissionMessageExternal}</Alert>
)
) : (
<></>
)}
<div className="d-flex flex-column flex-md-row justify-content-end align-items-md-center">
<Button variant="outline-success" type="submit">
<Trans i18nKey={"SETTINGS_PAGE.UPDATE"} />
</Button>
</div>
</Form>
<Form className="settings-form">
<Form.Group as={Row} className="mb-3">
<Form.Label column className="">

View File

@@ -76,7 +76,7 @@ function MPMovies(props) {
}
return (
<ItemStatComponent base_url={config.hostUrl} data={data} heading={<Trans i18nKey="STAT_CARDS.MOST_POPULAR_MOVIES" />} units={<Trans i18nKey="USERS" />}/>
<ItemStatComponent base_url={config.settings?.EXTERNAL_URL ?? config.hostUrl} data={data} heading={<Trans i18nKey="STAT_CARDS.MOST_POPULAR_MOVIES" />} units={<Trans i18nKey="USERS" />}/>
);
}

View File

@@ -70,7 +70,7 @@ function MPMusic(props) {
return (
<ItemStatComponent base_url={config.hostUrl} data={data} heading={<Trans i18nKey="STAT_CARDS.MOST_POPULAR_MUSIC" />} units={<Trans i18nKey="USERS" />} isAudio={true}/>
<ItemStatComponent base_url={config.settings?.EXTERNAL_URL ?? config.hostUrl} data={data} heading={<Trans i18nKey="STAT_CARDS.MOST_POPULAR_MUSIC" />} units={<Trans i18nKey="USERS" />} isAudio={true}/>
);
}

View File

@@ -67,7 +67,7 @@ function MPSeries(props) {
return (
<ItemStatComponent base_url={config.hostUrl} data={data} heading={<Trans i18nKey="STAT_CARDS.MOST_POPULAR_SERIES" />} units={<Trans i18nKey="USERS" />}/>
<ItemStatComponent base_url={config.settings?.EXTERNAL_URL ?? config.hostUrl} data={data} heading={<Trans i18nKey="STAT_CARDS.MOST_POPULAR_SERIES" />} units={<Trans i18nKey="USERS" />}/>
);
}

View File

@@ -74,7 +74,7 @@ function MVMusic(props) {
return (
<ItemStatComponent base_url={config.hostUrl} data={data} heading={<Trans i18nKey="STAT_CARDS.MOST_VIEWED_MOVIES" />} units={<Trans i18nKey="UNITS.PLAYS" />}/>
<ItemStatComponent base_url={config.settings?.EXTERNAL_URL ?? config.hostUrl} data={data} heading={<Trans i18nKey="STAT_CARDS.MOST_VIEWED_MOVIES" />} units={<Trans i18nKey="UNITS.PLAYS" />}/>
);
}

View File

@@ -69,7 +69,7 @@ function MVMovies(props) {
return (
<ItemStatComponent base_url={config.hostUrl} data={data} heading={<Trans i18nKey="STAT_CARDS.MOST_LISTENED_MUSIC" />} units={<Trans i18nKey="UNITS.PLAYS" />} isAudio={true}/>
<ItemStatComponent base_url={config.settings?.EXTERNAL_URL ?? config.hostUrl} data={data} heading={<Trans i18nKey="STAT_CARDS.MOST_LISTENED_MUSIC" />} units={<Trans i18nKey="UNITS.PLAYS" />} isAudio={true}/>
);
}

View File

@@ -70,7 +70,7 @@ function MVSeries(props) {
return (
<ItemStatComponent base_url={config.hostUrl} data={data} heading={<Trans i18nKey="STAT_CARDS.MOST_VIEWED_SERIES" />} units={<Trans i18nKey="UNITS.PLAYS" />}/>
<ItemStatComponent base_url={config.settings?.EXTERNAL_URL ?? config.hostUrl} data={data} heading={<Trans i18nKey="STAT_CARDS.MOST_VIEWED_SERIES" />} units={<Trans i18nKey="UNITS.PLAYS" />}/>
);
}

View File

@@ -77,7 +77,7 @@ function PlaybackMethodStats(props) {
return (
<ItemStatComponent
base_url={config.hostUrl}
base_url={config.settings?.EXTERNAL_URL ?? config.hostUrl}
data={data.map((stream) =>
stream.Name == "DirectPlay" ? { ...stream, Name: translations.DirectPlay } : { ...stream, Name: translations.Transocde }
)}

View File

@@ -67,7 +67,7 @@ function LastPlayed(props) {
<div className="last-played-container">
{data.map((item, index) => (
<ErrorBoundary key={item.Id + item.EpisodeNumber + index}>
<LastWatchedCard data={item} base_url={config.hostUrl} />
<LastWatchedCard data={item} base_url={config.settings?.EXTERNAL_URL ?? config.hostUrl} />
</ErrorBoundary>
))}
</div>

View File

@@ -107,7 +107,11 @@ function Libraries() {
.sort((a, b) => a.Name - b.Name)
.map((item) => (
<ErrorBoundary key={item.Id}>
<LibraryCard data={item} metadata={metadata.find((data) => data.Id === item.Id)} base_url={config.hostUrl} />
<LibraryCard
data={item}
metadata={metadata.find((data) => data.Id === item.Id)}
base_url={config.settings?.EXTERNAL_URL ?? config.hostUrl}
/>
</ErrorBoundary>
))}
</div>

View File

@@ -75,7 +75,7 @@ function LibrarySelector() {
{data &&
data.map((item) => (
<ErrorBoundary key={item.Id}>
<SelectionCard data={item} base_url={config.hostUrl} />
<SelectionCard data={item} base_url={config.settings?.EXTERNAL_URL ?? config.hostUrl} />
</ErrorBoundary>
))}
</div>

View File

@@ -454,7 +454,7 @@ function Users() {
<EnhancedTableHead order={order} orderBy={orderBy} onRequestSort={handleRequestSort} rowCount={rowsPerPage} />
<TableBody>
{filteredData.map((row) => (
<Row key={row.UserId} data={row} updateTrackedState={updateTrackedState} hostUrl={config.hostUrl} />
<Row key={row.UserId} data={row} updateTrackedState={updateTrackedState} hostUrl={config.settings?.EXTERNAL_URL ?? config.hostUrl} />
))}
{data.length === 0 ? (
<tr>