Skip to content

Instantly share code, notes, and snippets.

@bugmancx
Created March 20, 2024 20:21
Show Gist options
  • Save bugmancx/04a132c9f6b59babb4f630f55f7ab008 to your computer and use it in GitHub Desktop.
Save bugmancx/04a132c9f6b59babb4f630f55f7ab008 to your computer and use it in GitHub Desktop.
TitleCardMaker UI UserScripts
// ==UserScript==
// @name TCM: Automatically display if blueprints are available on Blueprints tab
// @version 1.0
// @description Check for available blueprints, and if so, update the counter on the tab
// @author bugmancx
// @match https://titlecardmaker:4242/series/*
// ==/UserScript==
(function() {
'use strict';
// Function to query blueprints and update tab count
function updateBlueprintsTabCount() {
// Run queryBlueprints() function
queryBlueprints();
// Wait for a brief moment before counting blueprints
setTimeout(function() {
// Get count of blueprints returned
var blueprintCount = document.querySelectorAll('#blueprint-cards .card').length;
// Update Blueprints tab text with count
var blueprintsTab = document.querySelector('[data-tab="blueprints"]');
if (blueprintsTab) {
var originalText = blueprintsTab.textContent.trim();
var newText = originalText + ' (' + blueprintCount + ')';
blueprintsTab.textContent = newText;
}
}, 1000); // Adjust delay as needed
}
// Call function to update Blueprints tab count
updateBlueprintsTabCount();
})();
// ==UserScript==
// @name TCM: Expand Cards on Files tab
// @version 1.0
// @description Always Expand cards on the Files tab.
// @author bugmancx
// @match http://titlecardmaker:4242/series/*
// ==/UserScript==
(function() {
'use strict';
// Only proceed if the URL hash matches '#files'
if (window.location.hash !== '#files') {
return;
}
// Function to force expand the 'View Images' section
function forceExpandViewImages() {
const contentDiv = document.querySelector('.ui.styled.fluid.accordion.inverted .content');
if (contentDiv && !contentDiv.classList.contains('active')) {
contentDiv.classList.add('active'); // Add 'active' class if not present
contentDiv.style.display = 'block !important'; // Ensure it's always displayed
// Ensure the images and pagination are visible
const imagesDiv = contentDiv.querySelector('#card-previews');
const paginationDiv = contentDiv.querySelector('#card-pagination');
if (imagesDiv) {
imagesDiv.classList.add('visible');
imagesDiv.style.display = 'block !important';
}
if (paginationDiv) {
paginationDiv.classList.add('visible');
paginationDiv.style.display = 'inline-flex !important';
}
}
}
// MutationObserver to handle dynamic content loading
const observer = new MutationObserver((mutations, obs) => {
forceExpandViewImages();
});
observer.observe(document.body, {
childList: true,
subtree: true
});
// Initial attempt in case the section is already loaded
forceExpandViewImages();
})();
// ==UserScript==
// @name TCM: Inject S01E01 preview card into main series display
// @version 1.0
// @description Dynamically injects an episode card preview above the series poster on TitleCardMaker WebUI, prioritizing non-Season 0 episodes.
// @author bugmancx
// @match http://titlecardmaker:4242/series/*
// ==/UserScript==
(function() {
'use strict';
const previewMarginBottom = '20px'; // Adjust the margin below the preview
function getSeriesIdFromUrl() {
const urlPattern = /\/series\/(\d+)/;
const matches = window.location.href.match(urlPattern);
return matches ? matches[1] : null;
}
function fetchEpisodePreviewImageUrl(seriesId, callback) {
fetch(`/api/cards/series/${seriesId}?page=1&size=50`)
.then(response => response.json())
.then(data => {
if (data && data.items && data.items.length > 0) {
// Correctly filter out Season 0 episodes
const validEpisodes = data.items.filter(item => item.episode.season_number > 0);
let selectedEpisode;
// Check if there's at least one valid episode to use
if (validEpisodes.length > 0) {
// Attempt to find the first episode of the first season
selectedEpisode = validEpisodes.find(item => item.episode.season_number === 1 && item.episode.episode_number === 1);
// If no S01E01 episode is found, use the first valid episode
selectedEpisode = selectedEpisode || validEpisodes[0];
} else {
// If all episodes are from Season 0, just use the very first episode from the original list
selectedEpisode = data.items[0];
}
if (selectedEpisode) {
const imageUrl = selectedEpisode.file_url; // Use relative URL
callback(imageUrl);
} else {
console.error('No appropriate episode preview image found.');
}
} else {
console.error('No episode preview images found.');
}
})
.catch(() => {
console.error('Failed to fetch episode preview images.');
});
}
function createEpisodePreview(imageUrl) {
const previewDiv = document.createElement('div');
previewDiv.id = 'episode-preview';
previewDiv.style.marginBottom = previewMarginBottom;
previewDiv.innerHTML = `<div class="ui card">
<div class="image">
<img src="${imageUrl}" alt="Title Card Preview">
</div>
<div class="content">
<div class="header">Title Card Preview</div>
</div>
</div>`;
return previewDiv;
}
function insertEpisodePreviewAbovePoster(imageUrl) {
const posterDiv = document.getElementById('poster');
if (posterDiv) {
const episodePreview = createEpisodePreview(imageUrl);
posterDiv.parentNode.insertBefore(episodePreview, posterDiv);
} else {
console.error('Poster div not found!');
}
}
const seriesId = getSeriesIdFromUrl();
if (seriesId) {
fetchEpisodePreviewImageUrl(seriesId, imageUrl => {
insertEpisodePreviewAbovePoster(imageUrl);
});
} else {
console.error('Series ID could not be determined from the URL.');
}
})();
// ==UserScript==
// @name TCM: Forward-back series with square brackets
// @version 1.0
// @description Press "[" to go to the previous series entry and "]" to go to the next series entry on titlecardmaker.
// @author bugmancx
// @match http://titlecardmaker:4242/series/*
// ==/UserScript==
(function() {
'use strict';
document.addEventListener('keydown', function(event) {
if (event.key === '[') {
const previousSeriesLink = document.querySelector('i[data-action="previous-series"]');
if (previousSeriesLink) {
previousSeriesLink.click();
}
} else if (event.key === ']') {
const nextSeriesLink = document.querySelector('i[data-action="next-series"]');
if (nextSeriesLink) {
nextSeriesLink.click();
}
}
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment