Size
4.6 KB
Version
1.1.4
Created
Mar 3, 2026
Updated
18 days ago
1// ==UserScript==
2// @name TMDB to Simkl Button
3// @description Adds a button to navigate from TMDB to Simkl
4// @version 1.1.4
5// @match https://*.themoviedb.org/*
6// @icon https://www.themoviedb.org/assets/2/favicon-32x32-543a21832c8931d3494a68881f6afcafc58e96c5d324345377f3197a37b367b5.png
7// @grant GM.openInTab
8// @grant GM_openInTab
9// ==/UserScript==
10(function() {
11 'use strict';
12
13 function debounce(func, wait) {
14 let timeout;
15 return function executedFunction(...args) {
16 const later = () => {
17 clearTimeout(timeout);
18 func(...args);
19 };
20 clearTimeout(timeout);
21 timeout = setTimeout(later, wait);
22 };
23 }
24
25 function getMovieOrShowTitle() {
26 // Get the title from the h2 a element
27 const titleElement = document.querySelector('section.header.poster div.title h2 a');
28 if (titleElement) {
29 return titleElement.textContent.trim();
30 }
31 return null;
32 }
33
34 function addSimklButton() {
35 // Check if button already exists
36 if (document.getElementById('simkl-button')) {
37 return;
38 }
39
40 // Find the actions list where favorite, watchlist buttons are
41 const actionsList = document.querySelector('ul.auto.actions');
42 if (!actionsList) {
43 console.log('Actions list not found, will retry...');
44 return;
45 }
46
47 const title = getMovieOrShowTitle();
48 if (!title) {
49 console.log('Title not found, will retry...');
50 return;
51 }
52
53 // Create the button list item
54 const listItem = document.createElement('li');
55 listItem.className = 'tooltip use_tooltip';
56 listItem.setAttribute('title', 'Go to Simkl');
57 listItem.setAttribute('data-role', 'tooltip');
58 listItem.id = 'simkl-button';
59
60 // Create the link
61 const link = document.createElement('a');
62 link.href = '#';
63 link.className = 'simkl-link';
64 link.style.cssText = 'display: flex; align-items: center; justify-content: center;';
65
66 // Create the icon span with Simkl logo
67 const icon = document.createElement('img');
68 icon.src = 'https://cdn.jsdelivr.net/npm/simple-icons@v13/icons/simkl.svg';
69 icon.alt = 'Simkl';
70 icon.style.cssText = 'width: 24px; height: 24px; filter: brightness(0) invert(1);';
71
72 link.appendChild(icon);
73 listItem.appendChild(link);
74
75 // Add click handler
76 link.addEventListener('click', async (e) => {
77 e.preventDefault();
78
79 // Detect if it's a movie or TV show based on URL
80 const isMovie = window.location.href.includes('/movie/');
81 const isTVShow = window.location.href.includes('/tv/');
82
83 let searchUrl;
84 if (isMovie) {
85 searchUrl = `https://simkl.com/search/?type=movies&q=${encodeURIComponent(title)}`;
86 } else if (isTVShow) {
87 searchUrl = `https://simkl.com/search/?type=tv&q=${encodeURIComponent(title)}`;
88 } else {
89 // Fallback to general search
90 searchUrl = `https://simkl.com/search/?q=${encodeURIComponent(title)}`;
91 }
92
93 console.log('Opening Simkl URL:', searchUrl);
94 await GM.openInTab(searchUrl, false);
95 });
96
97 // Insert the button after the watchlist button
98 const watchlistButton = actionsList.querySelector('li a#watchlist');
99 if (watchlistButton && watchlistButton.parentElement) {
100 watchlistButton.parentElement.insertAdjacentElement('afterend', listItem);
101 console.log('Simkl button added successfully');
102 } else {
103 // Fallback: append to the end of the list
104 actionsList.appendChild(listItem);
105 console.log('Simkl button added to end of list');
106 }
107 }
108
109 function init() {
110 console.log('TMDB to Simkl Button extension loaded');
111
112 // Try to add button immediately
113 addSimklButton();
114
115 // Watch for DOM changes in case the page loads dynamically
116 const debouncedAddButton = debounce(addSimklButton, 1000);
117
118 const observer = new MutationObserver(debouncedAddButton);
119 observer.observe(document.body, {
120 childList: true,
121 subtree: true
122 });
123
124 // Also try again after a short delay
125 setTimeout(addSimklButton, 2000);
126 }
127
128 // Wait for body to be ready
129 if (document.body) {
130 init();
131 } else {
132 document.addEventListener('DOMContentLoaded', init);
133 }
134})();