labels panel

labels panel from catliife

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         labels panel
// @namespace    http://tampermonkey.net/
// @version      2025-01-19
// @description  labels panel from catliife
// @author       me
// @match        https://worldcats.ru/play/
// @match        https://worldcats.ru/play/?v=b
// @match        https://catlifeonline.com/play/
// @match        https://catlifeonline.com/play/?v=b
// @icon         https://www.google.com/s2/favicons?sz=64&domain=catlifeonline.com
// @grant        none
// ==/UserScript==

// Создаем контейнер для интерфейса
var mapUI = document.createElement('div');
mapUI.style.position = 'fixed';
mapUI.style.top = '10px';
mapUI.style.right = '80px';
mapUI.style.zIndex = '9999';
mapUI.style.background = 'rgba(0,0,0,0.7)';
mapUI.style.padding = '10px';
mapUI.style.borderRadius = '5px';
mapUI.style.color = 'white';
mapUI.style.fontFamily = 'Arial';
mapUI.style.width = '300px';
mapUI.style.display = 'none';

// Кнопка для показа/скрытия панели
var toggleBtn = document.createElement('button');
toggleBtn.textContent = 'Метки';
toggleBtn.style.position = 'fixed';
toggleBtn.style.top = '10px';
toggleBtn.style.right = '80px';
toggleBtn.style.zIndex = '9998';
toggleBtn.style.padding = '5px 10px';
toggleBtn.style.background = '#3498db';
toggleBtn.style.border = 'none';
toggleBtn.style.borderRadius = '3px';
toggleBtn.style.cursor = 'pointer';

toggleBtn.onclick = function() {
  mapUI.style.display = mapUI.style.display === 'none' ? 'block' : 'none';
};

document.body.appendChild(toggleBtn);

// Заголовок и кнопка закрытия
var header = document.createElement('div');
header.style.display = 'flex';
header.style.justifyContent = 'space-between';
header.style.alignItems = 'center';
header.style.marginBottom = '15px';

var title = document.createElement('h3');
title.textContent = 'Панель меток';
title.style.margin = '0';

var closeBtn = document.createElement('button');
closeBtn.textContent = '×';
closeBtn.style.background = 'transparent';
closeBtn.style.border = 'none';
closeBtn.style.color = 'white';
closeBtn.style.fontSize = '20px';
closeBtn.style.cursor = 'pointer';
closeBtn.style.padding = '0 5px';

closeBtn.onclick = function() {
  mapUI.style.display = 'none';
};

header.appendChild(title);
header.appendChild(closeBtn);
mapUI.appendChild(header);

// Секция для ввода названия
var nameSection = document.createElement('div');
nameSection.style.marginBottom = '10px';

var nameLabel = document.createElement('label');
nameLabel.textContent = 'Название локации:';
nameLabel.style.display = 'block';
nameLabel.style.marginBottom = '5px';

var nameInput = document.createElement('input');
nameInput.type = 'text';
nameInput.id = 'wcNameInput';
nameInput.placeholder = 'Введите название';
nameInput.style.width = '100%';
nameInput.style.padding = '5px';

nameSection.appendChild(nameLabel);
nameSection.appendChild(nameInput);
mapUI.appendChild(nameSection);

// Секция для ввода локации
var locSection = document.createElement('div');
locSection.style.marginBottom = '15px';

var locLabel = document.createElement('label');
locLabel.textContent = 'ID локации:';
locLabel.style.display = 'block';
locLabel.style.marginBottom = '5px';

var locInput = document.createElement('input');
locInput.type = 'text';
locInput.id = 'wcLocationInput';
locInput.placeholder = 'Введите ID';
locInput.style.width = '100%';
locInput.style.padding = '5px';

locSection.appendChild(locLabel);
locSection.appendChild(locInput);
mapUI.appendChild(locSection);

// Кнопки для меток
var btnContainer = document.createElement('div');
btnContainer.style.display = 'flex';
btnContainer.style.flexWrap = 'wrap';
btnContainer.style.gap = '5px';
btnContainer.style.marginBottom = '10px';

var btnResource = createButton('Ресурсы', '#2ecc71');
var btnDanger = createButton('Опасность', '#e74c3c');
var btnCustom = createButton('Своя метка', '#9b59b6');
var btnDelete = createButton('Удалить', '#e74c3c');

btnContainer.appendChild(btnResource);
btnContainer.appendChild(btnDanger);
btnContainer.appendChild(btnCustom);
btnContainer.appendChild(btnDelete);
mapUI.appendChild(btnContainer);// Кнопка для просмотра всех меток
var btnShowAll = createButton('Все метки', '#f39c12');
btnShowAll.style.marginTop = '10px';
mapUI.appendChild(btnShowAll);

