Button to open todoist task in new tab from a task list latest version (currently v1.1.2)

← Back to User Scripts

Script Content

// ==UserScript==
// @name         Todoist: Open Task in New Tab
// @namespace    https://www.timhilton.xyz/user-scripts
// @version      1.1.2
// @description  Add a button to any todoist task list which will open the selected task in a new tab
// @author       Tim Hilton
// @match        https://app.todoist.com/app/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    const LOG_PREFIX = '[Todoist: Open Task in New Tab]';

    console.debug(`${LOG_PREFIX} Script initialized`);

    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            if (mutation.type === 'childList') {
                mutation.addedNodes.forEach((node) => {
                    if (node.nodeType === Node.ELEMENT_NODE && node.hasAttribute('data-item-index')) {
                        console.debug(`${LOG_PREFIX} Adding event listener`);
                        node.addEventListener('mouseenter', onHover);
                    }
                });
            }
        });
    });

    observer.observe(document.body, { childList: true, subtree: true });

    function onHover(event) {
        console.debug(`${LOG_PREFIX} Firing onHover`);

        const hoveredTask = event.currentTarget;
        const taskActions = hoveredTask.querySelector('.task_list_item__actions');
        if (taskActions) {
            console.debug(`${LOG_PREFIX} Task actions found`);
            const buttonAlreadyAdded = taskActions.querySelector('.tjhleeds-open-new-tab') !== null;

            if (buttonAlreadyAdded) {
                console.debug(`${LOG_PREFIX} Button already added`);
                return;
            }

            console.debug(`${LOG_PREFIX} Adding open in new tab button`);

            const taskId = getTaskId(hoveredTask);

            const newTabButton = buildLink(taskId);
            taskActions.appendChild(newTabButton);
            console.log(`${LOG_PREFIX} ✅ Button added to task ${taskId}`);
        } else {
            console.log(`${LOG_PREFIX} ❌ Task actions not found`);
        }
    }

    function getTaskId(hoveredTask) {
        const elementId = hoveredTask.children[0].children[0].id;

        const regexParts = elementId.match(/task-(.*)/);

        if (regexParts?.length > 1) {
            return regexParts[1];
        }

        throw new Error('Task ID could not be found');
    }

    function buildLink(taskId) {
        const taskUrl = `https://app.todoist.com/app/task/${taskId}`;

        const newTabLink = document.createElement('a');
        newTabLink.href = taskUrl;
        newTabLink.target = '_blank';
        newTabLink.innerHTML = getIconAsSvg();
        newTabLink.classList.add('tjhleeds-open-new-tab');

        return newTabLink;
    }

    function getIconAsSvg() {
        return `
        
            
            
        `;
    }

})();