2025-03-15, 02:54 PM
I added some more keyboard shortcuts to edit images, because click path takes so long for modals to animate. Just throw the code into client.
Usage
CTRL+e (e for edit and unused)
1. Dashboard (hovered element) - Next up/recently added episode will open selection for the primary episode image. Movie will open the image selection for primary image
2. List (hovered element) - will open the image selection for currently used image type (primary/thumb/logo or (clear)Art) - I know I patched art and also removed banner in my client
3. Search (hovered element) - will open the image selection for primary image
4. Detail view - opens primary image OR the hovered resource. e.g. current movie or episode, but if next up is hovered, it will open that instead
CTRL+3 (near e-key and unused)
Opens only overview for the images and not the selection
s
Go to search
h
Go to hone/dashboard
FAQ
Code looks complicated! Why?!
Over time, I wanted more and more features with same combo and I used a browser add-on, that had a code box per shortcut.
⇉ You Should use a switch-case! ⇒ "Fork" it and maintain it. Please post the plugin or PR below - thx
Why not integrate it into jellyfin-web?
I know there is a shortcut functionality (used it before), but the jellyfin code base separates between devices types and shortcuts. I used a keyboard on Tablet, TV or Desktop. Easiest way was to just trigger/emulate the click path for my desired functionality. GitHub issues around shortcuts are stale, and I guess everybody wants something else (mapping and functions...). This can easily be adjusted for own needs e.g. add a metadata edit shortcut.
Known issues
- Clicks to fast and loading animation will be removed form finishing modal before - I DO NOT CARE (not a big fan of layering modals in a UI)
- s for search will also search for s (new - suppression of input was handled by browser add-on, before I moved to a script)
---
I shared this, because I found some useful stuff in forum and metadata manager has no image maintenance.
Code:
// History of this ugly code - used with https://github.com/crittermike/shortkeys (split in per shortcut code, no shared functions). Moved it to a script, so i can use it in JMP.
function clickElement(selector) {
// Do not use it while using an input like search
const activeElement = document.activeElement;
if (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA") {
return;
}
return new Promise((resolve) => {
const element = document.querySelector(selector);
if (element) {
element.click();
resolve();
} else {
reject();
}
});
}
// Loading and animation takes a moment for a element to match selector
function clickElementRetry(selector) {
return new Promise((resolve) => {
const interval = setInterval(() => {
const element = document.querySelector(selector);
if (element) {
element.click();
clearInterval(interval);
resolve();
}
}, 100);
});
}
// Loading and animation takes a moment for a element to match selector - edit hovered image type
function clickElementRetryImageType(selector, imageType) {
return new Promise((resolve) => {
const interval = setInterval(() => {
const element = document.querySelector(selector);
if (element) {
element.setAttribute("data-imagetype", imageType);
element.click();
clearInterval(interval);
resolve();
}
}, 100);
});
}
function triggerRightClick(selector) {
return new Promise((resolve) => {
const element = document.querySelector(selector);
if (element) {
const event = new MouseEvent("contextmenu", {
bubbles: true,
cancelable: true,
view: window,
});
element.dispatchEvent(event);
resolve();
} else {
reject();
}
});
}
function extractTagValue(url) {
const urlParams = new URLSearchParams(url.split("?")[1]);
return urlParams.get("tag");
}
function getType() {
const possibleTags = ["Logo", "Thumb", "Primary", "Art"];
let imageWithTag;
for (let tag of possibleTags) {
imageWithTag = document.querySelector(
`.card-withuserdata .cardImageContainer.coveredImage img[src*="/Images/${tag}?"]`
);
if (imageWithTag) {
return tag;
}
}
return "Primary";
}
document.addEventListener("keydown", function (event) {
if (event.ctrlKey && event.key === "e") {
event.preventDefault();
if (
document.querySelector(
".card-hoverable:hover, .detailPageContent div.listItem:hover"
)
) {
triggerRightClick(
".card-hoverable:hover, .detailPageContent div.listItem:hover"
).then(() => {
let imageType = getType();
clickElementRetry('[data-id="editimages"]').then(() => {
clickElementRetryImageType(".btnBrowseAllImages", imageType);
});
});
} else {
clickElement(
'#itemDetailPage:not(.hide) .detailRibbon [title="More"]'
).then(() => {
clickElementRetry('[data-id="editimages"]').then(() => {
clickElementRetry(".btnBrowseAllImages");
});
});
}
}
if (event.ctrlKey && event.key === "3") {
if (document.querySelector(".card-hoverable:hover")) {
triggerRightClick(".card-hoverable:hover").then(() => {
clickElementRetry('[data-id="editimages"]');
});
} else {
clickElement(
'#itemDetailPage:not(.hide) .detailRibbon [title="More"]'
).then(() => {
clickElementRetry('[data-id="editimages"]');
});
}
}
if (event.key === "s") {
clickElement('[href="#/search.html"]');
}
if (event.key === "h") {
clickElement('[href="#/"]');
}
});
Usage
Quote:
CTRL+e (e for edit and unused)
1. Dashboard (hovered element) - Next up/recently added episode will open selection for the primary episode image. Movie will open the image selection for primary image
2. List (hovered element) - will open the image selection for currently used image type (primary/thumb/logo or (clear)Art) - I know I patched art and also removed banner in my client
3. Search (hovered element) - will open the image selection for primary image
4. Detail view - opens primary image OR the hovered resource. e.g. current movie or episode, but if next up is hovered, it will open that instead
CTRL+3 (near e-key and unused)
Opens only overview for the images and not the selection
s
Go to search
h
Go to hone/dashboard
FAQ
Code looks complicated! Why?!
Over time, I wanted more and more features with same combo and I used a browser add-on, that had a code box per shortcut.
⇉ You Should use a switch-case! ⇒ "Fork" it and maintain it. Please post the plugin or PR below - thx

Why not integrate it into jellyfin-web?
I know there is a shortcut functionality (used it before), but the jellyfin code base separates between devices types and shortcuts. I used a keyboard on Tablet, TV or Desktop. Easiest way was to just trigger/emulate the click path for my desired functionality. GitHub issues around shortcuts are stale, and I guess everybody wants something else (mapping and functions...). This can easily be adjusted for own needs e.g. add a metadata edit shortcut.
Known issues
- Clicks to fast and loading animation will be removed form finishing modal before - I DO NOT CARE (not a big fan of layering modals in a UI)
- s for search will also search for s (new - suppression of input was handled by browser add-on, before I moved to a script)
---
I shared this, because I found some useful stuff in forum and metadata manager has no image maintenance.