Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63be8214d0 | ||
|
|
99411afffd | ||
|
|
9510ae6ba7 | ||
|
|
2030538acc | ||
|
|
463e9ef424 | ||
|
|
dbe9ce97d2 | ||
|
|
45c780c018 | ||
|
|
9de268caa7 |
@@ -35,5 +35,7 @@ namespace Jellyfin.Plugin.MediaBarEnhanced.Configuration
|
||||
public bool EnableSeasonalContent { get; set; } = false;
|
||||
public bool IsEnabled { get; set; } = true;
|
||||
public bool EnableClientSideSettings { get; set; } = false;
|
||||
public string SortBy { get; set; } = "Random";
|
||||
public string SortOrder { get; set; } = "Ascending";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,6 +274,32 @@
|
||||
mobile).</div>
|
||||
</div>
|
||||
|
||||
<h2 class="sectionTitle">Content Sorting</h2>
|
||||
<div class="selectContainer">
|
||||
<label class="selectLabel" for="SortBy">Sort By</label>
|
||||
<select is="emby-select" id="SortBy" name="SortBy" class="emby-select-withcolor emby-select">
|
||||
<option value="Random">Random</option>
|
||||
<option value="Original">Original (Custom List Order)</option>
|
||||
<option value="PremiereDate">Premiere Date</option>
|
||||
<option value="DateCreated">Date Created</option>
|
||||
<option value="CommunityRating">Community Rating</option>
|
||||
<option value="Name">Name</option>
|
||||
<option value="Runtime">Runtime</option>
|
||||
</select>
|
||||
<div class="fieldDescription">Sort items by the selected criteria.</div>
|
||||
</div>
|
||||
<div class="selectContainer">
|
||||
<label class="selectLabel" for="SortOrder">Sort Order</label>
|
||||
<select is="emby-select" id="SortOrder" name="SortOrder" class="emby-select-withcolor emby-select">
|
||||
<option value="Ascending">Ascending</option>
|
||||
<option value="Descending">Descending</option>
|
||||
</select>
|
||||
<div class="fieldDescription">Sort items in Ascending or Descending order.</div>
|
||||
</div>
|
||||
<div class="fieldDescription" style="margin-bottom: 2em; color: #ffcc00;">
|
||||
<b>Note:</b> Sorting settings apply to both Server content and Custom IDs. 'Original' preserves Custom List order.
|
||||
</div>
|
||||
|
||||
<h2 class="sectionTitle">Content Limits</h2>
|
||||
<p>Leave a setting blank to use the default value.</p>
|
||||
<div class="inputContainer">
|
||||
@@ -370,7 +396,7 @@
|
||||
'WaitForTrailerToEnd', 'StartMuted', 'FullWidthVideo', 'EnableMobileVideo',
|
||||
'ShowTrailerButton', 'AlwaysShowArrows', 'EnableKeyboardControls',
|
||||
'EnableCustomMediaIds', 'CustomMediaIds', 'EnableLoadingScreen',
|
||||
'EnableSeasonalContent', 'EnableClientSideSettings'
|
||||
'EnableSeasonalContent', 'EnableClientSideSettings', 'SortBy', 'SortOrder'
|
||||
];
|
||||
|
||||
keys.forEach(function (key) {
|
||||
@@ -419,7 +445,7 @@
|
||||
'WaitForTrailerToEnd', 'StartMuted', 'FullWidthVideo', 'EnableMobileVideo',
|
||||
'ShowTrailerButton', 'AlwaysShowArrows', 'EnableKeyboardControls',
|
||||
'EnableCustomMediaIds', 'CustomMediaIds', 'EnableLoadingScreen',
|
||||
'EnableSeasonalContent', 'EnableClientSideSettings'
|
||||
'EnableSeasonalContent', 'EnableClientSideSettings', 'SortBy', 'SortOrder'
|
||||
];
|
||||
|
||||
keys.forEach(function (key) {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<!-- <TreatWarningsAsErrors>false</TreatWarningsAsErrors> -->
|
||||
<Title>Jellyfin Media Bar Enhanced Plugin</Title>
|
||||
<Authors>CodeDevMLH</Authors>
|
||||
<Version>1.5.0.3</Version>
|
||||
<Version>1.5.0.6</Version>
|
||||
<RepositoryUrl>https://github.com/CodeDevMLH/jellyfin-plugin-media-bar-enhanced</RepositoryUrl>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@ const CONFIG = {
|
||||
customMediaIds: "",
|
||||
enableLoadingScreen: true,
|
||||
enableClientSideSettings: false,
|
||||
sortBy: "Random",
|
||||
sortOrder: "Ascending",
|
||||
};
|
||||
|
||||
// State management
|
||||
@@ -460,6 +462,62 @@ waitForApiClientAndInitialize();
|
||||
* Utility functions for slide creation and management
|
||||
*/
|
||||
const SlideUtils = {
|
||||
/**
|
||||
* Sorts items based on configuration
|
||||
* @param {Array<Object>} items - Array of item objects
|
||||
* @param {string} sortBy - Sort criteria
|
||||
* @param {string} sortOrder - Sort order 'Ascending' or 'Descending'
|
||||
* @returns {Array<Object>} Sorted array of items
|
||||
*/
|
||||
sortItems(items, sortBy, sortOrder) {
|
||||
if (sortBy === 'Random' || sortBy === 'Original') {
|
||||
return items;
|
||||
}
|
||||
|
||||
const simpleCompare = (a, b) => {
|
||||
if (a < b) return -1;
|
||||
if (a > b) return 1;
|
||||
return 0;
|
||||
};
|
||||
|
||||
const sorted = [...items].sort((a, b) => {
|
||||
let valA, valB;
|
||||
|
||||
switch (sortBy) {
|
||||
case 'DateCreated':
|
||||
valA = new Date(a.DateCreated).getTime();
|
||||
valB = new Date(b.DateCreated).getTime();
|
||||
break;
|
||||
case 'PremiereDate':
|
||||
valA = new Date(a.PremiereDate).getTime();
|
||||
valB = new Date(b.PremiereDate).getTime();
|
||||
break;
|
||||
case 'CommunityRating':
|
||||
valA = a.CommunityRating || 0;
|
||||
valB = b.CommunityRating || 0;
|
||||
break;
|
||||
case 'Runtime':
|
||||
valA = a.RunTimeTicks || 0;
|
||||
valB = b.RunTimeTicks || 0;
|
||||
break;
|
||||
case 'Name':
|
||||
valA = (a.Name || '').toLowerCase();
|
||||
valB = (b.Name || '').toLowerCase();
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return simpleCompare(valA, valB);
|
||||
});
|
||||
|
||||
if (sortOrder === 'Descending') {
|
||||
sorted.reverse();
|
||||
}
|
||||
|
||||
return sorted;
|
||||
},
|
||||
|
||||
/**
|
||||
* Shuffles array elements randomly
|
||||
* @param {Array} array - Array to shuffle
|
||||
@@ -960,8 +1018,8 @@ const ApiUtils = {
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`${STATE.jellyfinData.serverAddress}/Items/${itemId}`,
|
||||
// `${STATE.jellyfinData.serverAddress}/Users/${STATE.jellyfinData.userId}/Items/${itemId}?Fields=Overview,RemoteTrailers,Genres,CommunityRating,CriticRating,OfficialRating,PremiereDate,RunTimeTicks,ProductionYear,MediaSources`,
|
||||
// `${STATE.jellyfinData.serverAddress}/Items/${itemId}`,
|
||||
`${STATE.jellyfinData.serverAddress}/Items/${itemId}?Fields=Overview,RemoteTrailers,Genres,CommunityRating,CriticRating,OfficialRating,PremiereDate,ProductionYear,MediaSources,RunTimeTicks`,
|
||||
{
|
||||
headers: this.getAuthHeaders(),
|
||||
}
|
||||
@@ -1033,8 +1091,16 @@ const ApiUtils = {
|
||||
|
||||
console.log("Fetching random items from server...");
|
||||
|
||||
let sortParams = `sortBy=${CONFIG.sortBy}`;
|
||||
|
||||
if (CONFIG.sortBy === 'Random' || CONFIG.sortBy === 'Original') {
|
||||
sortParams = 'sortBy=Random';
|
||||
} else {
|
||||
sortParams += `&sortOrder=${CONFIG.sortOrder}`;
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`${STATE.jellyfinData.serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&hasOverview=true&imageTypes=Logo,Backdrop&sortBy=Random&isPlayed=False&enableUserData=true&Limit=${CONFIG.maxItems}&fields=Id`,
|
||||
`${STATE.jellyfinData.serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&hasOverview=true&imageTypes=Logo,Backdrop&${sortParams}&isPlayed=False&enableUserData=true&Limit=${CONFIG.maxItems}&fields=Id`,
|
||||
{
|
||||
headers: this.getAuthHeaders(),
|
||||
}
|
||||
@@ -2560,30 +2626,6 @@ const SlideshowManager = {
|
||||
e.preventDefault();
|
||||
break;
|
||||
|
||||
// case "ArrowDown":
|
||||
// // Manually shift focus to the content below the slideshow
|
||||
// const contentBelow = document.querySelector('.homeSectionsContainer');
|
||||
// if (contentBelow) {
|
||||
// const focusable = contentBelow.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
||||
// if (focusable) {
|
||||
// focusable.focus();
|
||||
// e.preventDefault();
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
|
||||
// case "ArrowUp":
|
||||
// // Manually shift focus to the header (Search/User)
|
||||
// const header = document.querySelector('.skinHeader');
|
||||
// if (header) {
|
||||
// const focusable = header.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
||||
// if (focusable) {
|
||||
// focusable.focus();
|
||||
// e.preventDefault();
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
|
||||
case " ": // Space bar
|
||||
this.togglePause();
|
||||
e.preventDefault();
|
||||
@@ -2798,10 +2840,28 @@ const SlideshowManager = {
|
||||
if (itemIds.length === 0) {
|
||||
console.log("No custom list found, fetching random items from server...");
|
||||
itemIds = await ApiUtils.fetchItemIdsFromServer();
|
||||
|
||||
if (CONFIG.sortBy === 'Random') {
|
||||
itemIds = SlideUtils.shuffleArray(itemIds);
|
||||
}
|
||||
} else {
|
||||
// Custom IDs
|
||||
if (CONFIG.sortBy === 'Random') {
|
||||
itemIds = SlideUtils.shuffleArray(itemIds);
|
||||
} else if (CONFIG.sortBy !== 'Original') {
|
||||
// Client-side sort required...
|
||||
console.log(`Sorting ${itemIds.length} custom items by ${CONFIG.sortBy} ${CONFIG.sortOrder}`);
|
||||
const itemsWithDetails = [];
|
||||
for (const id of itemIds) {
|
||||
const item = await ApiUtils.fetchItemDetails(id);
|
||||
if (item) itemsWithDetails.push(item);
|
||||
}
|
||||
|
||||
const sortedItems = SlideUtils.sortItems(itemsWithDetails, CONFIG.sortBy, CONFIG.sortOrder);
|
||||
itemIds = sortedItems.map(i => i.Id);
|
||||
}
|
||||
}
|
||||
|
||||
itemIds = SlideUtils.shuffleArray(itemIds);
|
||||
|
||||
STATE.slideshow.itemIds = itemIds;
|
||||
STATE.slideshow.totalItems = itemIds.length;
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
"imageUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/raw/branch/main/logo.png",
|
||||
"versions": [
|
||||
{
|
||||
"version": "1.5.0.3",
|
||||
"changelog": "- fix: keyboard controls in TV mode \n- Update mediaBarEnhanced.js and mediaBarEnhanced.css with version 4.0.1 from original repo",
|
||||
"version": "1.5.0.6",
|
||||
"changelog": "- fix: keyboard controls in TV mode\n- Add sorting options for content in configuration\n- Update mediaBarEnhanced.js and mediaBarEnhanced.css with version 4.0.1 from original repo",
|
||||
"targetAbi": "10.11.0.0",
|
||||
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.5.0.3/Jellyfin.Plugin.MediaBarEnhanced.zip",
|
||||
"checksum": "f5454300163a4d30559d552ef7c4bbd0",
|
||||
"timestamp": "2026-02-08T00:41:44Z"
|
||||
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.5.0.6/Jellyfin.Plugin.MediaBarEnhanced.zip",
|
||||
"checksum": "c1c0736b06b3855523fe2eac25e6b34b",
|
||||
"timestamp": "2026-02-09T00:31:34Z"
|
||||
},
|
||||
{
|
||||
"version": "1.3.0.3",
|
||||
|
||||
Reference in New Issue
Block a user