Volafile Mark Read

Adds a line to Volafile chat showing the line last read, along with a menu to show a list of file URLs for use with downloaders.

  1. // ==UserScript==
  2. // @name Volafile Mark Read
  3. // @author Arnold François Lecherche and a Vola anon named Adonis
  4. // @namespace greasyfork.org
  5. // @icon https://volafile.org/favicon.ico
  6. // @version 1.07
  7. // @description Adds a line to Volafile chat showing the line last read, along with a menu to show a list of file URLs for use with downloaders.
  8. // @include http://volafile.org/*
  9. // @include http://*.volafile.org/*
  10. // @include https://volafile.org/*
  11. // @include https://*.volafile.org/*
  12. // @grant none
  13. // @run-at document-end
  14. // @copyright 2020 Arnold François Lecherche
  15. // ==/UserScript==
  16. (function (w, d, b) {
  17. 'use strict';
  18. var pr = [w.prog0 || d.createElement('div'), w.prog1 || d.createElement('div')],
  19. menu = w.menu || d.createElement('div'),
  20. f = d.querySelector('#files_header_row'),
  21. u = d.getElementById('dolos_cuckmenu'),
  22. n = ['chat_message', 'filelist_file'],
  23. p = /^(?:MOTD|News|System|Script)/i,
  24. i = pr.length, g, m, c, s, k;
  25. function init() {
  26. g = w.config;
  27. g.bump = w.setInterval(refreshConfig, 60000);
  28. if (g.chat_max_history < 1000) g.chat_max_history = 1000;
  29. while (i--) {
  30. s = pr[i].style;
  31. pr[i].className = n[i];
  32. pr[i].id = 'prog' + i;
  33. s.borderTop = '3px dashed #f88';
  34. s.height = '2px';
  35. s.overflow = 'hidden';
  36. s.color = 'rgba(67,94,120,0)';
  37. pr[i].innerText = 'qwerty';
  38. b.appendChild(pr[i]);
  39. }
  40. w.chat_scroller.style.borderTop = '3px dotted #597895';
  41. g.title_append = g.title_append.replace(' - Volafile.org Live Filesharing & Chat', '');
  42. m = w.chat_messages;
  43. c = w.RoomInstance.extensions.chat;
  44. menu.id = 'menu';
  45. menu.style.display = 'inline-block';
  46. menu.innerHTML = '<a href="#" style="border-right:1px solid #597895;padding:0 1em;font-size:10px">File list</a>';
  47. f.insertBefore(menu, f.firstChild);
  48. menu.firstChild.addEventListener('click', flist, false);
  49. w.addEventListener('keydown', reloadMarker, false);
  50. c.showMessage('Script', 'Vola marker line loaded. Hit [esc] to activate.', {dontsave: true, staff: true});
  51. }
  52. function killnews(m) {
  53. var msg = c[m], i = msg.length;
  54. while (i--) if (msg[i].options.staff && p.test(msg[i].nick)) {
  55. if (msg[i].elem.parentNode) msg[i].elem.parentNode.removeChild(msg[i].elem);
  56. msg.splice(i, 1);
  57. }
  58. }
  59. function reloadMarker(e) {
  60. var key = e.key || e.charCode || e.keyCode, k;
  61. if (!key) return;
  62. if (key === 'Escape' || key === 'Esc' || key === 27) {
  63. if (g.chat_max_history < 1000) g.chat_max_history = 1000;
  64. m.appendChild(w.prog0);
  65. w.file_list.insertBefore(w.prog1, w.file_list.querySelector('#file_list .filelist_file:not(.file_uploading):not(.file_queued)'));
  66. killnews('messages');
  67. d.querySelector('.icon-arrow-down').style.display = 'none';
  68. k = d.querySelector('#kill_flist');
  69. if (k) k.click();
  70. }
  71. }
  72. function refreshConfig() {
  73. var pin = d.querySelector('.ui_frame_table [name="password"]'), b, i;
  74. if (g.chat_max_history < 1000) g.chat_max_history = 1000;
  75. g.title_append = g.title_append.replace(' - Volafile.org Live Filesharing & Chat', '');
  76. if (pin) {
  77. b = d.querySelectorAll('.ui_frame_buttons .button:not(.light)');
  78. i = b.length;
  79. while (i--) b[i].click();
  80. }
  81. killnews('queued_messages');
  82. }
  83. function flist(e) {
  84. var f = d.querySelectorAll('#file_list .filelist_file:not([id]):not([style]):not(.file_queued):not(.file_uploading)'),
  85. v = b.appendChild(d.createElement('div')),
  86. i = f.length, t = '', inf;
  87. while (i--) {
  88. if (f[i].id === 'prog1') {
  89. if (i !== 0) t += '#----------------------------------------------------------------------------------------------------\n';
  90. continue;
  91. }
  92. inf = '#____' + f[i].querySelector('a .file_tag').innerText + '_' +
  93. f[i].querySelector('.file_right_part').childNodes[0].data.replace(' ', '');
  94. t += f[i].querySelector('a[href]').href + inf + '\n';
  95. }
  96. v.innerHTML += '<div id="flist_list" style="position:absolute;top:0;left:0;background:#88f">' +
  97. '<a id="kill_flist" href="#" onclick="this.parentNode.parentNode.removeChild(this.parentNode)">[⮽ CLOSE]</a> &bull; ' +
  98. '<a href="#" onclick="window.text.value=window.text.value.replace(/\\n$/,[]).split(\'\\n\').reverse().join(\'\\n\')+\'\\n\'">[⇵ reverse]</a>' +
  99. '<textarea id="text" spellcheck="false" style="width:80em;height:30em;margin:1em;resize:both;display:block">' +
  100. t + '</textarea></div>';
  101. e.preventDefault();
  102. return false;
  103. }
  104. function unCuck() {
  105. u = d.getElementById('dolos_cuckmenu');
  106. if (u) {
  107. u.style.fontSize = '75%';
  108. if (k) w.clearInterval(k);
  109. }
  110. }
  111. w.addEventListener('load', init, false);
  112. d.addEventListener('DOMContentLoaded', unCuck, false);
  113. w.addEventListener('load', unCuck, false);
  114. if (u) u.style.fontSize = '75%';
  115. else k = w.setInterval(unCuck, 100);
  116. })(window, document, document.body || body);