Persistent Invidious Settings

Makes Invidious settings persist across instances and in private browsing.

当前为 2023-04-23 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Persistent Invidious Settings
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.10
  5. // @description Makes Invidious settings persist across instances and in private browsing.
  6. // @author Veeno
  7. // @license GPLv3
  8. // @resource instances https://api.invidious.io/instances.json
  9. // @match https://*/*
  10. // @icon https://invidious.io/invidious-colored-vector.svg
  11. // @run-at document-start
  12. // @grant GM_getResourceText
  13. // @grant GM_getValue
  14. // @grant GM_setValue
  15. // ==/UserScript==
  16.  
  17. /* jshint esversion: 11 */
  18.  
  19. (() => {
  20. 'use strict';
  21.  
  22. if(window.self !== window.top) return;
  23.  
  24. const domain = location.hostname;
  25.  
  26. const domainUpToDate = (() => {
  27. const storedDomainUpToDate = GM_getValue("Invidious_DomainUpToDate", {});
  28. try{
  29. return Object.fromEntries(
  30. JSON.parse(GM_getResourceText("instances"))
  31. .filter(instance => instance[1].type === "https")
  32. .map(instance => [instance[0], storedDomainUpToDate[instance[0]] || false])
  33. );
  34. }
  35. catch(e){
  36. return {};
  37. }
  38. })();
  39.  
  40. if(!Object.hasOwn(domainUpToDate, domain)) return;
  41.  
  42. function validateCurrentDomain(){
  43. domainUpToDate[domain] = true;
  44. GM_setValue("Invidious_DomainUpToDate", domainUpToDate);
  45. }
  46.  
  47. function invalidateOtherDomains(){
  48. Object.keys(domainUpToDate).forEach(key => { domainUpToDate[key] = false; });
  49. validateCurrentDomain();
  50. }
  51.  
  52. const storedSettings = GM_getValue(
  53. "Invidious_Settings",
  54. encodeURIComponent(JSON.stringify({
  55. annotations: false,
  56. annotations_subscribed: false,
  57. autoplay: true,
  58. automatic_instance_redirect: false,
  59. captions: ["", "", ""],
  60. comments: ["youtube", ""],
  61. continue: false,
  62. continue_autoplay: true,
  63. dark_mode: "",
  64. latest_only: false,
  65. listen: false,
  66. local: false,
  67. watch_history: false,
  68. vr_mode: true,
  69. show_nick: false,
  70. locale: "en-US",
  71. region: "US",
  72. max_results: 40,
  73. notifications_only: false,
  74. player_style: "invidious",
  75. quality: "hd720",
  76. quality_dash: "auto",
  77. default_home: "Popular",
  78. feed_menu: ["Popular", "Trending"],
  79. related_videos: true,
  80. sort: "published",
  81. speed: 1,
  82. thin_mode: false,
  83. unseen_only: false,
  84. video_loop: false,
  85. extend_desc: false,
  86. volume: 100,
  87. save_player_pos: false
  88. }))
  89. );
  90.  
  91. const cookieSettings = document.cookie
  92. .split("; ")
  93. .find(entry => entry.startsWith("PREFS="))
  94. ?.slice(6);
  95.  
  96. if(cookieSettings && domainUpToDate[domain]){
  97. if(cookieSettings !== storedSettings){
  98. GM_setValue("Invidious_Settings", cookieSettings);
  99. invalidateOtherDomains();
  100. }
  101. } else{
  102. const date = new Date();
  103. date.setFullYear(date.getFullYear() + 2);
  104. document.cookie = "PREFS=" + storedSettings + "; domain=" + domain + "; path=/; expires=" + date.toGMTString() + "; Secure; SameSite=Lax";
  105. validateCurrentDomain();
  106. location.reload();
  107. }
  108. })();