Compare commits
No commits in common. "feature/jellyfinQuickConnect" and "main" have entirely different histories.
feature/je
...
main
4 changed files with 12 additions and 83 deletions
|
|
@ -31,8 +31,6 @@ public class ServersController : ControllerBase
|
||||||
|
|
||||||
var servers = await _serverService.GetServers();
|
var servers = await _serverService.GetServers();
|
||||||
|
|
||||||
_logger.LogDebug("Servers found: {}", servers.Length);
|
|
||||||
|
|
||||||
return Ok(servers);
|
return Ok(servers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ public class JellyfinApiClient
|
||||||
|
|
||||||
private string GetAuthHeader()
|
private string GetAuthHeader()
|
||||||
{
|
{
|
||||||
var header = "Client=JellyGlass, Device=JellyGlass, DeviceId=JellyGlass, Version=1";
|
var header = "Client=Test, Device=Test, DeviceId=Test, Version=1";
|
||||||
|
|
||||||
if (_apiKey != String.Empty)
|
if (_apiKey != String.Empty)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
import axios, { AxiosError } from "axios";
|
|
||||||
|
|
||||||
const DeviceInfoString = "MediaBrowser Client=JellyGlass, Device=JellyGlass, DeviceId=JellyGlass, Version=1";
|
|
||||||
|
|
||||||
interface QuickConnectInfo {
|
|
||||||
Code: string;
|
|
||||||
Secret: string;
|
|
||||||
Authenticated: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface QuickConnectAuth {
|
|
||||||
AccessToken: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const BeginQuickConnect = async (url: string, callback: (apiToken: string) => void, isCancelled: () => boolean, onError: (e: AxiosError) => void): Promise<string> => {
|
|
||||||
const response = await axios.post<QuickConnectInfo>(`${url}/QuickConnect/Initiate`, {}, { headers: { Authorization: DeviceInfoString } });
|
|
||||||
|
|
||||||
setTimeout(() => { PollQuickConnect(url, response.data, callback, isCancelled, onError) });
|
|
||||||
|
|
||||||
return response.data.Code;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PollQuickConnect = async (url: string, info: QuickConnectInfo, callback: (apiToken: string) => void, isCancelled: () => boolean, onError: (e: AxiosError) => void) => {
|
|
||||||
if (isCancelled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await axios.get<QuickConnectInfo>(`${url}/QuickConnect/Connect?secret=${info.Secret}`, { headers: { Authorization: DeviceInfoString } });
|
|
||||||
|
|
||||||
if (response.data.Authenticated) {
|
|
||||||
const authResponse = await axios.post<QuickConnectAuth>(`${url}/Users/AuthenticateWithQuickConnect`, { Secret: response.data.Secret })
|
|
||||||
callback(authResponse.data.AccessToken);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setTimeout(() => { PollQuickConnect(url, response.data, callback, isCancelled, onError) }, 5000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
onError(e as AxiosError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +1,17 @@
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect } from "react";
|
||||||
import { Button, Form, Modal, Spinner, Table } from "react-bootstrap";
|
import { Button, Form, Spinner, Table } from "react-bootstrap";
|
||||||
import { AddServer, getServerList, RemoveServer, type Server } from "../../../Lib/Servers";
|
import { AddServer, getServerList, RemoveServer, type Server } from "../../../Lib/Servers";
|
||||||
import { useImmer } from "use-immer";
|
import { useImmer } from "use-immer";
|
||||||
import styles from "../Management.module.scss";
|
import styles from "../Management.module.scss";
|
||||||
import { BeginQuickConnect } from "../../../Lib/QuickConnect";
|
|
||||||
import type { AxiosError } from "axios";
|
|
||||||
|
|
||||||
|
|
||||||
const ServerManagement = () => {
|
const ServerManagement = () => {
|
||||||
const [servers, setServers] = useImmer<Array<Server> | undefined>(undefined);
|
const [servers, setServers] = useImmer<Array<Server> | undefined>(undefined);
|
||||||
const [isCancelled, setIsCancelled] = useState(false);
|
|
||||||
const [quickConnectCode, setQuickConnectCode] = useState<string | undefined>(undefined);
|
|
||||||
|
|
||||||
const [addServerInfo, setAddServerInfo] = useImmer({
|
const [addServerInfo, setAddServerInfo] = useImmer({
|
||||||
url: "",
|
url: "",
|
||||||
owner: "",
|
owner: "",
|
||||||
|
apiToken: ""
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -40,25 +37,8 @@ const ServerManagement = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const onQuickConnect = () => {
|
const onServerAdd = () => {
|
||||||
setIsCancelled(false);
|
AddServer(addServerInfo.owner, addServerInfo.url, addServerInfo.apiToken).then(result => {
|
||||||
BeginQuickConnect(addServerInfo.url, onServerAdd, () => isCancelled, onQuickConnectError).then(code => {
|
|
||||||
setQuickConnectCode(code);
|
|
||||||
}).catch(err => {
|
|
||||||
console.log(err);
|
|
||||||
alert(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const onQuickConnectError = (e: AxiosError) => {
|
|
||||||
setIsCancelled(true);
|
|
||||||
setQuickConnectCode(undefined);
|
|
||||||
alert(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
const onServerAdd = (apiToken: string) => {
|
|
||||||
setQuickConnectCode(undefined);
|
|
||||||
AddServer(addServerInfo.owner, addServerInfo.url, apiToken).then(result => {
|
|
||||||
if (result.errored) {
|
if (result.errored) {
|
||||||
alert("Server was added, but is not working. Check the logs for details");
|
alert("Server was added, but is not working. Check the logs for details");
|
||||||
}
|
}
|
||||||
|
|
@ -72,6 +52,7 @@ const ServerManagement = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
setAddServerInfo(draft => {
|
setAddServerInfo(draft => {
|
||||||
|
draft.apiToken = "";
|
||||||
draft.owner = "";
|
draft.owner = "";
|
||||||
draft.url = "";
|
draft.url = "";
|
||||||
});
|
});
|
||||||
|
|
@ -93,7 +74,11 @@ const ServerManagement = () => {
|
||||||
<Form.Label>Url</Form.Label>
|
<Form.Label>Url</Form.Label>
|
||||||
<Form.Control type="text" placeholder="Url" onChange={e => setAddServerInfo(draft => { draft.url = e.target.value })} value={addServerInfo.url} />
|
<Form.Control type="text" placeholder="Url" onChange={e => setAddServerInfo(draft => { draft.url = e.target.value })} value={addServerInfo.url} />
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<Button className={styles.formButton} onClick={() => onQuickConnect()}>Quick Connect</Button>
|
<Form.Group className="mb-3">
|
||||||
|
<Form.Label>ApiToken</Form.Label>
|
||||||
|
<Form.Control type="text" placeholder="ApiToken" onChange={e => setAddServerInfo(draft => { draft.apiToken = e.target.value })} value={addServerInfo.apiToken} />
|
||||||
|
</Form.Group>
|
||||||
|
<Button className={styles.formButton} onClick={() => onServerAdd()}>Add Server</Button>
|
||||||
</Form>
|
</Form>
|
||||||
<Table className={styles.table} bordered striped>
|
<Table className={styles.table} bordered striped>
|
||||||
<thead>
|
<thead>
|
||||||
|
|
@ -122,17 +107,6 @@ const ServerManagement = () => {
|
||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
<Modal show={quickConnectCode !== undefined} onHide={() => { setQuickConnectCode(undefined); setIsCancelled(true); }}>
|
|
||||||
<Modal.Header>
|
|
||||||
<Modal.Title>Jellyfin quick connect code</Modal.Title>
|
|
||||||
</Modal.Header>
|
|
||||||
<Modal.Body>
|
|
||||||
Your quick connect code is {quickConnectCode}
|
|
||||||
</Modal.Body>
|
|
||||||
<Modal.Footer>
|
|
||||||
<Button onClick={() => { setQuickConnectCode(undefined); setIsCancelled(true); }}>Cancel</Button>
|
|
||||||
</Modal.Footer>
|
|
||||||
</Modal>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue