Memoarca

Memo certain nicknames for arca.live

  1. // ==UserScript==
  2. // @name Memoarca
  3. // @name:ko 메모아카
  4. // @name:es Memoarca
  5. // @name:gn Memoarca
  6. // @version 2024-06-20.1
  7. // @description Memo certain nicknames for arca.live
  8. // @description:ko 아카라이브 브라우저에서 메모하기
  9. // @description:es Memoriza ciertos apodos para arca.live
  10. // @description:gn Memo ciertos apodos para arca.live
  11. // @author noise1617@gmail.com
  12. // @license MIT License
  13. // @match https://arca.live/*
  14. // @run-at document-end
  15. // @grant GM_registerMenuCommand
  16. // @grant GM_setValue
  17. // @grant GM_getValue
  18. // @namespace https://greasyfork.org/users/1320818
  19. // ==/UserScript==
  20.  
  21. /* 고정닉: '닉' 그대로 입력
  22. 반고닉: '닉#(번호)' 입력
  23. 유동: 'IP.두자리' 입력 ex) '255.255'
  24. */
  25.  
  26. (function() {
  27. 'use strict';
  28.  
  29. // 설정: 메모의 배경색, 글자색
  30. const memoBackgroundColor = 'yellow';
  31. const memoColor = 'black';
  32.  
  33. const mapToObject = map => Object.fromEntries(map.entries());
  34. const objectToMap = obj => new Map(Object.entries(obj));
  35. const setMemoMap = memoMap => GM_setValue("memoMap", mapToObject(memoMap));
  36. const getMemoMap = function() { return objectToMap(GM_getValue("memoMap", null)); };
  37.  
  38. // Map 닉 -> 메모
  39. var initMemoMap = function() {
  40. var memoMap = GM_getValue("memoMap", null);
  41. if (memoMap == null) {
  42. let memoMap = new Map();
  43. memoMap.set('*ㅎㅎ','전 관리자'); // default 메모
  44. setMemoMap(memoMap);
  45. };
  46. };
  47. initMemoMap();
  48.  
  49. var sanitizedId = function(text) {
  50. return text.replace(/^[^,]*(?:, )|\s+$/,'');
  51. };
  52.  
  53. var writeMemo = function() {
  54. var defaultNickname = "";
  55. if (window.location.href.match(/https:\/\/arca\.live\/u\/@.*/)) { // 이미 누군가의 챈로그에 있다면
  56. defaultNickname = window.location.href.replace(/https:\/\/arca\.live\/u\/@/, "");
  57. defaultNickname = sanitizedId(decodeURIComponent(defaultNickname.replace("/","#")));
  58. } else {
  59. var head = document.querySelector(".article-head")
  60. if (head) {
  61. defaultNickname = getIds(head, defaultNickname);
  62. };
  63. };
  64. var id = prompt("닉네임:", defaultNickname);
  65. if (id == null) { return; };
  66. if (id == "") {
  67. alert("No Nickname");
  68. };
  69. id = sanitizedId(id);
  70.  
  71. var memoMap = getMemoMap();
  72. var memo = prompt("메모: " + id, memoMap.get(id));
  73. if (!memo) {
  74. if (confirm(id + "에 대한 메모를 지우시겠습니까?")){
  75. memoMap.delete(id);
  76. };
  77. } else {
  78. memoMap.set(id, memo);
  79. };
  80. setMemoMap(memoMap);
  81. setTimeout(run, 3000);
  82. };
  83.  
  84. var exportMemo = function() {
  85. var memoMap = GM_getValue("memoMap", null);
  86. alert(JSON.stringify(memoMap));
  87. };
  88.  
  89. var importMemo = function() {
  90. var memoMap = prompt("Import Memos: ");
  91. if (memoMap == null) { return; };
  92. try {
  93. memoMap = JSON.parse(memoMap);
  94. } catch(e) {
  95. alert("입력을 이해하지 못했습니다");
  96. console.log(e);
  97. return;
  98. }
  99. if (!memoMap) {
  100. if (confirm("모든 메모를 지우시겠습니까?")){
  101. setMemoMap(new Map());
  102. };
  103. } else {
  104. GM_setValue("memoMap", memoMap);
  105. }
  106. setTimeout(run, 3000);
  107. }
  108.  
  109. const menu_command_writeMemo = GM_registerMenuCommand("Write Memo", writeMemo);
  110. const menu_command_exportMemo = GM_registerMenuCommand("Export", exportMemo);
  111. const menu_command_importMemo = GM_registerMenuCommand("Import", importMemo);
  112.  
  113. var getNicknames = function() {
  114. var nicknames = document.querySelectorAll(".user-info");
  115. return nicknames;
  116. };
  117.  
  118. var getIds = function(nickname, noname = null) {
  119. var idObj = nickname.querySelector("a[data-filter],span[data-filter]");
  120. if (idObj) {
  121. var id = idObj.getAttribute('data-filter');
  122. return sanitizedId(id);
  123. };
  124. return noname;
  125. };
  126.  
  127. var addMemoObj = function(nickname, memoMap) {
  128. var id = getIds(nickname);
  129. if (id == null) {return null;};
  130. var memoText = memoMap[id]; // Map as Object
  131. if(memoText){
  132. let memoObj = nickname.querySelector("#memo_by_memoarca");
  133. if (memoObj) { // A memo already exists, we are overwriting
  134. memoObj.innerHTML = memoText;
  135. } else { // New memo
  136. let memoObj = document.createElement('span');
  137. memoObj.style.backgroundColor = memoBackgroundColor;
  138. memoObj.style.color = memoColor;
  139. memoObj.id = "memo_by_memoarca"
  140. memoObj.innerHTML = memoText;
  141. nickname.insertBefore(memoObj, nickname.querySelector(".zero-at-one-space"));
  142. };
  143. } else {
  144. // Delete memo > delete memoObj
  145. var memoObj = nickname.querySelector("#memo_by_memoarca");
  146. if (memoObj) { memoObj.remove(); };
  147. };
  148. };
  149.  
  150. var run = function() {
  151. var nicknames = getNicknames();
  152. var memoMap = GM_getValue("memoMap", null); // as Object
  153. for (var i=0; i<nicknames.length; i++) {
  154. var nickname = nicknames[i];
  155. addMemoObj(nickname, memoMap);
  156. };
  157. };
  158.  
  159. setTimeout(run, 3000);
  160. })();