mirror of
https://github.com/trafficlunar/jellyfin-spicetify.git
synced 2026-06-13 19:07:06 +00:00
feat: login automatically
This commit is contained in:
parent
9cc104c6c9
commit
116b91c46e
2 changed files with 37 additions and 26 deletions
23
src/app.tsx
23
src/app.tsx
|
|
@ -1,11 +1,10 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Api, Jellyfin } from "@jellyfin/sdk";
|
import { Api, Jellyfin } from "@jellyfin/sdk";
|
||||||
|
import { getUserApi } from "@jellyfin/sdk/lib/utils/api/user-api";
|
||||||
import { getSearchApi } from "@jellyfin/sdk/lib/utils/api/search-api";
|
import { getSearchApi } from "@jellyfin/sdk/lib/utils/api/search-api";
|
||||||
import { BaseItemKind } from "@jellyfin/sdk/lib/generated-client/models";
|
import { BaseItemKind } from "@jellyfin/sdk/lib/generated-client/models";
|
||||||
import SettingsModal from "./settings";
|
import SettingsModal from "./settings";
|
||||||
|
|
||||||
let hijackActive = false;
|
|
||||||
|
|
||||||
export const jellyfin = new Jellyfin({
|
export const jellyfin = new Jellyfin({
|
||||||
clientInfo: {
|
clientInfo: {
|
||||||
name: "Spicetify",
|
name: "Spicetify",
|
||||||
|
|
@ -26,11 +25,31 @@ export const setJellyfinUser = (id: string) => {
|
||||||
jellyfinUser = id;
|
jellyfinUser = id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let hijackActive = false;
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
while (!Spicetify.showNotification) {
|
while (!Spicetify.showNotification) {
|
||||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Automatically login to Jellyfin if settings are present
|
||||||
|
const url = Spicetify.LocalStorage.get("jellyfin-url");
|
||||||
|
const token = Spicetify.LocalStorage.get("jellyfin-token");
|
||||||
|
|
||||||
|
if (url && token) {
|
||||||
|
const servers = await jellyfin.discovery.getRecommendedServerCandidates(url);
|
||||||
|
const best = jellyfin.discovery.findBestServer(servers);
|
||||||
|
if (!best) {
|
||||||
|
Spicetify.showNotification("Failed to connect to Jellyfin server!", true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
jellyfinApi = jellyfin.createApi(best.address);
|
||||||
|
jellyfinApi.accessToken = token;
|
||||||
|
|
||||||
|
const user = await getUserApi(jellyfinApi).getCurrentUser();
|
||||||
|
if (user.data.Id) setJellyfinUser(user.data.Id);
|
||||||
|
}
|
||||||
|
|
||||||
const audio = new Audio();
|
const audio = new Audio();
|
||||||
|
|
||||||
// Topbar button for settings
|
// Topbar button for settings
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,16 @@ import React, { useEffect, useState } from "react";
|
||||||
import { getQuickConnectApi } from "@jellyfin/sdk/lib/utils/api/quick-connect-api";
|
import { getQuickConnectApi } from "@jellyfin/sdk/lib/utils/api/quick-connect-api";
|
||||||
import { getUserApi } from "@jellyfin/sdk/lib/utils/api/user-api";
|
import { getUserApi } from "@jellyfin/sdk/lib/utils/api/user-api";
|
||||||
|
|
||||||
import { jellyfin, jellyfinApi, setJellyfinApi, setJellyfinUser } from "./app";
|
import { jellyfin, jellyfinApi, jellyfinUser, setJellyfinApi, setJellyfinUser } from "./app";
|
||||||
import styles from "./styles.module.css";
|
import styles from "./styles.module.css";
|
||||||
|
|
||||||
type View = "url" | "password" | "quick-connect";
|
type View = "url" | "password" | "quick-connect" | "settings";
|
||||||
|
|
||||||
export default function SettingsModal() {
|
export default function SettingsModal() {
|
||||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
|
||||||
const [url, setUrl] = useState(Spicetify.LocalStorage.get("jellyfin-url") || "");
|
const [url, setUrl] = useState(Spicetify.LocalStorage.get("jellyfin-url") || "");
|
||||||
const [username, setUsername] = useState("");
|
const [username, setUsername] = useState("");
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const [view, setView] = useState<View>("url");
|
const [view, setView] = useState<View>(jellyfinUser ? "settings" : "url");
|
||||||
const [quickConnectCode, setQuickConnectCode] = useState("");
|
const [quickConnectCode, setQuickConnectCode] = useState("");
|
||||||
|
|
||||||
const createApi = async () => {
|
const createApi = async () => {
|
||||||
|
|
@ -42,16 +41,18 @@ export default function SettingsModal() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
jellyfinApi!.accessToken = auth.data.AccessToken;
|
jellyfinApi.accessToken = auth.data.AccessToken;
|
||||||
Spicetify.LocalStorage.set("jellyfin-token", auth.data.AccessToken);
|
Spicetify.LocalStorage.set("jellyfin-token", auth.data.AccessToken);
|
||||||
|
|
||||||
const user = await getUserApi(jellyfinApi!).getCurrentUser();
|
const user = await getUserApi(jellyfinApi).getCurrentUser();
|
||||||
if (user.data.Id) {
|
if (user.data.Id) setJellyfinUser(user.data.Id);
|
||||||
setJellyfinUser(user.data.Id!);
|
|
||||||
Spicetify.LocalStorage.set("jellyfin-user", user.data.Id!);
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsLoggedIn(true);
|
setView("settings");
|
||||||
|
};
|
||||||
|
|
||||||
|
const logout = () => {
|
||||||
|
Spicetify.LocalStorage.remove("jellyfin-token");
|
||||||
|
setView("url");
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -93,12 +94,9 @@ export default function SettingsModal() {
|
||||||
Spicetify.LocalStorage.set("jellyfin-token", auth.data.AccessToken);
|
Spicetify.LocalStorage.set("jellyfin-token", auth.data.AccessToken);
|
||||||
|
|
||||||
const user = await getUserApi(jellyfinApi!).getCurrentUser();
|
const user = await getUserApi(jellyfinApi!).getCurrentUser();
|
||||||
if (user.data.Id) {
|
if (user.data.Id) setJellyfinUser(user.data.Id);
|
||||||
setJellyfinUser(user.data.Id!);
|
|
||||||
Spicetify.LocalStorage.set("jellyfin-user", user.data.Id!);
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsLoggedIn(true);
|
setView("settings");
|
||||||
} catch {
|
} catch {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
Spicetify.showNotification("Quick Connect polling failed!", true);
|
Spicetify.showNotification("Quick Connect polling failed!", true);
|
||||||
|
|
@ -110,7 +108,7 @@ export default function SettingsModal() {
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [view]);
|
}, [view]);
|
||||||
|
|
||||||
if (isLoggedIn)
|
if (view === "settings")
|
||||||
return (
|
return (
|
||||||
<div className={styles.modal}>
|
<div className={styles.modal}>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 512 512">
|
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 512 512">
|
||||||
|
|
@ -151,13 +149,7 @@ export default function SettingsModal() {
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<hr className={styles.hr} />
|
<hr className={styles.hr} />
|
||||||
<button
|
<button onClick={logout} className={styles.button}>
|
||||||
onClick={() => {
|
|
||||||
setIsLoggedIn(false);
|
|
||||||
setView("url");
|
|
||||||
}}
|
|
||||||
className={styles.button}
|
|
||||||
>
|
|
||||||
Log out
|
Log out
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue