Floatplane Always Captioned

Automatically check if a captioned version is available and switch to it if it is

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Floatplane Always Captioned
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Automatically check if a captioned version is available and switch to it if it is
// @license      GPL-v3
// @author       German
// @match        https://*.floatplane.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=floatplane.com
// @grant        none
// ==/UserScript==

(function () {
  'use strict';

  let apiRequestMade = false;

  function checkAndSwitchToCaptioned() {
    let url = new URL(window.location.href);

    if (url.pathname.includes('/post/')) {
      let post_id = url.pathname.split('/')[2];
      if (!post_id) return;

      if (apiRequestMade) return; // Prevent hammering API
      apiRequestMade = true;

      fetch(`${window.location.origin}/api/v3/content/post?id=${post_id}`)
        .then(response => response.json())
        .then(data => {
          if (!data) return;
          if (data.videoAttachments.length > 1) {
            let captioned = data.videoAttachments.find(attachment =>
              attachment.title.startsWith('Captioned')
            );
            if (captioned) {
              let attachmentList = document.querySelector('div[class*="attachmentList"]');
              if (attachmentList) {
                let attachments = attachmentList.querySelectorAll('div > div > div');
                for (let attachment of attachments) {
                  let titleDiv = attachment.querySelector('div[title]');
                  if (titleDiv && titleDiv.title.startsWith('Captioned')) {
                    let blackout = createBlackout();
                    setTimeout(() => {
                      attachment.firstChild.click();
                      hideBlockout(blackout);
                    }, 1000); // have to wait otherwise angular freaks out
                    break;
                  }
                }
              } else {
                console.log('Attachment list not found, retrying...');
                setTimeout(() => {
                  apiRequestMade = false;
                  checkAndSwitchToCaptioned();
                }, 1000);
              }
            }
          }
        })
        .catch(error => {
          console.error('API request failed:', error);
          apiRequestMade = false;
        });
    }
  }

  // Function to listen for URL changes
  function listenForUrlChanges() {
    let oldHref = document.location.href;

    window.addEventListener('popstate', function () {
      if (oldHref !== document.location.href) {
        oldHref = document.location.href;
        apiRequestMade = false;
        checkAndSwitchToCaptioned();
      }
    });

    // monkeypatch pushState and replaceState to detect changes
    const pushState = history.pushState;
    history.pushState = function () {
      const result = pushState.apply(this, arguments);
      window.dispatchEvent(new Event('popstate'));
      return result;
    };

    const replaceState = history.replaceState;
    history.replaceState = function () {
      const result = replaceState.apply(this, arguments);
      window.dispatchEvent(new Event('popstate'));
      return result;
    };
  }

  // Initial check in case the page is already loaded
  checkAndSwitchToCaptioned();

  // Start listening for URL changes
  listenForUrlChanges();

  // Cool blackout screen to let you know that it's switching
  function createBlackout() {
    let blackout = document.createElement('div');
    blackout.style.position = 'fixed';
    blackout.style.top = '0';
    blackout.style.left = '0';
    blackout.style.width = '100%';
    blackout.style.height = '100%';
    blackout.style.backgroundColor = 'black';
    blackout.style.zIndex = '9999';
    blackout.style.transition = 'all 0.2s';
    blackout.style.opacity = '0';
    blackout.innerHTML = `<h1 style="color: white; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-family: sans">Switching to captioned version...</h1>`;
    document.body.appendChild(blackout);
    setTimeout(() => {
      blackout.style.opacity = '1';
    }, 100);
    return blackout;
  }

  function hideBlockout(blackout) {
    blackout.style.opacity = '0';
    setTimeout(() => {
      blackout.remove();
    }, 200);
  }
})();