TMDB to Simkl Button

Adds a button to navigate from TMDB to Simkl

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})();