Instagram - 为关注的用户添加备注

为所关注的用户添加备注功能,以帮助识别

当前为 2019-08-09 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Instagram为关注用户添加备注
  3. // @name:en Instagram - Add notes to following
  4. // @name:zh-CN Instagram - 为关注的用户添加备注
  5. // @name:zh-TW Instagram - 為追蹤的用戶添加備註
  6. // @name:ja Instagram - 興味のあるユーザーにメモを追加する
  7. // @name:ko Instagram - 관심있는 사용자에게 메모 추가
  8. // @namespace https://greasyfork.org/zh-CN/users/193133-pana
  9. // @homepage https://www.sailboatweb.com
  10. // @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yMCwxNSBMMjAsNCBMNCw0IEw0LDIwIEwxNSwyMCBMMTUsMTcgQzE1LDE1Ljg5NTQzMDUgMTUuODk1NDMwNSwxNSAxNywxNSBMMjAsMTUgWiBNMTkuNTg1Nzg2NCwxNyBMMTcsMTcgTDE3LDE5LjU4NTc4NjQgTDE5LjU4NTc4NjQsMTcgWiBNNCwyMiBDMi44OTU0MzA1LDIyIDIsMjEuMTA0NTY5NSAyLDIwIEwyLDQgQzIsMi44OTU0MzA1IDIuODk1NDMwNSwyIDQsMiBMMjAsMiBDMjEuMTA0NTY5NSwyIDIyLDIuODk1NDMwNSAyMiw0IEwyMiwxNy40MTQyMTM2IEwxNy40MTQyMTM2LDIyIEw0LDIyIFogTTcsMTcgTDcsMTUgTDEzLDE1IEwxMywxNyBMNywxNyBaIE03LDEzIEw3LDExIEwxNywxMSBMMTcsMTMgTDcsMTMgWiBNNyw5IEw3LDcgTDE3LDcgTDE3LDkgTDcsOSBaIi8+Cjwvc3ZnPgo=
  11. // @version 1.2.0
  12. // @description 为所关注的用户添加备注功能,以帮助识别
  13. // @description:en Add notes to users you follow to help identify
  14. // @description:zh-CN 为所关注的用户添加备注功能,以帮助识别
  15. // @description:zh-TW 為所追蹤的用戶添加備註功能,以幫助識別
  16. // @description:ja 識別しやすくするために、気になるユーザーにメモを追加します
  17. // @description:ko 식별에 도움이되는 관심 사용자에게 메모 추가
  18. // @author pana
  19. // @include http*://www.instagram.com/*
  20. // @require https://code.jquery.com/jquery-3.4.1.min.js
  21. // @require https://cdnjs.cloudflare.com/ajax/libs/arrive/2.4.1/arrive.min.js
  22. // @grant GM_getValue
  23. // @grant GM_setValue
  24. // ==/UserScript==
  25.  
  26. (function() {
  27. 'use strict';
  28. const LANG = {
  29. ZH: {
  30. div_title: '备注',
  31. input_placeholder: '(请输入备注,置空时删除;按下Enter键保存)',
  32. save_button_text: '保存',
  33. cancel_button_text: '取消',
  34. },
  35. ZH_TW: {
  36. div_title: '備註',
  37. input_placeholder: '(請輸入備註,置空時刪除;按下Enter鍵保存)',
  38. save_button_text: '保存',
  39. cancel_button_text: '取消',
  40. },
  41. EN: {
  42. div_title: 'note',
  43. input_placeholder: '(Enter a note, delete it when blanked; press Enter to save)',
  44. save_button_text: 'Save',
  45. cancel_button_text: 'Cancel',
  46. },
  47. JA: {
  48. div_title: '備考',
  49. input_placeholder: '(コメントを入力し、空白になったら削除してください。)',
  50. save_button_text: '保存する',
  51. cancel_button_text: 'キャンセル',
  52. },
  53. KO: {
  54. div_title: '비고',
  55. input_placeholder: '(메모를 입력하십시오.비워지면 삭제)',
  56. save_button_text: '저장',
  57. cancel_button_text: '취소',
  58. },
  59. };
  60. var lang_value = {
  61. div_title: 'note',
  62. input_placeholder: '(Please enter a note and delete it when blanked)',
  63. save_button_text: 'Save',
  64. cancel_button_text: 'Cancel',
  65. };
  66. var user_handle = {
  67. user_id: '',
  68. user_tag: '',
  69. };
  70. var instagram_config = {};
  71. var default_config = {
  72. user_array: [],
  73. };
  74. const PAGE_REG = {
  75. HOMEPAGE: /^https?:\/\/www\.instagram\.com\/?(\?[a-z]+=[a-z\-]+)?$/i,
  76. USER_PAGE: /^https?:\/\/www\.instagram\.com\/[^/]*\/?(\?[a-z]+=[a-z\-]+)?$/i,
  77. STORIES: /^https?:\/\/www\.instagram\.com\/stories\/[^/]*\/?(\?[a-z]+=[a-z\-]+)?$/i,
  78. };
  79.  
  80. function judge_User(user_title) {
  81. for (let i = 0; i < instagram_config.user_array.length; i++) {
  82. if (user_title === instagram_config.user_array[i].user_id) {
  83. return i
  84. }
  85. }
  86. return -1
  87. }
  88. function write_User(user_title, input_tag) {
  89. let judge_value = judge_User(user_title);
  90. if (judge_value !== -1) {
  91. if (input_tag) {
  92. instagram_config.user_array[judge_value].user_tag = input_tag
  93. } else {
  94. instagram_config.user_array.splice(judge_value, 1)
  95. }
  96. } else {
  97. if (input_tag) {
  98. let temp_user_obj = {
  99. user_id: user_title,
  100. user_tag: input_tag,
  101. };
  102. instagram_config.user_array.push(temp_user_obj)
  103. }
  104. }
  105. GM_setValue('instagram_config', instagram_config)
  106. }
  107. function create_Add_Input_Div(user_title) {
  108. let presentation_div = document.createElement('div');
  109. presentation_div.className = 'presentation_div_for_user';
  110. presentation_div.style.display = 'flex';
  111. presentation_div.style.position = 'fixed';
  112. presentation_div.style.backgroundColor = 'rgba(0, 0, 0, .5)';
  113. presentation_div.style.top = '0';
  114. presentation_div.style.bottom = '0';
  115. presentation_div.style.left = '0';
  116. presentation_div.style.right = '0';
  117. presentation_div.style.zIndex = '1';
  118. presentation_div.style.alignItems = 'center';
  119. presentation_div.style.justifyContent = 'center';
  120. presentation_div.addEventListener('click', function(event) {
  121. if (event.target === this) {
  122. $('.presentation_div_for_user').remove()
  123. }
  124. });
  125. let dialog_div = document.createElement('div');
  126. dialog_div.className = 'dialog_div_for_user';
  127. dialog_div.style.position = 'relative';
  128. dialog_div.style.width = '400px';
  129. dialog_div.style.backgroundColor = '#fff';
  130. dialog_div.style.border = '0 solid #000';
  131. dialog_div.style.borderRadius = '12px';
  132. let user_title_p = document.createElement('button');
  133. user_title_p.className = 'user_title_span_for_user';
  134. user_title_p.innerText = user_title;
  135. user_title_p.style.minHeight = '48px';
  136. user_title_p.style.textAlign = 'center';
  137. user_title_p.style.border = '1px solid #efefef';
  138. user_title_p.style.color = 'red';
  139. user_title_p.style.fontWeight = 'bold';
  140. user_title_p.style.backgroundColor = 'rgba(0, 0, 0, 0)';
  141. user_title_p.style.borderTopLeftRadius = '12px';
  142. user_title_p.style.borderTopRightRadius = '12px';
  143. let tag_input = document.createElement('input');
  144. tag_input.className = 'tag_input_for_user';
  145. tag_input.type = 'text';
  146. tag_input.placeholder = lang_value.input_placeholder;
  147. tag_input.style.minHeight = '32px';
  148. tag_input.style.margin = '5px';
  149. let judge_value = judge_User(user_title);
  150. if (judge_value !== -1) {
  151. tag_input.value = instagram_config.user_array[judge_value].user_tag
  152. } else {
  153. tag_input.value = ''
  154. }
  155. $(tag_input).keyup(function(e) {
  156. if (e.keyCode === 13) {
  157. write_User(user_title, $('.tag_input_for_user').val());
  158. save_Update_Event(user_title);
  159. $('.presentation_div_for_user').remove()
  160. }
  161. });
  162. let save_button = document.createElement('button');
  163. save_button.className = 'save_button_for_user';
  164. save_button.type = 'button';
  165. save_button.innerText = lang_value.save_button_text;
  166. save_button.style.minHeight = '48px';
  167. save_button.style.cursor = 'pointer';
  168. save_button.style.border = '1px solid #efefef';
  169. save_button.style.backgroundColor = 'rgba(0, 0, 0, 0)';
  170. save_button.addEventListener('click', function() {
  171. write_User(user_title, $('.tag_input_for_user').val());
  172. save_Update_Event(user_title);
  173. $('.presentation_div_for_user').remove()
  174. });
  175. let cancel_button = document.createElement('button');
  176. cancel_button.className = 'cancel_button_for_user';
  177. cancel_button.type = 'button';
  178. cancel_button.innerText = lang_value.cancel_button_text;
  179. cancel_button.style.minHeight = '48px';
  180. cancel_button.style.cursor = 'pointer';
  181. cancel_button.style.border = '1px solid #efefef';
  182. cancel_button.style.backgroundColor = 'rgba(0, 0, 0, 0)';
  183. cancel_button.style.borderBottomLeftRadius = '12px';
  184. cancel_button.style.borderBottomRightRadius = '12px';
  185. cancel_button.addEventListener('click', function(event) {
  186. $('.presentation_div_for_user').remove()
  187. });
  188. dialog_div.appendChild(user_title_p);
  189. dialog_div.appendChild(tag_input);
  190. dialog_div.appendChild(save_button);
  191. dialog_div.appendChild(cancel_button);
  192. presentation_div.appendChild(dialog_div);
  193. return presentation_div
  194. }
  195. function create_Add_Tags_Div(user_title) {
  196. let tags_div = document.createElement('div');
  197. tags_div.className = 'Tags_A';
  198. tags_div.href = 'javascript:;';
  199. tags_div.title = lang_value.div_title;
  200. tags_div.style.width = '32px';
  201. tags_div.style.height = '32px';
  202. tags_div.style.backgroundImage = 'url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yMCwxNSBMMjAsNCBMNCw0IEw0LDIwIEwxNSwyMCBMMTUsMTcgQzE1LDE1Ljg5NTQzMDUgMTUuODk1NDMwNSwxNSAxNywxNSBMMjAsMTUgWiBNMTkuNTg1Nzg2NCwxNyBMMTcsMTcgTDE3LDE5LjU4NTc4NjQgTDE5LjU4NTc4NjQsMTcgWiBNNCwyMiBDMi44OTU0MzA1LDIyIDIsMjEuMTA0NTY5NSAyLDIwIEwyLDQgQzIsMi44OTU0MzA1IDIuODk1NDMwNSwyIDQsMiBMMjAsMiBDMjEuMTA0NTY5NSwyIDIyLDIuODk1NDMwNSAyMiw0IEwyMiwxNy40MTQyMTM2IEwxNy40MTQyMTM2LDIyIEw0LDIyIFogTTcsMTcgTDcsMTUgTDEzLDE1IEwxMywxNyBMNywxNyBaIE03LDEzIEw3LDExIEwxNywxMSBMMTcsMTMgTDcsMTMgWiBNNyw5IEw3LDcgTDE3LDcgTDE3LDkgTDcsOSBaIi8+Cjwvc3ZnPgo=)';
  203. tags_div.style.backgroundRepeat = 'no-repeat';
  204. tags_div.style.backgroundPosition = 'center';
  205. tags_div.style.backgroundSize = '24px auto';
  206. tags_div.style.marginLeft = '5px';
  207. tags_div.addEventListener('click', function() {
  208. document.body.appendChild(create_Add_Input_Div(user_title))
  209. });
  210. return tags_div
  211. }
  212. function create_Add_Tag_P(tag_string) {
  213. let tag_p = document.createElement('p');
  214. tag_p.className = 'tag_p';
  215. tag_p.style.marginLeft = '5px';
  216. tag_p.style.color = '#990033';
  217. tag_p.style.whiteSpace = 'nowrap';
  218. tag_p.innerText = '(' + tag_string + ')';
  219. return tag_p
  220. }
  221. function create_Add_Tag_Span(tag_string, font_size) {
  222. let tag_span = document.createElement('span');
  223. tag_span.className = 'tag_span';
  224. tag_span.style.marginLeft = '5px';
  225. tag_span.style.color = '#990033';
  226. tag_span.style.fontSize = font_size;
  227. tag_span.innerText = '(' + tag_string + ')';
  228. return tag_span
  229. }
  230. function homepage_Event(dom_container) {
  231. let user_title = $(dom_container).find('a.nJAzx').attr('title');
  232. let judge_value = judge_User(user_title);
  233. if (judge_value !== -1) {
  234. $(dom_container).find('.e1e1d').append(create_Add_Tag_P(instagram_config.user_array[judge_value].user_tag))
  235. }
  236. $(dom_container).find('.e1e1d').append(create_Add_Tags_Div(user_title));
  237. $(dom_container).find('.e1e1d').css('overflow', 'visible')
  238. }
  239. function homepage_Stories_Event(dom_container) {
  240. let user_title = $(dom_container).find('.jQgLo').text();
  241. let judge_value = judge_User(user_title);
  242. if (judge_value !== -1) {
  243. $(dom_container).find('.jQgLo').append(create_Add_Tag_Span(instagram_config.user_array[judge_value].user_tag, '12px'))
  244. }
  245. }
  246. function user_Page_Event(selector_container) {
  247. let user_title = selector_container.find('.KV-D4').text();
  248. selector_container.find('.AFWDX').after(create_Add_Tags_Div(user_title));
  249. let judge_value = judge_User(user_title);
  250. if (judge_value !== -1) {
  251. selector_container.find('.AFWDX').after(create_Add_Tag_Span(instagram_config.user_array[judge_value].user_tag, '16px'))
  252. }
  253. $.each(selector_container.find('span._32eiM'), function(index, item) {
  254. let em_user_title = item.innerText;
  255. let em_judge_value = judge_User(em_user_title);
  256. if (em_judge_value !== -1) {
  257. item.innerText = em_user_title + ' (' + instagram_config.user_array[em_judge_value].user_tag + ')'
  258. }
  259. })
  260. }
  261. function stories_Page_Event(selector_container) {
  262. let user_title = selector_container.find('.FPmhX').text();
  263. let judge_value = judge_User(user_title);
  264. if (judge_value !== -1) {
  265. selector_container.append(create_Add_Tag_Span(instagram_config.user_array[judge_value].user_tag, '14px'))
  266. }
  267. }
  268. function follow_Page_Event(selector_container) {
  269. if (selector_container.find('.tag_span').length === 0) {
  270. let user_title = selector_container.find('a.FPmhX').attr('title');
  271. let judge_value = judge_User(user_title);
  272. if (judge_value !== -1) {
  273. selector_container.find('a.FPmhX').parent().append(create_Add_Tag_Span(instagram_config.user_array[judge_value].user_tag, '14px'))
  274. }
  275. }
  276. }
  277. function save_Update_Event(user_title) {
  278. let old_url = location.href;
  279. if (PAGE_REG.HOMEPAGE.test(old_url)) {
  280. $.each($('article'), function(index, item) {
  281. let page_user_title = $(item).find('a.nJAzx').attr('title');
  282. if (user_title === page_user_title) {
  283. let judge_value = judge_User(user_title);
  284. if (judge_value !== -1) {
  285. if ($(item).find('p.tag_p').length !== 0) {
  286. $(item).find('p.tag_p').text('(' + instagram_config.user_array[judge_value].user_tag + ')')
  287. } else {
  288. $(item).find('.Tags_A').before(create_Add_Tag_P(instagram_config.user_array[judge_value].user_tag))
  289. }
  290. } else {
  291. if ($(item).find('p.tag_p').length !== 0) {
  292. $(item).find('p.tag_p').remove()
  293. }
  294. }
  295. }
  296. });
  297. $.each($('.BI5t6'), function(index, item) {
  298. let page_user_selector = $(item).find('.jQgLo').clone();
  299. page_user_selector.find('.tag_span').remove();
  300. let page_user_title = page_user_selector.text();
  301. if (user_title === page_user_title) {
  302. let judge_value = judge_User(user_title);
  303. if (judge_value !== -1) {
  304. if ($(item).find('span.tag_span').length !== 0) {
  305. $(item).find('span.tag_span').text('(' + instagram_config.user_array[judge_value].user_tag + ')')
  306. } else {
  307. $(item).find('.jQgLo').append(create_Add_Tag_Span(instagram_config.user_array[judge_value].user_tag, '12px'))
  308. }
  309. } else {
  310. if ($(item).find('span.tag_span').length !== 0) {
  311. $(item).find('span.tag_span').remove()
  312. }
  313. }
  314. }
  315. })
  316. } else if (PAGE_REG.USER_PAGE.test(old_url)) {
  317. let user_title = $('.KV-D4').text();
  318. let judge_value = judge_User(user_title);
  319. if (judge_value !== -1) {
  320. if ($('.tag_span').length !== 0) {
  321. $('.tag_span').text('(' + instagram_config.user_array[judge_value].user_tag + ')')
  322. } else {
  323. $('.AFWDX').after(create_Add_Tag_Span(instagram_config.user_array[judge_value].user_tag, '16px'))
  324. }
  325. } else {
  326. if ($('.tag_span').length !== 0) {
  327. $('.tag_span').remove()
  328. }
  329. }
  330. }
  331. }
  332. function set_Language(lang_string) {
  333. switch (lang_string) {
  334. case 'zh':
  335. case 'zh-cn':
  336. lang_value = LANG.ZH;
  337. break;
  338. case 'zh-hk':
  339. case 'zh-tw':
  340. lang_value = LANG.ZH_TW;
  341. break;
  342. case 'en':
  343. lang_value = LANG.EN;
  344. break;
  345. case 'ja':
  346. lang_value = LANG.JA;
  347. break;
  348. case 'ko':
  349. lang_value = LANG.KO;
  350. break;
  351. default:
  352. lang_value = LANG.EN;
  353. break
  354. }
  355. }
  356. function init() {
  357. set_Language($('html:first').attr('lang'));
  358. $.each($('article'), function(index, item) {
  359. homepage_Event(item)
  360. });
  361. setTimeout(function() {
  362. $.each($('.BI5t6'), function(index, item) {
  363. homepage_Stories_Event(item)
  364. })
  365. }, 1000);
  366. $('#react-root').arrive('article', function() {
  367. homepage_Event(this)
  368. });
  369. $('#react-root').arrive('.BI5t6', function() {
  370. homepage_Stories_Event(this)
  371. });
  372. if ($('.zwlfE').length !== 0) {
  373. user_Page_Event($('.zwlfE'))
  374. }
  375. $('#react-root').arrive('.zwlfE', function() {
  376. user_Page_Event($(this))
  377. });
  378. if ($('.yn6BW').length !== 0) {
  379. stories_Page_Event($('.yn6BW'))
  380. }
  381. $('#react-root').arrive('.yn6BW', function() {
  382. stories_Page_Event($(this))
  383. });
  384. $('body').arrive('.isgrP li', {
  385. onceOnly: true
  386. }, function() {
  387. follow_Page_Event($(this))
  388. });
  389. $('body').arrive('.d7ByH', function() {
  390. follow_Page_Event($(this))
  391. })
  392. }
  393. Promise.all([GM_getValue('instagram_config')]).then(function(data) {
  394. if (data[0] !== undefined) {
  395. instagram_config = data[0]
  396. } else {
  397. instagram_config = default_config
  398. }
  399. init()
  400. })
  401. })();