// Блок для отображения информации
var infoDiv = document.createElement('div');
infoDiv.id = 'wcMarkerInfo';
infoDiv.style.marginTop = '15px';
infoDiv.style.padding = '10px';
infoDiv.style.background = 'rgba(255,255,255,0.1)';
infoDiv.style.borderRadius = '5px';
mapUI.appendChild(infoDiv);// Добавляем контейнер в документ
document.body.appendChild(mapUI);

// Функция создания кнопки
function createButton(text, color) {
  var btn = document.createElement('button');
  btn.textContent = text;
  btn.style.background = color;
  btn.style.border = 'none';
  btn.style.padding = '5px 10px';
  btn.style.borderRadius = '3px';
  btn.style.cursor = 'pointer';
  btn.style.flex = '1 1 auto';
  return btn;
}

// Загружаем сохраненные метки
var savedMarkers = loadMarkers();

// Функция загрузки меток
function loadMarkers() {
  try {
    var savedData = localStorage.getItem('wcMarkers');
    return savedData ? JSON.parse(savedData) : {};
  } catch (e) {
    console.error('Ошибка загрузки меток:', e);
    return {};
  }
}

// Функция сохранения меток
function saveMarkers() {
  try {
    localStorage.setItem('wcMarkers', JSON.stringify(savedMarkers));
    return true;
  } catch (e) {
    console.error('Ошибка сохранения меток:', e);
    return false;
  }
}

// Функция для добавления метки
function addMarker(type, color) {
  var locId = document.getElementById('wcLocationInput').value.trim();
  var name = document.getElementById('wcNameInput').value.trim();

  if (!locId) return alert('Введите ID локации!');
  if (!name) return alert('Введите название локации!');

  var details = prompt('Описание для метки "' + type + '":', type);
  if (details === null) return;

  if (type === 'Своя метка') {
    color = prompt('Цвет метки (HEX, например #ff0000):', color);
    if (color === null) return;
  }

  savedMarkers[locId] = {
    type: type,
    color: color,
    name: name,
    text: details,
    date: new Date().toLocaleString()
  };

  if (!saveMarkers()) {
    return alert('Ошибка сохранения! Возможно, закончилось место.');
  }

  alert('✅ Метка добавлена на локацию ' + locId + '!');
}

// Функция для удаления метки
function deleteMarker() {
  var locId = document.getElementById('wcLocationInput').value.trim();
  if (!locId) return alert('Введите ID локации!');

  if (!savedMarkers[locId]) return alert('Метка не найдена!');

  if (confirm('Удалить метку для локации ' + locId + '?')) {
    delete savedMarkers[locId];
    if (saveMarkers()) {
      alert('Метка удалена!');
    } else {
      alert('Ошибка при удалении!');
    }
  }
}

// Обработчики для кнопок
btnResource.onclick = function() { addMarker('Ресурсы', '#2ecc71'); };
btnDanger.onclick = function() { addMarker('Опасность', '#e74c3c'); };
btnCustom.onclick = function() { addMarker('Своя метка', '#9b59b6'); };
btnDelete.onclick = deleteMarker;

// Функция для показа всех меток
btnShowAll.onclick = showAllMarkers;

// Переменная для хранения текущего окна меток
var currentMarkersWindow = null;

