mirror of
https://github.com/ranaldsgift/KefinTweaks.git
synced 2026-11-05 15:52:47 +01:00
Update authentication headers to support v12 requirements, also add v12 skin support to skins from v11
This commit is contained in:
1 parent
290b36f7bf
commit
6f2617f942
15 files changed
+135
-153
No files matched your search
+27
-15
@@ -7,6 +7,22 @@
|
||||
|
||||
console.log('[KefinTweaks Injector] Initializing...');
|
||||
|
||||
function getAuthHeader() {
|
||||
const token = ApiClient.accessToken();
|
||||
const client = typeof ApiClient.applicationName === 'function' ? ApiClient.applicationName() : 'Jellyfin Web';
|
||||
const device = typeof ApiClient.deviceName === 'function' ? ApiClient.deviceName() : (navigator.userAgent.includes('Chrome') ? 'Chrome' : 'Browser');
|
||||
const deviceId = typeof ApiClient.deviceId === 'function' ? ApiClient.deviceId() : '';
|
||||
const version = ApiClient._appVersion || ApiClient._serverVersion || '';
|
||||
const parts = [
|
||||
`Client="${encodeURIComponent(client)}"`,
|
||||
`Device="${encodeURIComponent(device)}"`,
|
||||
`DeviceId="${encodeURIComponent(deviceId)}"`,
|
||||
`Version="${encodeURIComponent(version)}"`,
|
||||
`Token="${encodeURIComponent(token)}"`
|
||||
];
|
||||
return `MediaBrowser ${parts.join(', ')}`;
|
||||
}
|
||||
|
||||
// Check for global configuration reset
|
||||
try {
|
||||
const config = window.KefinTweaksConfig || {};
|
||||
@@ -110,7 +126,7 @@
|
||||
name: 'utils',
|
||||
script: 'utils.js',
|
||||
css: null,
|
||||
dependencies: [],
|
||||
dependencies: ['apiHelper'],
|
||||
description: 'Common utilities for page view management and MutationObserver conversion'
|
||||
},
|
||||
{
|
||||
@@ -131,7 +147,7 @@
|
||||
name: 'skinManager',
|
||||
script: 'skinManager.js',
|
||||
css: 'defaultSkin.css',
|
||||
dependencies: ['utils', 'skinConfigLegacyDefaults', 'skinConfig', 'modal'],
|
||||
dependencies: ['utils', 'skinConfigLegacyDefaults', 'skinConfig', 'modal', 'apiHelper'],
|
||||
priority: true, // Load immediately after dependencies to reduce UI disruption
|
||||
description: 'Adds skin selection dropdown to display preferences page and manages skin CSS loading'
|
||||
},
|
||||
@@ -202,7 +218,7 @@
|
||||
name: 'headerTabs',
|
||||
script: 'headerTabs.js',
|
||||
css: null,
|
||||
dependencies: [],
|
||||
dependencies: ['apiHelper'],
|
||||
description: 'Header tab improvements'
|
||||
},
|
||||
{
|
||||
@@ -230,7 +246,7 @@
|
||||
name: 'updoot',
|
||||
script: 'updoot.js',
|
||||
css: null,
|
||||
dependencies: [],
|
||||
dependencies: ['apiHelper'],
|
||||
description: 'Upvote functionality provided by https://github.com/BobHasNoSoul/jellyfin-updoot'
|
||||
},
|
||||
{
|
||||
@@ -251,14 +267,14 @@
|
||||
name: 'removeContinue',
|
||||
script: 'removeContinue.js',
|
||||
css: null,
|
||||
dependencies: [],
|
||||
dependencies: ['apiHelper'],
|
||||
description: 'Adds remove from continue watching functionality to cards with data-position-ticks'
|
||||
},
|
||||
{
|
||||
name: 'subtitleSearch',
|
||||
script: 'subtitleSearch.js',
|
||||
css: 'subtitleSearch.css',
|
||||
dependencies: ['toaster'],
|
||||
dependencies: ['toaster', 'apiHelper'],
|
||||
description: 'Adds subtitle search functionality to the video OSD, allowing users to search and download subtitles from remote sources'
|
||||
},
|
||||
{
|
||||
@@ -624,7 +640,7 @@
|
||||
}
|
||||
|
||||
async function loadConfigurationJS() {
|
||||
const configDependencyNames = ['modal', 'toaster', 'utils', 'apiHelper', 'indexedDBCache'];
|
||||
const configDependencyNames = ['modal', 'toaster', 'apiHelper', 'utils', 'indexedDBCache'];
|
||||
for (const depName of configDependencyNames) {
|
||||
const depScript = SCRIPT_DEFINITIONS.find(script => script.name === depName);
|
||||
if (depScript) {
|
||||
@@ -839,11 +855,10 @@
|
||||
}
|
||||
|
||||
const server = ApiClient._serverAddress;
|
||||
const token = ApiClient.accessToken();
|
||||
|
||||
const response = await fetch(`${server}/Plugins`, {
|
||||
headers: {
|
||||
'X-Emby-Token': token
|
||||
'Authorization': getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -870,11 +885,10 @@
|
||||
}
|
||||
|
||||
const server = ApiClient._serverAddress;
|
||||
const token = ApiClient.accessToken();
|
||||
|
||||
const response = await fetch(`${server}/Plugins/${pluginId}/Configuration`, {
|
||||
headers: {
|
||||
'X-Emby-Token': token
|
||||
'Authorization': getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -897,12 +911,11 @@
|
||||
}
|
||||
|
||||
const server = ApiClient._serverAddress;
|
||||
const token = ApiClient.accessToken();
|
||||
|
||||
const response = await fetch(`${server}/Plugins/${pluginId}/Configuration`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Emby-Token': token,
|
||||
'Authorization': getAuthHeader(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(config)
|
||||
@@ -956,11 +969,10 @@
|
||||
|
||||
// Get current CustomTabs config
|
||||
const server = ApiClient._serverAddress;
|
||||
const token = ApiClient.accessToken();
|
||||
|
||||
const response = await fetch(`${server}/CustomTabs/Config`, {
|
||||
headers: {
|
||||
'X-Emby-Token': token
|
||||
'Authorization': getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+8
-11
@@ -21,7 +21,6 @@
|
||||
async function getActiveSession() {
|
||||
ensureApiClient();
|
||||
|
||||
const token = ApiClient.accessToken();
|
||||
const serverUrl = ApiClient.serverAddress();
|
||||
const deviceId = ApiClient.deviceId();
|
||||
|
||||
@@ -39,7 +38,7 @@
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Authorization': `MediaBrowser Token="${token}"`
|
||||
'Authorization': getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -71,7 +70,6 @@
|
||||
const session = await getActiveSession();
|
||||
const sessionId = session.Id;
|
||||
|
||||
const token = ApiClient.accessToken();
|
||||
const serverUrl = ApiClient.serverAddress();
|
||||
|
||||
const limitedIds = ids.slice(0, MAX_PLAY_NOW_IDS);
|
||||
@@ -102,7 +100,7 @@
|
||||
const response = await fetch(`${serverUrl}/Sessions/${sessionId}/Playing?${params.toString()}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Emby-Token': token,
|
||||
'Authorization': getAuthHeader(),
|
||||
}
|
||||
});
|
||||
|
||||
@@ -115,7 +113,6 @@
|
||||
const session = await getActiveSession();
|
||||
const sessionId = session.Id;
|
||||
|
||||
const token = ApiClient.accessToken();
|
||||
const serverUrl = ApiClient.serverAddress();
|
||||
|
||||
const params = new URLSearchParams({
|
||||
@@ -131,7 +128,7 @@
|
||||
const response = await fetch(`${serverUrl}/Sessions/${sessionId}/Playing?${params.toString()}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Emby-Token': token
|
||||
'Authorization': getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -276,10 +273,9 @@
|
||||
|
||||
// Fetch from API
|
||||
try {
|
||||
const token = ApiClient.accessToken();
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
'X-Emby-Token': token,
|
||||
'Authorization': getAuthHeader(),
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
});
|
||||
@@ -426,7 +422,7 @@
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Emby-Token': ApiClient.accessToken()
|
||||
'Authorization': getAuthHeader()
|
||||
},
|
||||
body: JSON.stringify({
|
||||
Rating: rating,
|
||||
@@ -502,7 +498,6 @@
|
||||
throw new Error('No active session found');
|
||||
}
|
||||
|
||||
const token = ApiClient.accessToken();
|
||||
const serverUrl = ApiClient.serverAddress();
|
||||
|
||||
// Build NowPlayingQueue array - each item needs at least an Id
|
||||
@@ -522,7 +517,7 @@
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `MediaBrowser Token="${token}"`
|
||||
'Authorization': getAuthHeader()
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
@@ -555,6 +550,8 @@
|
||||
|
||||
return await response.json();
|
||||
},
|
||||
|
||||
getAuthHeader,
|
||||
};
|
||||
|
||||
// Expose apiHelper to global window object
|
||||
|
||||
@@ -3782,7 +3782,7 @@
|
||||
const token = window.ApiClient.accessToken();
|
||||
|
||||
const response = await fetch(`${serverAddress}/Users/${userId}/Items?IncludeItemTypes=BoxSet,CollectionFolder&Recursive=true&Fields=ItemCounts`, {
|
||||
headers: { 'X-Emby-Token': token }
|
||||
headers: { 'Authorization': apiHelper.getAuthHeader() }
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -3902,7 +3902,7 @@
|
||||
const token = window.ApiClient.accessToken();
|
||||
|
||||
const response = await fetch(`${serverAddress}/Users/${userId}/Items?IncludeItemTypes=Playlist&Recursive=true&Fields=ItemCounts`, {
|
||||
headers: { 'X-Emby-Token': token }
|
||||
headers: { 'Authorization': apiHelper.getAuthHeader() }
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -4022,7 +4022,7 @@
|
||||
const token = window.ApiClient.accessToken();
|
||||
|
||||
const response = await fetch(`${serverAddress}/Users/${userId}/Items?IncludeItemTypes=BoxSet,CollectionFolder&Recursive=true&Fields=ItemCounts`, {
|
||||
headers: { 'X-Emby-Token': token }
|
||||
headers: { 'Authorization': apiHelper.getAuthHeader() }
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -4160,7 +4160,7 @@
|
||||
const token = window.ApiClient.accessToken();
|
||||
|
||||
const response = await fetch(`${serverAddress}/Users/${userId}/Items?IncludeItemTypes=Playlist&Recursive=true&Fields=ItemCounts`, {
|
||||
headers: { 'X-Emby-Token': token }
|
||||
headers: { 'Authorization': apiHelper.getAuthHeader() }
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -4738,23 +4738,10 @@
|
||||
}
|
||||
|
||||
const server = ApiClient._serverAddress;
|
||||
const token = ApiClient.accessToken();
|
||||
const client = typeof ApiClient.applicationName === 'function' ? ApiClient.applicationName() : 'Jellyfin Web';
|
||||
const device = typeof ApiClient.deviceName === 'function' ? ApiClient.deviceName() : (navigator.userAgent.includes('Chrome') ? 'Chrome' : 'Browser');
|
||||
const deviceId = typeof ApiClient.deviceId === 'function' ? ApiClient.deviceId() : '';
|
||||
const version = ApiClient._appVersion || ApiClient._serverVersion || '';
|
||||
const parts = [
|
||||
`Client="${encodeURIComponent(client)}"`,
|
||||
`Device="${encodeURIComponent(device)}"`,
|
||||
`DeviceId="${encodeURIComponent(deviceId)}"`,
|
||||
`Version="${encodeURIComponent(version)}"`,
|
||||
`Token="${encodeURIComponent(token)}"`
|
||||
];
|
||||
const auth = `MediaBrowser ${parts.join(', ')}`;
|
||||
|
||||
const response = await fetch(`${server}/Plugins/${pluginId}/Configuration`, {
|
||||
headers: {
|
||||
'Authorization': auth
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Authorization': `MediaBrowser Token="${token}"`
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
LOG(`Fetching Next Up episode for series: ${seriesId}`);
|
||||
const nextUpUrl = `${serverUrl}/Shows/NextUp?SeriesId=${seriesId}&UserId=${userId}&Fields=MediaSourceCount`;
|
||||
const nextUpRes = await fetch(nextUpUrl, {
|
||||
headers: { "Authorization": `MediaBrowser Token="${token}"` }
|
||||
headers: { "Authorization": apiHelper.getAuthHeader() }
|
||||
});
|
||||
|
||||
if (!nextUpRes.ok) {
|
||||
@@ -69,7 +69,7 @@
|
||||
LOG(`Fetching episodes for series: ${seriesId}`);
|
||||
const episodesUrl = `${serverUrl}/Shows/${seriesId}/Episodes?UserId=${userId}&Fields=UserData`;
|
||||
const episodesRes = await fetch(episodesUrl, {
|
||||
headers: { "Authorization": `MediaBrowser Token="${token}"` }
|
||||
headers: { "Authorization": apiHelper.getAuthHeader() }
|
||||
});
|
||||
|
||||
if (!episodesRes.ok) {
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
`${serverAddress}/DisplayPreferences/usersettings?userId=${userId}&client=emby`,
|
||||
{
|
||||
headers: {
|
||||
'X-Emby-Token': accessToken
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -345,7 +345,7 @@
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Emby-Token": ApiClient._serverInfo.AccessToken || ApiClient.accessToken(),
|
||||
"Authorization": apiHelper.getAuthHeader(),
|
||||
},
|
||||
});
|
||||
const customTabs = await response.json();
|
||||
|
||||
+15
-15
@@ -1112,7 +1112,7 @@
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1552,7 +1552,7 @@
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
'Authorization': `MediaBrowser Token="${ApiClient.accessToken()}"`
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1649,7 +1649,7 @@
|
||||
try {
|
||||
const response = await fetch(`${serverUrl}/Genres?IncludeItemTypes=Movie`, {
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1745,7 +1745,7 @@
|
||||
queries.map(async (query) => {
|
||||
const response = await fetch(query.url, {
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1854,7 +1854,7 @@
|
||||
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2214,7 +2214,7 @@
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2251,7 +2251,7 @@
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2565,7 +2565,7 @@
|
||||
const studiosUrl = `${serverUrl}/Studios?SortBy=SortName&SortOrder=Ascending&IncludeItemTypes=Series&Recursive=true&Fields=DateCreated%2CPrimaryImageAspectRatio&StartIndex=0&ParentId=${library.Id}&userId=${userId}${filterParam}`;
|
||||
const response = await fetch(studiosUrl, {
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2646,7 +2646,7 @@
|
||||
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2680,7 +2680,7 @@
|
||||
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3828,7 +3828,7 @@
|
||||
const movieUrl = `${serverUrl}/Users/${userId}/Items/${recentMovie.Id}?Fields=People`;
|
||||
const movieResponse = await fetch(movieUrl, {
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3890,7 +3890,7 @@
|
||||
const movieUrl = `${serverUrl}/Users/${userId}/Items/${recentMovie.Id}?Fields=People`;
|
||||
const movieResponse = await fetch(movieUrl, {
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3958,7 +3958,7 @@
|
||||
const movieUrl = `${serverUrl}/Users/${userId}/Items/${recentMovie.Id}?Fields=People`;
|
||||
const movieResponse = await fetch(movieUrl, {
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -4708,7 +4708,7 @@
|
||||
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5391,7 +5391,7 @@
|
||||
const serverAddress = ApiClient.serverAddress();
|
||||
const token = ApiClient.accessToken();
|
||||
const genresResponse = await fetch(`${serverAddress}/Genres?IncludeItemTypes=Movie`, {
|
||||
headers: { "Authorization": `MediaBrowser Token="${token}"` }
|
||||
headers: { "Authorization": apiHelper.getAuthHeader() }
|
||||
});
|
||||
|
||||
if (!genresResponse.ok) {
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
const response = await fetch(userDataUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`,
|
||||
"Authorization": apiHelper.getAuthHeader(),
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
@@ -196,7 +196,7 @@
|
||||
const response = await fetch(userDataUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`,
|
||||
"Authorization": apiHelper.getAuthHeader(),
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(updatedUserData)
|
||||
|
||||
+17
-16
@@ -24,7 +24,7 @@
|
||||
LOG(`Fetching Next Up episode for series: ${seriesId}`);
|
||||
const nextUpUrl = `${serverUrl}/Shows/NextUp?SeriesId=${seriesId}&UserId=${userId}&Fields=MediaSourceCount`;
|
||||
const nextUpRes = await fetch(nextUpUrl, {
|
||||
headers: { "Authorization": `MediaBrowser Token="${token}"` }
|
||||
headers: { "Authorization": apiHelper.getAuthHeader() }
|
||||
});
|
||||
|
||||
if (!nextUpRes.ok) {
|
||||
@@ -63,7 +63,7 @@
|
||||
LOG(`Fetching season data for season ID: ${seasonId}`);
|
||||
const seasonUrl = `${serverUrl}/Items/${seasonId}?UserId=${userId}`;
|
||||
const seasonRes = await fetch(seasonUrl, {
|
||||
headers: { "Authorization": `MediaBrowser Token="${token}"` }
|
||||
headers: { "Authorization": apiHelper.getAuthHeader() }
|
||||
});
|
||||
|
||||
if (!seasonRes.ok) {
|
||||
@@ -95,7 +95,7 @@
|
||||
LOG(`Fetching episodes for series: ${seriesId}${seasonId ? ` (Season ID: ${seasonId})` : ''}`);
|
||||
const episodesUrl = `${serverUrl}/Shows/${seriesId}/Episodes?UserId=${userId}&Fields=UserData`;
|
||||
const episodesRes = await fetch(episodesUrl, {
|
||||
headers: { "Authorization": `MediaBrowser Token="${token}"` }
|
||||
headers: { "Authorization": apiHelper.getAuthHeader() }
|
||||
});
|
||||
|
||||
if (!episodesRes.ok) {
|
||||
@@ -559,18 +559,17 @@
|
||||
|
||||
// Insert episodes section right after NextUp section (or at the beginning if no NextUp)
|
||||
const detailPageContent = activePage.querySelector('.detailPageContent');
|
||||
if (detailPageContent) {
|
||||
if (nextUpSection && nextUpSection.parentNode) {
|
||||
nextUpSection.parentNode.insertBefore(seasonSection, nextUpSection.nextSibling);
|
||||
} else {
|
||||
// Find a good insertion point - after NextUp or before childrenCollapsible
|
||||
const childrenCollapsible = activePage.querySelector('.detailSection #listChildrenCollapsible') ||
|
||||
activePage.querySelector('#childrenCollapsible');
|
||||
if (childrenCollapsible && childrenCollapsible.parentNode) {
|
||||
childrenCollapsible.parentNode.insertBefore(seasonSection, childrenCollapsible);
|
||||
} else {
|
||||
detailPageContent.insertBefore(seasonSection, detailPageContent.firstChild);
|
||||
}
|
||||
if (nextUpSection && nextUpSection.parentNode) {
|
||||
nextUpSection.parentNode.insertBefore(seasonSection, nextUpSection.nextSibling);
|
||||
} else {
|
||||
// Find a good insertion point - after NextUp or before childrenCollapsible
|
||||
const childrenCollapsible = activePage.querySelector('.detailSection #listChildrenCollapsible') ||
|
||||
activePage.querySelector('#childrenCollapsible');
|
||||
if (childrenCollapsible && childrenCollapsible.parentNode) {
|
||||
childrenCollapsible.parentNode.insertBefore(seasonSection, childrenCollapsible);
|
||||
}
|
||||
else if (detailPageContent){
|
||||
detailPageContent.insertBefore(seasonSection, detailPageContent.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -817,7 +816,9 @@
|
||||
}
|
||||
|
||||
// Mark as processed
|
||||
activePage.dataset.seriesEpisodesProcessed = 'true';
|
||||
if (activePage.querySelector('.series-episodes-section')) {
|
||||
activePage.dataset.seriesEpisodesProcessed = 'true';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+12
-12
@@ -107,7 +107,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
majorServerVersions: [11],
|
||||
majorServerVersions: [11, 12],
|
||||
urls: [
|
||||
'https://cdn.jsdelivr.net/gh/lscambo13/ElegantFin@main/Theme/ElegantFin-jellyfin-theme-build-latest-minified.css',
|
||||
`${getKefinTweaksRoot()}skins/elegant-kefin.css`,
|
||||
@@ -159,7 +159,7 @@
|
||||
author: 'KartoffelChipss',
|
||||
url: [
|
||||
{
|
||||
majorServerVersions: [10, 11],
|
||||
majorServerVersions: [10, 11, 12],
|
||||
urls: [
|
||||
'https://cdn.jsdelivr.net/gh/KartoffelChipss/NeutralFin@latest/theme/neutralfin-minified.css',
|
||||
'https://cdn.jsdelivr.net/gh/KartoffelChipss/Jellyfin-Lucide@main/theme/jellyfin-lucide.css',
|
||||
@@ -211,7 +211,7 @@
|
||||
author: 'KBH-Reeper',
|
||||
url: [
|
||||
{
|
||||
majorServerVersions: [10, 11],
|
||||
majorServerVersions: [10, 11, 12],
|
||||
urls: [
|
||||
'https://cdn.jsdelivr.net/gh/KBH-Reeper/GlassFin@latest/Theme/GlassFin-Theme-latest-stable.css',
|
||||
'https://cdn.jsdelivr.net/gh/KBH-Reeper/GlassFin@latest/Theme/PluginStyling/MediaBar-Plugin-latest.css',
|
||||
@@ -296,7 +296,7 @@
|
||||
urls: ['https://cdn.jsdelivr.net/gh/ranaldsgift/Jellypane@main/jellypane.css']
|
||||
},
|
||||
{
|
||||
majorServerVersions: [11],
|
||||
majorServerVersions: [11, 12],
|
||||
urls: ['https://cdn.jsdelivr.net/gh/tedhinklater/Jellypane@main/jellypane.css']
|
||||
},
|
||||
],
|
||||
@@ -311,7 +311,7 @@
|
||||
urls: ['https://cdn.jsdelivr.net/gh/tedhinklater/finimalism@main/finimalism7.css']
|
||||
},
|
||||
{
|
||||
majorServerVersions: [11],
|
||||
majorServerVersions: [11, 12],
|
||||
urls: ['https://cdn.jsdelivr.net/gh/tedhinklater/finimalism@main/finimalism10.11.css']
|
||||
}
|
||||
],
|
||||
@@ -338,7 +338,7 @@
|
||||
urls: ['https://cdn.jsdelivr.net/gh/n00bcodr/jellyfish@main/theme.css']
|
||||
},
|
||||
{
|
||||
majorServerVersions: [11],
|
||||
majorServerVersions: [11, 12],
|
||||
urls: [
|
||||
'https://cdn.jsdelivr.net/gh/n00bcodr/jellyfish@main/theme.css',
|
||||
'https://cdn.jsdelivr.net/gh/n00bcodr/jellyfish@main/10.11_fixes.css'
|
||||
@@ -428,7 +428,7 @@
|
||||
author: 'alexyle',
|
||||
url: [
|
||||
{
|
||||
majorServerVersions: [10, 11],
|
||||
majorServerVersions: [10, 11, 12],
|
||||
urls: ['https://cdn.jsdelivr.net/gh/alexyle/jellyfin-theme@main/glassmorphism/theme.css']
|
||||
}
|
||||
],
|
||||
@@ -491,7 +491,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
majorServerVersions: [11],
|
||||
majorServerVersions: [11, 12],
|
||||
urls: [
|
||||
'https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/complete.css',
|
||||
`${getKefinTweaksRoot()}skins/jamfin-kefin.css`
|
||||
@@ -539,7 +539,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
majorServerVersions: [11],
|
||||
majorServerVersions: [11, 12],
|
||||
urls: [
|
||||
'https://cdn.jsdelivr.net/gh/loof2736/scyfin@latest/CSS/scyfin-theme.css',
|
||||
`${getKefinTweaksRoot()}skins/scyfin-kefin.css`
|
||||
@@ -581,7 +581,7 @@
|
||||
author: 'Catppuccin',
|
||||
url: [
|
||||
{
|
||||
majorServerVersions: [10, 11],
|
||||
majorServerVersions: [10, 11, 12],
|
||||
urls: ['https://jellyfin.catppuccin.com/theme.css']
|
||||
}
|
||||
],
|
||||
@@ -616,7 +616,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
majorServerVersions: [11],
|
||||
majorServerVersions: [11, 12],
|
||||
urls: [
|
||||
'https://cdn.jsdelivr.net/gh/LitCastVlog/Flow@main/CSS/ScyFlow-oneliner.css',
|
||||
'https://cdn.jsdelivr.net/gh/LitCastVlog/Flow@main/CSS/ScyFlow-Compatibility.css',
|
||||
@@ -719,7 +719,7 @@
|
||||
author: 'CTalvio',
|
||||
url: [
|
||||
{
|
||||
majorServerVersions: [10, 11],
|
||||
majorServerVersions: [10, 11, 12],
|
||||
urls: [
|
||||
'https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/base.css',
|
||||
'https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/accentlist.css',
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
|
||||
function getMajorServerVersion(version) {
|
||||
const versionParts = version.split('.');
|
||||
const firstPartInt = parseInt(versionParts[0], 10);
|
||||
if (firstPartInt >= 12) {
|
||||
return 12;
|
||||
}
|
||||
|
||||
if (versionParts.length >= 2) {
|
||||
const majorVersion = parseInt(versionParts[1], 10);
|
||||
if (!isNaN(majorVersion)) {
|
||||
@@ -360,7 +365,7 @@
|
||||
|
||||
// Find JavaScript Injector plugin
|
||||
const pluginsResponse = await fetch(`${server}/Plugins`, {
|
||||
headers: { 'X-Emby-Token': token }
|
||||
headers: { 'Authorization': apiHelper.getAuthHeader() }
|
||||
});
|
||||
|
||||
if (!pluginsResponse.ok) {
|
||||
@@ -382,7 +387,7 @@
|
||||
// Get current injector config
|
||||
const configUrl = `${server}/Plugins/${pluginId}/Configuration`;
|
||||
const configResponse = await fetch(configUrl, {
|
||||
headers: { 'X-Emby-Token': token }
|
||||
headers: { 'Authorization': apiHelper.getAuthHeader() }
|
||||
});
|
||||
|
||||
if (!configResponse.ok) {
|
||||
@@ -421,7 +426,7 @@ window.KefinTweaksConfig = ${JSON.stringify(configToBackup, null, 2)};`;
|
||||
const saveResponse = await fetch(configUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Emby-Token': token,
|
||||
'Authorization': apiHelper.getAuthHeader(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(injectorConfig)
|
||||
|
||||
@@ -338,7 +338,7 @@
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Authorization': `MediaBrowser Token="${token}"`
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -425,7 +425,7 @@
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Authorization': `MediaBrowser Token="${token}"`
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -512,7 +512,7 @@
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Authorization': `MediaBrowser Token="${token}"`
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -588,7 +588,7 @@
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Authorization': `MediaBrowser Token="${token}"`
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -638,7 +638,7 @@
|
||||
const response = await fetch(`${serverUrl}/Sessions/${sessionId}/Command`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Emby-Token': token,
|
||||
'Authorization': apiHelper.getAuthHeader(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
@@ -788,7 +788,7 @@
|
||||
const commandResponse = await fetch(`${serverUrl}/Sessions/${sessionId}/Playing?${params.toString()}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Emby-Token': token
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -903,7 +903,7 @@
|
||||
const response = await fetch(`${serverUrl}/Items/${itemId}/RemoteSearch/Subtitles/${subId}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `MediaBrowser Token="${token}"`
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+2
-2
@@ -29,11 +29,11 @@
|
||||
async function fetchItemDetails(itemId) {
|
||||
console.log('Fetching item details for itemId:', itemId);
|
||||
try {
|
||||
const url = `${serverUrl}/Items/${itemId}?api_key=${apiKey}`; // Fixed typo from original: 'melalui' to 'apiKey'
|
||||
const url = `${serverUrl}/Items/${itemId}`;
|
||||
console.log('Requesting:', url);
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: { 'X-Emby-Token': apiKey }
|
||||
headers: { 'Authorization': apiHelper.getAuthHeader() }
|
||||
});
|
||||
if (!response.ok) {
|
||||
console.error('Fetch item details failed:', `HTTP ${response.status}`);
|
||||
|
||||
+3
-23
@@ -51,26 +51,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build MediaBrowser Authorization header
|
||||
* @returns {string} - Authorization header
|
||||
*/
|
||||
function getAuthHeader() {
|
||||
const token = ApiClient.accessToken();
|
||||
const client = typeof ApiClient.applicationName === 'function' ? ApiClient.applicationName() : 'Jellyfin Web';
|
||||
const device = typeof ApiClient.deviceName === 'function' ? ApiClient.deviceName() : (navigator.userAgent.includes('Chrome') ? 'Chrome' : 'Browser');
|
||||
const deviceId = typeof ApiClient.deviceId === 'function' ? ApiClient.deviceId() : '';
|
||||
const version = ApiClient._appVersion || ApiClient._serverVersion || '';
|
||||
const parts = [
|
||||
`Client="${encodeURIComponent(client)}"`,
|
||||
`Device="${encodeURIComponent(device)}"`,
|
||||
`DeviceId="${encodeURIComponent(deviceId)}"`,
|
||||
`Version="${encodeURIComponent(version)}"`,
|
||||
`Token="${encodeURIComponent(token)}"`
|
||||
];
|
||||
return `MediaBrowser ${parts.join(', ')}`;
|
||||
}
|
||||
|
||||
// Array to store registered handlers
|
||||
const handlers = [];
|
||||
|
||||
@@ -452,7 +432,7 @@
|
||||
// Get current injector config
|
||||
const configUrl = `${server}/Plugins/${pluginId}/Configuration`;
|
||||
const configResponse = await fetch(configUrl, {
|
||||
headers: { 'Authorization': getAuthHeader() }
|
||||
headers: { 'Authorization': apiHelper.getAuthHeader() }
|
||||
});
|
||||
|
||||
if (!configResponse.ok) {
|
||||
@@ -495,7 +475,7 @@ window.KefinTweaksConfig = ${JSON.stringify(configToSave, null, 2)};`;
|
||||
const saveResponse = await fetch(configUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': getAuthHeader(),
|
||||
'Authorization': apiHelper.getAuthHeader(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(injectorConfig)
|
||||
@@ -579,7 +559,7 @@ window.KefinTweaksConfig = ${JSON.stringify(configToSave, null, 2)};`;
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Emby-Token": ApiClient._serverInfo.AccessToken || ApiClient.accessToken(),
|
||||
"Authorization": apiHelper.getAuthHeader(),
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
+24
-24
@@ -1263,13 +1263,13 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
|
||||
try {
|
||||
const episodeUrl = `${serverUrl}/Items/${episodeId}?UserId=${userId}&Fields=ParentId`;
|
||||
const episodeRes = await fetch(episodeUrl, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } });
|
||||
const episodeRes = await fetch(episodeUrl, { headers: { "Authorization": apiHelper.getAuthHeader() } });
|
||||
const episodeData = await episodeRes.json();
|
||||
|
||||
// Get the series ID from the episode's parent (season) parent
|
||||
if (episodeData.ParentId) {
|
||||
const seasonUrl = `${serverUrl}/Items/${episodeData.ParentId}?UserId=${userId}&Fields=ParentId`;
|
||||
const seasonRes = await fetch(seasonUrl, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } });
|
||||
const seasonRes = await fetch(seasonUrl, { headers: { "Authorization": apiHelper.getAuthHeader() } });
|
||||
const seasonData = await seasonRes.json();
|
||||
|
||||
return seasonData.ParentId || null;
|
||||
@@ -1351,7 +1351,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
try {
|
||||
// Fetch the series item
|
||||
const seriesUrl = `${serverUrl}/Items/${seriesId}?UserId=${userId}&Fields=UserData,RecursiveItemCount&EnableImageTypes=Primary,Banner`;
|
||||
const seriesRes = await fetch(seriesUrl, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } });
|
||||
const seriesRes = await fetch(seriesUrl, { headers: { "Authorization": apiHelper.getAuthHeader() } });
|
||||
const series = await seriesRes.json();
|
||||
|
||||
if (!series || !series.Id) {
|
||||
@@ -2505,7 +2505,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
const seriesUrl = `${serverUrl}/Items?IncludeItemTypes=Series&UserId=${userId}&Recursive=true&Fields=UserData,RecursiveItemCount&EnableImageTypes=Primary,Banner`;
|
||||
|
||||
try {
|
||||
const seriesRes = await fetch(seriesUrl, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } });
|
||||
const seriesRes = await fetch(seriesUrl, { headers: { "Authorization": apiHelper.getAuthHeader() } });
|
||||
const seriesData = await seriesRes.json();
|
||||
const series = seriesData.Items || [];
|
||||
|
||||
@@ -2596,7 +2596,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
|
||||
// Get all episodes including missing ones to get accurate TotalRecordCount
|
||||
const episodesUrl = `${serverUrl}/Shows/${series.Id}/Episodes?UserId=${userId}&Fields=UserData&EnableImageTypes=Primary`;
|
||||
const episodesRes = await fetch(episodesUrl, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } });
|
||||
const episodesRes = await fetch(episodesUrl, { headers: { "Authorization": apiHelper.getAuthHeader() } });
|
||||
const episodesData = await episodesRes.json();
|
||||
let episodes = episodesData.Items || [];
|
||||
|
||||
@@ -2736,7 +2736,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
const toggleRes = await fetch(toggleUrl, {
|
||||
method: method,
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`
|
||||
"Authorization": apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3803,7 +3803,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
const url = `${serverUrl}/Users/${userId}/Items?IncludeItemTypes=Playlist&Recursive=true&Fields=ChildCount`;
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
'Authorization': `MediaBrowser Token="${token}"`
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -4039,7 +4039,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
const response = await fetch(`${serverUrl}/Playlists?${params.toString()}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `MediaBrowser Token="${token}"`
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -4062,7 +4062,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
// Remove existing entries
|
||||
const existingItemsResponse = await fetch(`${serverUrl}/Playlists/${playlistId}/Items`, {
|
||||
headers: {
|
||||
'Authorization': `MediaBrowser Token="${token}"`
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -4082,7 +4082,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
const deleteResponse = await fetch(`${serverUrl}/Playlists/${playlistId}/Items?${params.toString()}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Authorization': `MediaBrowser Token="${token}"`
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
if (!deleteResponse.ok) {
|
||||
@@ -4102,7 +4102,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
const response = await fetch(`${serverUrl}/Playlists/${playlistId}/Items?${params.toString()}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `MediaBrowser Token="${token}"`
|
||||
'Authorization': apiHelper.getAuthHeader()
|
||||
}
|
||||
});
|
||||
if (!response.ok) {
|
||||
@@ -4269,7 +4269,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
if (item.ParentId) {
|
||||
try {
|
||||
const seasonUrl = `${serverUrl}/Items/${item.ParentId}?UserId=${userId}&Fields=Name`;
|
||||
const seasonRes = await fetch(seasonUrl, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } });
|
||||
const seasonRes = await fetch(seasonUrl, { headers: { "Authorization": apiHelper.getAuthHeader() } });
|
||||
const seasonData = await seasonRes.json();
|
||||
if (seasonData.Name) {
|
||||
exportItem.SeasonName = seasonData.Name;
|
||||
@@ -4405,7 +4405,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
let allLibraryItems = [];
|
||||
try {
|
||||
const url = `${serverUrl}/Items?${queryParams.toString()}`;
|
||||
const res = await fetch(url, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } });
|
||||
const res = await fetch(url, { headers: { "Authorization": apiHelper.getAuthHeader() } });
|
||||
const libraryData = await res.json();
|
||||
allLibraryItems = libraryData.Items || [];
|
||||
LOG(`Fetched ${allLibraryItems.length} items from library matching import criteria`);
|
||||
@@ -4439,7 +4439,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
for (const type of watchlistTypes) {
|
||||
try {
|
||||
const url = `${serverUrl}/Items?Filters=Likes&IncludeItemTypes=${type}&UserId=${userId}&Recursive=true&Fields=ProviderIds`;
|
||||
const res = await fetch(url, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } });
|
||||
const res = await fetch(url, { headers: { "Authorization": apiHelper.getAuthHeader() } });
|
||||
const watchlistData = await res.json();
|
||||
const items = watchlistData.Items || [];
|
||||
for (const item of items) {
|
||||
@@ -4547,7 +4547,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
for (const type of types) {
|
||||
try {
|
||||
const url = `${serverUrl}/Items?Filters=Likes&IncludeItemTypes=${type}&UserId=${userId}&Recursive=true&Fields=Id`;
|
||||
const res = await fetch(url, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } });
|
||||
const res = await fetch(url, { headers: { "Authorization": apiHelper.getAuthHeader() } });
|
||||
const data = await res.json();
|
||||
const items = data.Items || [];
|
||||
|
||||
@@ -4869,7 +4869,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
try {
|
||||
// Fetch the series item
|
||||
const seriesUrl = `${serverUrl}/Items/${seriesId}?UserId=${userId}&Fields=UserData,RecursiveItemCount&EnableImageTypes=Primary,Banner`;
|
||||
const seriesRes = await fetch(seriesUrl, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } });
|
||||
const seriesRes = await fetch(seriesUrl, { headers: { "Authorization": apiHelper.getAuthHeader() } });
|
||||
const series = await seriesRes.json();
|
||||
|
||||
if (!series || !series.Id) {
|
||||
@@ -5251,7 +5251,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
const url = `${serverUrl}/Items?IncludeItemTypes=Movie&UserId=${userId}&Recursive=true&Filters=IsPlayed&Fields=UserData,ProviderIds&EnableImageTypes=Primary,Backdrop,Thumb&ImageTypeLimit=1&SortBy=DatePlayed&SortOrder=Descending`;
|
||||
|
||||
try {
|
||||
const res = await fetch(url, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } });
|
||||
const res = await fetch(url, { headers: { "Authorization": apiHelper.getAuthHeader() } });
|
||||
const data = await res.json();
|
||||
const movies = data.Items || [];
|
||||
|
||||
@@ -6033,7 +6033,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
try {
|
||||
LOG(`Fetching episodes from API for series: ${seriesId}`);
|
||||
const episodesUrl = `${serverUrl}/Shows/${seriesId}/Episodes?UserId=${userId}&Fields=UserData&EnableImageTypes=Primary`;
|
||||
const episodesRes = await fetch(episodesUrl, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } });
|
||||
const episodesRes = await fetch(episodesUrl, { headers: { "Authorization": apiHelper.getAuthHeader() } });
|
||||
const episodesData = await episodesRes.json();
|
||||
let episodes = episodesData.Items || [];
|
||||
|
||||
@@ -6203,7 +6203,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
const response = await fetch(markPlayedUrl, {
|
||||
method: isWatched ? 'POST' : 'DELETE',
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`,
|
||||
"Authorization": apiHelper.getAuthHeader(),
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
@@ -6328,7 +6328,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
const response = await fetch(markPlayedUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Authorization": `MediaBrowser Token="${token}"`,
|
||||
"Authorization": apiHelper.getAuthHeader(),
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
@@ -7124,7 +7124,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Emby-Token": ApiClient._serverInfo.AccessToken || ApiClient.accessToken(),
|
||||
"Authorization": apiHelper.getAuthHeader(),
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
@@ -7229,7 +7229,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Emby-Token": ApiClient._serverInfo.AccessToken || ApiClient.accessToken(),
|
||||
"Authorization": apiHelper.getAuthHeader(),
|
||||
},
|
||||
})
|
||||
.then((r) => r.json())
|
||||
@@ -7795,7 +7795,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
const token = apiClient.accessToken();
|
||||
|
||||
const url = `${serverUrl}/Items?IncludeItemTypes=Series&UserId=${userId}&Recursive=true&Fields=UserData,RecursiveItemCount`;
|
||||
const res = await fetch(url, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } });
|
||||
const res = await fetch(url, { headers: { "Authorization": apiHelper.getAuthHeader() } });
|
||||
const data = await res.json();
|
||||
const series = data.Items || [];
|
||||
|
||||
@@ -7823,7 +7823,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
const token = apiClient.accessToken();
|
||||
|
||||
fetch(`${serverUrl}/Items?IncludeItemTypes=Series&UserId=${userId}&Recursive=true&Fields=UserData,ChildCount,RecursiveItemCount`, {
|
||||
headers: { "Authorization": `MediaBrowser Token=\"${token}\"` }
|
||||
headers: { "Authorization": apiHelper.getAuthHeader() }
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
Reference in new issue
Block a user