NimoTV Chat Enhancer

Tùy chỉnh phòng chat NimoTV: gán màu ngẫu nhiên cho tên người dùng (lưu trong localStorage), thêm nút trả lời, sửa lỗi từ bị chặn và lỗi trùng video.

  1. // ==UserScript==
  2. // @name NimoTV Chat Enhancer
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  5. // @description Tùy chỉnh phòng chat NimoTV: gán màu ngẫu nhiên cho tên người dùng (lưu trong localStorage), thêm nút trả lời, sửa lỗi từ bị chặn và lỗi trùng video.
  6. // @author You
  7. // @match https://*.nimo.tv/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. // Hàm lấy cookie
  15. function getCookie(cname) {
  16. let name = cname + '=';
  17. let decodedCookie = decodeURIComponent(document.cookie);
  18. let ca = decodedCookie.split(';');
  19. for (let i = 0; i < ca.length; i++) {
  20. let c = ca[i];
  21. while (c.charAt(0) == ' ') {
  22. c = c.substring(1);
  23. }
  24. if (c.indexOf(name) == 0) {
  25. return c.substring(name.length, c.length);
  26. }
  27. }
  28. return '';
  29. }
  30.  
  31. // Khôi phục hoặc khởi tạo danh sách màu người dùng từ localStorage
  32. let users = JSON.parse(localStorage.getItem('usersColors') || '{}');
  33.  
  34. // Theo dõi thay đổi DOM
  35. new MutationObserver((mutations, observer) => {
  36. for (const mutation of mutations) {
  37. if (mutation.type === 'childList') {
  38. for (const node of mutation.addedNodes) {
  39. // Tùy chỉnh tin nhắn chat
  40. if (node && node.classList && node.classList.contains('nimo-room__chatroom__message-item')) {
  41. const chatMessage = node;
  42.  
  43. // Lấy tên người dùng và tên người dùng hiện tại
  44. const username = chatMessage.querySelector('.nm-message-nickname').innerHTML;
  45. const currentUserName = getCookie('userName');
  46.  
  47. // Gán màu cho người dùng nếu chưa có
  48. if (!users[username]) {
  49. users[username] = `hsl(${Math.ceil(365 * Math.random())}, ${Math.ceil(Math.random() * 50 + 50)}%, 65%)`;
  50. localStorage.setItem('usersColors', JSON.stringify(users));
  51. }
  52.  
  53. // Áp dụng màu
  54. const colon = chatMessage.querySelector('.nimo-room__chatroom__message-item__info-colon');
  55. if (colon) {
  56. colon.style.color = users[username];
  57. }
  58. chatMessage.querySelector('.nm-message-nickname').style.color = users[username];
  59.  
  60. // Thêm nút trả lời
  61. const btn = document.createElement('span');
  62. btn.classList.add('n-as-vtm');
  63. btn.innerHTML = ' <img src="https://img.icons8.com/office/32/paper-plane.png" width="16" height="16" style="vertical-align:middle;"/>';
  64. btn.addEventListener('click', () => {
  65. const [chatbox] = document.getElementsByClassName('nimo-chat-box__input');
  66. chatbox.value = `@${username} `;
  67. chatbox.focus();
  68. });
  69. chatMessage.append(btn);
  70.  
  71. // Sửa lỗi từ bị chặn
  72. if (currentUserName === username) {
  73. const [chatbox] = document.getElementsByClassName('nimo-chat-box__input');
  74. if (chatbox.value.length > 2) {
  75. chatMessage.classList.add('message-filtered');
  76. }
  77. }
  78. }
  79.  
  80. // Sửa lỗi trùng video
  81. if (node && node.nodeName && node.nodeName.toLowerCase() === 'video') {
  82. const videoContainer = node.parentElement;
  83. if (videoContainer && videoContainer.classList && videoContainer.classList.contains('video-player')) {
  84. const videos = videoContainer.querySelectorAll('video');
  85. if (videos && videos.length > 1) {
  86. videos[0].remove();
  87. }
  88. }
  89. }
  90. }
  91. }
  92. }
  93. }).observe(document.body, {
  94. attributes: false,
  95. childList: true,
  96. subtree: true
  97. });
  98. })();