function showAllMarkers() {
  // Закрываем предыдущее окно, если оно есть
  if (currentMarkersWindow) {
    document.body.removeChild(currentMarkersWindow);
  }

  currentMarkersWindow = document.createElement('div');
  currentMarkersWindow.style.position = 'fixed';
  currentMarkersWindow.style.top = '50%';
  currentMarkersWindow.style.left = '50%';
  currentMarkersWindow.style.transform = 'translate(-50%, -50%)';
  currentMarkersWindow.style.background = 'rgba(0,0,0,0.9)';
  currentMarkersWindow.style.padding = '20px';
  currentMarkersWindow.style.borderRadius = '5px';
  currentMarkersWindow.style.zIndex = '10000';
  currentMarkersWindow.style.width = '80%';
  currentMarkersWindow.style.maxWidth = '600px';
  currentMarkersWindow.style.maxHeight = '80vh';
  currentMarkersWindow.style.overflow = 'hidden';
  currentMarkersWindow.style.color = 'white';
  currentMarkersWindow.style.boxShadow = '0 0 20px rgba(0,0,0,0.5)';// Заголовок
  var header = document.createElement('div');
  header.style.display = 'flex';
  header.style.justifyContent = 'space-between';
  header.style.alignItems = 'center';header.style.marginBottom = '15px';

  var title = document.createElement('h3');
  title.textContent = 'Все метки (' + Object.keys(savedMarkers).length + ')';
  title.style.margin = '0';

  var closeBtn = document.createElement('button');
  closeBtn.textContent = '×';
  closeBtn.style.background = 'transparent';
  closeBtn.style.border = 'none';
  closeBtn.style.color = 'white';
  closeBtn.style.fontSize = '20px';
  closeBtn.style.cursor = 'pointer';
  closeBtn.style.padding = '0 5px';

  closeBtn.onclick = function() {
    document.body.removeChild(currentMarkersWindow);
    currentMarkersWindow = null;
  };

  header.appendChild(title);
  header.appendChild(closeBtn);
  currentMarkersWindow.appendChild(header);

  // Контейнер для списка меток
  var markersContainer = document.createElement('div');
  markersContainer.style.maxHeight = 'calc(80vh - 100px)';
  markersContainer.style.overflowY = 'auto';
  markersContainer.style.paddingRight = '10px';

  // Добавляем прокрутку колесиком мыши
  markersContainer.addEventListener('wheel', function(e) {
    this.scrollTop += e.deltaY;
  });

  if (Object.keys(savedMarkers).length === 0) {
    var emptyMsg = document.createElement('div');
    emptyMsg.textContent = 'Нет сохраненных меток';
    emptyMsg.style.textAlign = 'center';
    emptyMsg.style.padding = '20px';
    emptyMsg.style.color = '#aaa';
    markersContainer.appendChild(emptyMsg);
  } else {
    // Сортируем метки по дате (новые сверху)
    var sortedMarkers = Object.entries(savedMarkers).sort((a, b) => {
      return new Date(b[1].date) - new Date(a[1].date);
    });

    sortedMarkers.forEach(([locId, marker]) => {
      var markerElement = createMarkerElement(locId, marker);
      markersContainer.appendChild(markerElement);
    });
  }

  currentMarkersWindow.appendChild(markersContainer);
  document.body.appendChild(currentMarkersWindow);
}

// Функция создания элемента метки
function createMarkerElement(locId, marker) {
  var markerDiv = document.createElement('div');
  markerDiv.style.marginBottom = '15px';
  markerDiv.style.padding = '10px';
  markerDiv.style.background = 'rgba(255,255,255,0.1)';
  markerDiv.style.borderRadius = '5px';
  markerDiv.style.borderLeft = '4px solid ' + marker.color;
  markerDiv.style.position = 'relative';

  var locSpan = document.createElement('div');
  locSpan.textContent = 'ID: ' + locId;
  locSpan.style.fontWeight = 'bold';

  var nameSpan = document.createElement('div');
  nameSpan.textContent = 'Название: ' + marker.name;
  nameSpan.style.marginTop = '5px';

  var typeSpan = document.createElement('div');
  typeSpan.textContent = 'Тип: ' + marker.type;
  typeSpan.style.marginTop = '5px';

  var textSpan = document.createElement('div');
  textSpan.textContent = 'Описание: ' + marker.text;
  textSpan.style.marginTop = '5px';
  textSpan.style.fontStyle = 'italic';

  var dateSpan = document.createElement('div');
  dateSpan.textContent = 'Дата: ' + marker.date;
  dateSpan.style.marginTop = '5px';
  dateSpan.style.fontSize = '0.8em';
  dateSpan.style.color = '#ccc';

  // Кнопка удаления
  var deleteBtn = document.createElement('button');
  deleteBtn.textContent = 'Удалить';
  deleteBtn.style.position = 'absolute';
  deleteBtn.style.top = '10px';
  deleteBtn.style.right = '10px';
  deleteBtn.style.background = '#e74c3c';
  deleteBtn.style.border = 'none';
  deleteBtn.style.padding = '3px 8px';
  deleteBtn.style.borderRadius = '3px';
  deleteBtn.style.cursor = 'pointer';

  deleteBtn.onclick = function() {
    if (confirm('Удалить метку для локации ' + locId + '?')) {
      delete savedMarkers[locId];
      if (saveMarkers()) {
        markerDiv.style.opacity = '0.5';
        markerDiv.style.transition = 'opacity 0.3s';
        setTimeout(function() {markerDiv.remove();
          updateMarkersCount();
        }, 300);
      }
    }
  };markerDiv.appendChild(locSpan);
  markerDiv.appendChild(nameSpan);
  markerDiv.appendChild(typeSpan);
  markerDiv.appendChild(textSpan);
  markerDiv.appendChild(dateSpan);
  markerDiv.appendChild(deleteBtn);

  return markerDiv;
}

// Обновление счетчика меток
function updateMarkersCount() {
  if (!currentMarkersWindow) return;

  var title = currentMarkersWindow.querySelector('h3');
  if (title) {
    title.textContent = 'Все метки (' + Object.keys(savedMarkers).length + ')';
  }
}