2024-10-28, 08:02 PM
Some example functions. Note: for a lot of media manipulation you will want to generate an api code in jellyfin Admin settings, thenm hardcode it into your injections to make api calls.
Code:
// Get the current authenticated user's info
const getCurrentUser = () => {
return fetch('/Users/Me', {
method: 'GET',
headers: {
'Authorization': `MediaBrowser Token="${ApiClient.accessToken()}"`,
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.catch(error => {
console.error('Error getting current user:', error);
return null;
});
};
// Get a user's profile image URL by their ID
const getUserImageUrl = (userId) => {
return `${ApiClient.serverAddress()}/Users/${userId}/Images/Primary?quality=90`;
};
// Update a media item's tags
const updateMediaTags = (itemId, newTags) => {
return ApiClient.getItem(ApiClient.getCurrentUserId(), itemId)
.then(item => {
const updatedTags = [...new Set([...item.Tags, ...newTags])];
return ApiClient.updateItem({
Id: itemId,
Tags: updatedTags
});
})
.catch(error => {
console.error('Error updating tags:', error);
return false;
});
};
// Watch for navigation changes in Jellyfin's SPA
const watchNavigation = (callback) => {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList' &&
mutation.target.classList.contains('view')) {
callback(window.location.hash);
}
});
});
observer.observe(document.querySelector('div[data-role="content"]'), {
childList: true,
subtree: true
});
return observer;
};
// Inject a custom element into a specific page section
const injectElement = (targetSelector, htmlContent, position = 'beforeend') => {
const target = document.querySelector(targetSelector);
if (target) {
target.insertAdjacentHTML(position, htmlContent);
return true;
}
return false;
};
// Get all users and their online status
const getOnlineUsers = () => {
return fetch('/Users/Query', {
method: 'GET',
headers: {
'Authorization': `MediaBrowser Token="${ApiClient.accessToken()}"`,
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(users => {
return ApiClient.getSessions()
.then(sessions => {
return users.map(user => ({
...user,
isOnline: sessions.some(session => session.UserId === user.Id)
}));
});
})
.catch(error => {
console.error('Error getting online users:', error);
return [];
});
};
// Add a custom button to the media details page
const addCustomButton = (text, onClick) => {
const buttonHtml = `
<button is="emby-button"
type="button"
class="button-flat btnPlay button-flat-custom raised">
<span>${text}</span>
</button>
`;
injectElement('.detailButtons', buttonHtml);
const button = document.querySelector('.button-flat-custom');
if (button) {
button.addEventListener('click', onClick);
}
};
// Watch for theme changes and apply custom styles
const watchThemeChanges = (callback) => {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.attributeName === 'data-theme') {
const theme = document.documentElement.getAttribute('data-theme');
callback(theme);
}
});
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['data-theme']
});
return observer;
};
// Example usage of the functions:
/*
// Watch for navigation changes
const navObserver = watchNavigation((newPath) => {
console.log('Navigation changed to:', newPath);
if (newPath.includes('details')) {
addCustomButton('My Custom Action', () => {
console.log('Custom button clicked!');
});
}
});
// Watch for theme changes
const themeObserver = watchThemeChanges((newTheme) => {
console.log('Theme changed to:', newTheme);
// Apply custom styles based on theme
});
// Get current user and update UI
async function updateUserInfo() {
const user = await getCurrentUser();
if (user) {
const userImage = getUserImageUrl(user.Id);
console.log('Current user:', user.Name);
console.log('User image:', userImage);
}
}
// Update media tags
async function addTagToMedia(itemId, newTag) {
const success = await updateMediaTags(itemId, [newTag]);
if (success) {
console.log('Tags updated successfully');
}
}
// Check online users
async function showOnlineUsers() {
const users = await getOnlineUsers();
users.forEach(user => {
console.log(`${user.Name} is ${user.isOnline ? 'online' : 'offline'}`);
});
}
*/