Feedly : get back Keep Unread button

Get back the Keep Unread button visible when reading an article in Feedly.

  1. // ==UserScript==
  2. // @name Feedly : get back Keep Unread button
  3. // @namespace JML
  4. // @version 1
  5. // @grant none
  6. // @include https://feedly.com/*
  7. // @license MIT
  8. // @description Get back the Keep Unread button visible when reading an article in Feedly.
  9. // ==/UserScript==
  10.  
  11. function simulateKey(letter) {
  12. // Use the currently active element or body
  13. const el = document.activeElement || document.body;
  14. // Get the code for the letter
  15. const code = 'Key' + letter.toUpperCase();
  16. // Get the keyCode (ASCII code)
  17. const keyCode = letter.charCodeAt(0);
  18. // Trigger keydown event
  19. el.dispatchEvent(new KeyboardEvent('keydown', {
  20. key: letter,
  21. code: code,
  22. keyCode: keyCode,
  23. bubbles: true
  24. }));
  25. // Trigger keyup event
  26. el.dispatchEvent(new KeyboardEvent('keyup', {
  27. key: letter,
  28. code: code,
  29. keyCode: keyCode,
  30. bubbles: true
  31. }));
  32. }
  33.  
  34. (function() {
  35. 'use strict';
  36. function modifyButtonBar() {
  37. console.log("🔍 Attempting to modify the button bar...");
  38. // Check if the button already exists
  39. if (document.querySelector('.keep-unread-button')) {
  40. console.log("✅ Button already exists.");
  41. return; // If the button already exists, don't create it again.
  42. }
  43. const buttonBar = document.querySelector('.ShareBar__wrapper');
  44. if (buttonBar) {
  45. console.log("✅ Button bar found");
  46. // get the "..." menu
  47. const bMoreServices = document.querySelector('button[title="More services"]');
  48. if (!bMoreServices) {
  49. console.log("❌ More services not found!");
  50. return;
  51. }
  52. // Create Keep Unread button:
  53. const bKeepUnread = document.createElement('button');
  54. bKeepUnread.addEventListener('click', function() {
  55. simulateKey("m");
  56. });
  57. bKeepUnread.classList.add('keep-unread-button'); // Add a class to avoid recreating it
  58. bKeepUnread.innerHTML = `
  59. <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="icon__B4xp9 icon color--secondary__WX5GF">
  60. <g fill="currentColor" fill-rule="nonzero">
  61. <path d="M15.429 8.5a6.071 6.071 0 0 1 .227 12.139l-.227.004h-4.286a.5.5 0 0 1-.09-.992l.09-.008h4.286a5.071 5.071 0 0 0 .22-10.138l-.22-.005H2.57a.5.5 0 0 1-.09-.992l.09-.008z"></path>
  62. <path d="M6.504 4.358a.5.5 0 0 1 .765.638l-.058.07-3.933 3.93 3.933 3.934a.5.5 0 0 1 .058.637l-.058.07a.5.5 0 0 1-.638.058l-.07-.058L2.219 9.35a.5.5 0 0 1-.058-.638l.058-.07z"></path>
  63. </g>
  64. </svg>
  65. Keep Unread`;
  66. // Add classes css from "..." menu
  67. bKeepUnread.classList.add(...bMoreServices.classList);
  68. // Add the button to the bar
  69. //buttonBar.appendChild(bKeepUnread);
  70. buttonBar.insertBefore(bKeepUnread, buttonBar.firstChild);
  71. }
  72. }
  73. // Execute the function after the page has loaded
  74. window.addEventListener('load', modifyButtonBar);
  75. // Observe changes in the DOM in case new elements are added dynamically
  76. const observer = new MutationObserver(modifyButtonBar);
  77. observer.observe(document.body, { childList: true, subtree: true });
  78. })();