Threads Custom Keyboard Navigation

Customize keyboard shortcuts for navigating Threads features

Από την 01/06/2024. Δείτε την τελευταία έκδοση.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey, το Greasemonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Userscripts για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

Θα χρειαστεί να εγκαταστήσετε μια επέκταση διαχείρισης κώδικα χρήστη για να εγκαταστήσετε αυτόν τον κώδικα.

(Έχω ήδη έναν διαχειριστή κώδικα χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Έχω ήδη έναν διαχειριστή στυλ χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

// ==UserScript==
// @name       Threads Custom Keyboard Navigation
// @name:zh-TW  Threads自訂鍵盤導航
// @name:ja     Threadsカスタムキーボードナビゲーション
// @name:en    Threads Custom Keyboard Navigation
// @namespace   https://github.com/Max46656
// @version     1.13
// @description Customize  keyboard shortcuts for navigating Threads features
// @description:zh-TW 自訂鍵盤快捷鍵以瀏覽Threads功能
// @description:ja Threads 機能をトリガーするためのカスタムキーボードショートカット
// @description:en Customize keyboard shortcuts for navigating Threads features
// @author      Max
// @match       https://www.threads.net/*
// @icon        https://www.google.com/s2/favicons?sz=64&domain=threads.net
// @grant       GM_registerMenuCommand
// @grant       GM_setValue
// @grant       GM_getValue
// @license     MPL2.0

// ==/UserScript==

class boardInputNavigation {
    constructor() {
        this.setEventListeners();
        this.boardButtons = '.xefz13k.x1lq5wgf.xgqcy7u.x30kzoy';
        this.backButton='.x1nhvcw1 .x1u6grsq .x1i10hfl';
        this.newPostButton = '.x1i10hfl.x1ypdohk.xdl72j9.x2lah0s.xe8uvvx.xdj266r.x11i5rnm.xat24cr.x1mh8g0r.x2lwn1j.xeuugli.xexx8yu.x4uap5.x18d9i69.xkhd6sd.x16tdsg8.x1hl2dhg.xggy1nq.x1t137rt.x1q0g3np.x87ps6o.x1lku1pv.x1a2a7pz.x6s0dn4.xz401s1.x6bh95i.x1re03b8.x1hvtcl2.x3ug3ww.xfh8nwu.xoqspk4.x12v9rci.x138vmkv.x13fuv20.xu3j5b3.x1q0q8m5.x26u7qi.xt8cgyo.xj515ic.x1co6499.x2j4hbs.xy58vm5.x1elh40u.x9f619.x78zum5.xrsfl73.x1gb2em4.xl56j7k.xixxii4.x12w9bfk.x13dflua.x11xpdln.x1pigqs1.x1vjfegm.xd3so5o.x1lcra6a';
    }

    setEventListeners() {
        this.keydownHandler = (event) => this.handleKeydown(event);
        self.addEventListener("keypress", this.keydownHandler);
        const boardKey = GM_getValue("boardKey", { Home: "F", Notifications: "D", Profile: "S", Search: "A", Create: "B", BacK:"G"});
        console.log("開始聆聽", boardKey);
    }

    handleKeydown(event) {
        const boardKey = GM_getValue("boardKey", { Home: "F", Notifications: "D", Profile: "S", Search: "A", Create: "B", BacK:"G"});
        const boardButtons = document.querySelectorAll(this.boardButtons);
        const newPostButton = document.querySelector(this.newPostButton);
        const backButton=document.querySelector(this.backButton);
        const keyMap = {
            Home: boardButtons[0],
            Notifications: boardButtons[2],
            Profile: boardButtons[3],
            Search: boardButtons[1],
            Create: newPostButton,
            Back:backButton,
        };

        for (const [key, element] of Object.entries(boardKey)) {
            if (event.key.toUpperCase() === element.toUpperCase()) {
                console.log(key.toLowerCase());
                keyMap[key].click();
                break;
            }
        }
    }
}

class inputCustomMenu{
    constructor() {
        this.registerMenuCommands(this);
        this.loadBoardKey();
    }

    async customizeKey(buttonType) {
        const currentKey = this.boardKey[buttonType];
        const newKey = prompt(`${this.getFeatureMessageLocalization(`EnterNew${buttonType}Letter`)}${currentKey}`);

        if (newKey && newKey.length === 1) {
            this.boardKey[buttonType] = newKey;
            this.saveBoardKey();
        } else {
            alert(this.getFeatureMessageLocalization("CustomKeyError"));
        }
    }

    loadBoardKey() {
        this.boardKey = GM_getValue("boardKey", { Home: "F", Notifications: "D", Profile: "S", Search: "A", Create: "B", BacK:"G"});
        console.log(this.boardKey);
    }

    saveBoardKey() {
        GM_setValue("boardKey", this.boardKey);
    }

    getFeatureMessageLocalization(word) {
        let display = {
            "zh-TW": {
                "CustomizeHome": "自訂首頁按鍵",
                "CustomizeNotifications": "自訂通知按鍵",
                "CustomizeProfile": "自訂個人簡介按鍵",
                "CustomizeSearch": "自訂搜尋按鍵",
                "CustomizeCreate": "自訂新貼文按鍵",
                "CustomizeBack": "自訂返回按鍵",
                "EnterNewHomeLetter": "請輸入要替換首頁按鈕的一個英文字母或數字,目前為:",
                "EnterNewNotificationsLetter": "請輸入要替換通知按鈕的一個英文字母或數字,目前為:",
                "EnterNewProfileLetter": "請輸入要替換個人簡介按鈕的一個英文字母或數字,目前為:",
                "EnterNewSearchLetter": "請輸入要替換搜尋按鈕的一個英文字母或數字,目前為:",
                "EnterNewCreateLetter": "請輸入要替換新貼文按鈕的一個英文字母或數字,目前為:",
                "EnterNewBackLetter": "請輸入要替換返回按鈕的一個英文字母或數字,目前為:",
                "CustomKeyError": "自訂按鍵錯誤,請輸入一個英文字母或數字。",
            },
            "en": {
                "CustomizeHome": "Customize home button",
                "CustomizeNotifications": "Customize notification buttons",
                "CustomizeProfile": "Customize profile button",
                "CustomizeSearch": "Customize search button",
                "CustomizeCreate": "Customize the new post button",
                "EnterNewHomeLetter": "Please enter an English letter or number to replace the home button. Currently:",
                "EnterNewNotificationsLetter": "Please enter an English letter or number to replace the notification button, currently:",
                "EnterNewProfileLetter": "Please enter an English letter or number to replace the profile button. Currently:",
                "EnterNewSearchLetter": "Please enter an English letter or number to replace the search button. Currently:",
                "EnterNewCreateLetter": "Please enter an English letter or number to replace the new post button. Currently:",
                "EnterNewBackLetter": "Please enter a letter or number to be replaced back button, currently:",
                "CustomKeyError": "Custom key error, please enter an English letter or number.",
            },
            "ja": {
                "CustomizeHome": "ホームボタンをカスタマイズ",
                "CustomizeNotifications": "通知ボタンをカスタマイズする",
                "CustomizeProfile": "プロファイル ボタンをカスタマイズ",
                "CustomizeSearch": "検索ボタンをカスタマイズ",
                "CustomizeCreate": "新規投稿ボタンをカスタマイズします",
                "EnterNewHomeLetter": "ホーム ボタンを置き換える英語の文字または數字を入力してください。現在:",
                "EnterNewNotificationsLetter": "通知ボタンを置き換える英語の文字または數字を入力してください。現在:",
                "EnterNewProfileLetter": "プロフィール ボタンを置き換える英語の文字または數字を入力してください。現在:",
                "EnterNewSearchLetter": "検索ボタンを置き換える英語の文字または數字を入力してください。現在:",
                "EnterNewCreateLetter": "新しい投稿ボタンを置き換えるには、英語の文字または數字を入力してください。現在:",
                "EnterNewBackLetter": "戻るボタンを置き換える英語の文字または數字を入力してください。現在:",
                "CustomKeyError": "カスタム キー エラーです。英語の文字または數字を入力してください。",
            }
        };
        return display[navigator.language][word];
    }

    registerMenuCommands(instance) {
        const buttonTypes = ["Home", "Notifications", "Profile", "Search", "Create","Back"];
        buttonTypes.forEach(type => {
            GM_registerMenuCommand(instance.getFeatureMessageLocalization(`Customize${type}`), () => instance.customizeKey(type));
        });
    }
}

const johnTheAlmondHolder = new boardInputNavigation();
const johnTheRestaurantWaiter = new inputCustomMenu();