// ==UserScript==
// @name Deepseek会话文件夹
// @namespace http://tampermonkey.net/
// @version 1.2
// @description Manage Deepseek chats using folders. 使用文件夹管理Deepseek会话。
// @author paradox661
// @match https://chat.deepseek.com/*
// @icon https://www.deepseek.com/favicon.ico
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_listValues
// @license MIT
// ==/UserScript==
(function() {
'use strict';
console.log('Start DSChatFolders.');
const FOLDERS = JSON.parse(GM_getValue('folders', '{}'));
const CHATS = JSON.parse(GM_getValue('chats', '{}'));
const FOLDER_STATE = JSON.parse(GM_getValue('folder_state', '{}'));
let FOLDER_SEQ = JSON.parse(GM_getValue('folder_seq', '[]'));
// 等待cond()为true时运行func()
function waitFor(cond, func, timeout=2000) {
const observer = new MutationObserver(function() {
if (cond()) {
observer.disconnect();
func();
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
setTimeout(() => observer.disconnect(), timeout);
}
// 添加需要的CSS类
function addCSSClass() {
const iconLink = document.createElement('link');
iconLink.rel = 'stylesheet';
iconLink.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css';
document.head.appendChild(iconLink);
const style = document.createElement('style');
style.textContent = `
.no-after-content::after {
content: "" !important;
}
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.folder-btn {
border-radius: 12px;
margin: 2px;
}
.folder {
display: flex;
align-items: center;
justify-content: flex-start;
border-radius: 12px;
}
.folder::before {
content: "\\f07b";
font-family: "Font Awesome 6 Free";
font-weight: 900;
color: #6770FE;
display: inline-block;
margin-right: 5px;
}
.folder::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0);
pointer-events: none;
transition: background-color 0.2s;
border-radius: 12px;
}
.folder.active::after {
background-color: rgba(0,0,0,0.08);
}
.chat {
display: none;
align-items: center;
justify-content: flex-start;
}
.chat::before {
content: "";
display: inline-block;
margin-right: 10px;
}
.drop-top {
position: relative;
}
.drop-top::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 2px;
background: blue;
}
.drop-bottom {
position: relative;
}
.drop-bottom::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 2px;
background: blue;
}
`;
document.head.appendChild(style);
}
// 工具函数
let currentDragId = null;
function existChatAnchors() {
// 在某个会话页面刷新可能先加载一个,再加载其他。
// 如果length > 0,可能后续逻辑下其他会话还没有加载。
return getOriginalAnchors().length > 1;
}
function getChatId(chatAnchor) {
const href = chatAnchor.getAttribute('href');
if (href) {
const match = href.match(/^\/a\/chat\/s\/([a-f0-9-]+)$/);
return match[1];
}
}
function outputChatAnchors() {
const chatAnchors = getOriginalAnchors();
console.log(`总共找到 ${chatAnchors.length} 个会话`);
if (chatAnchors.length > 0) {
console.group('DeepSeek 会话');
chatAnchors.forEach(chatAnchor => {
console.log(chatAnchor);
console.log(getChatId(chatAnchor));
});
console.groupEnd();
}
}
function genRandomId() {
// 生成16位定长id
return (Date.now().toString(36).padStart(10, "0") + Math.random().toString(36).substring(2, 8)).slice(0, 16);
}
function isChatId(id) {
return id.length == 36 || id.length == 58;
}
function isFolderId(id) {
return id.length == 16;
}
function insertAfter(newNode, referenceNode) {
const parent = referenceNode.parentNode;
if (referenceNode.nextSibling) {
parent.insertBefore(newNode, referenceNode.nextSibling);
} else {
parent.appendChild(newNode);
}
}
function extractIdFromUrl(url) {
try {
const u = new URL(url);
const match = u.pathname.match(/\/a\/chat\/s\/([a-f0-9-]+)/i);
return match ? match[1] : null;
} catch (e) {
console.error("Invalid URL:", e);
return null;
}
}
// 获取DOM元素
function getScrollArea() {
return document.querySelector('.ds-scroll-area');
}
function getOriginalAnchors() {
return getScrollArea().querySelectorAll('a[href^="/a/chat/s/"]');
}
function getMenuBtn() {
return getScrollArea().querySelector('a[href^="/a/chat/s/"]').children[1];
}
// 获取魔法数字Class
function getBtnClass() {
return getScrollArea().parentNode.children[1].classList[0];
}
function getAnchorClass() {
return getOriginalAnchors()[0].classList[0];
}
function getAnchorSelectedClass() {
return 'b64fb9ae';
}
// 添加DOM元素
function addBtnArea() {
if (document.getElementById('btn-area')) {
return;
}
const btnArea = document.createElement('div');
btnArea.id = 'btn-area';
btnArea.style.cssText = `
display: flex;
margin-top: 6px;
margin-bottom: 6px;
`;
return btnArea;
}
function addNewFolderBtn() {
if (document.getElementById('new-folder-btn')) {
return;
}
const newFolderBtn = document.createElement('button');
newFolderBtn.id = 'new-folder-btn';
newFolderBtn.textContent = 'New Folder';
newFolderBtn.classList.add(getBtnClass(), 'folder-btn', 'no-after-content');
newFolderBtn.style.flex = 4;
newFolderBtn.addEventListener('click', () => {
const folderArea = document.getElementById('folder-area');
const folderName = prompt('文件夹名称:', '');
if (folderName !== null) {
const folderId = genRandomId();
FOLDERS[folderId] = folderName;
FOLDER_STATE[folderId] = false;
FOLDER_SEQ.push(folderId);
GM_setValue('folders', JSON.stringify(FOLDERS));
GM_setValue('folder_state', JSON.stringify(FOLDER_STATE));
GM_setValue('folder_seq', JSON.stringify(FOLDER_SEQ));
const newFolder = addNewFolder(folderName, folderId);
folderArea.appendChild(newFolder);
}
});
return newFolderBtn;
}
function addImportFoldersBtn() {
if (document.getElementById('import-folders-btn')) {
return;
}
const importFoldersBtn = document.createElement('button');
importFoldersBtn.id = 'import-folders-btn';
const icon = document.createElement('i');
icon.className = "fa-solid fa-arrow-turn-down";
importFoldersBtn.appendChild(icon);
importFoldersBtn.classList.add(getBtnClass(), 'folder-btn', 'no-after-content');
importFoldersBtn.style.flex = 1;
importFoldersBtn.style.color = '#6770FE';
//importFoldersBtn.addEventListener('click', () => {
// GM_setValue('folders', '{}');
// GM_setValue('chats', '{}');
// GM_setValue('folder_state', '{}');
// GM_setValue('folder_seq', '[]');
//});
importFoldersBtn.addEventListener('click', () => {
const input = document.createElement('input');
input.type = 'file';
input.accept = '.txt,.json';
input.onchange = async () => {
const file = input.files && input.files[0];
if (!file) return;
const text = await file.text();
const obj = JSON.parse(text);
for (const k of Object.keys(obj)) {
GM_setValue(k, obj[k]);
}
alert('导入完成。');
location.reload();
};
input.click();
});
return importFoldersBtn;
}
function addExportFoldersBtn() {
if (document.getElementById('export-folders-btn')) {
return;
}
const exportFoldersBtn = document.createElement('button');
exportFoldersBtn.id = 'export-folders-btn';
const icon = document.createElement('i');
icon.className = "fa-solid fa-arrow-turn-up";
exportFoldersBtn.appendChild(icon);
exportFoldersBtn.classList.add(getBtnClass(), 'folder-btn', 'no-after-content');
exportFoldersBtn.style.flex = 1;
exportFoldersBtn.style.color = '#6770FE';
//exportFoldersBtn.addEventListener('click', () => {
// console.log(JSON.parse(GM_getValue('folders', '{}')));
// console.log(JSON.parse(GM_getValue('chats', '{}')));
// console.log(JSON.parse(GM_getValue('folder_state', '{}')));
// console.log(JSON.parse(GM_getValue('folder_seq', '[]')));
//});
exportFoldersBtn.addEventListener('click', () => {
const keys = GM_listValues();
const data = {};
for (const k of keys){
data[k] = GM_getValue(k);
}
const text = JSON.stringify(data, null, 2);
const blob = new Blob([text], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `deepseek-folder_${new Date().toISOString().replace(/[:.]/g, '-')}.txt`;
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
});
return exportFoldersBtn;
}
function addFolderArea() {
if (document.getElementById('folder-area')) {
return;
}
const folderArea = document.createElement('div');
folderArea.id = 'folder-area';
folderArea.classList.add('no-scrollbar');
folderArea.style.cssText = `
height: 50%;
overflow-y: auto;
overflow-x: hidden;
`;
return folderArea;
}
function addNewFolder(folderName, folderId) {
const newFolder = document.createElement('div');
newFolder.id = folderId;
const folderHeader = document.createElement('div');
folderHeader.classList.add(getAnchorClass(), 'folder');
const folderHeaderText = document.createElement('div');
folderHeaderText.style.cssText = `
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
`;
folderHeaderText.textContent = folderName;
folderHeader.appendChild(folderHeaderText);
const folderMenuBtn = getMenuBtn().cloneNode(true);
folderMenuBtn.addEventListener('click', (e) => {
e.stopPropagation();
addMenu(folderMenuBtn);
});
folderHeader.appendChild(folderMenuBtn);
folderHeader.addEventListener('click', () => {
folderHeader.classList.toggle('active');
FOLDER_STATE[folderId] = folderHeader.classList.contains('active');
GM_setValue('folder_state', JSON.stringify(FOLDER_STATE));
Array.from(newFolder.children).forEach(child => {
if (child !== folderHeader) {
child.style.display = (child.style.display === 'none' ||
child.style.display === '') ? 'flex' : 'none';
}
});
});
folderHeader.draggable = true;
folderHeader.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', e.currentTarget.parentNode.id);
currentDragId = e.currentTarget.parentNode.id;
});
folderHeader.addEventListener('dragover', (e) => {
e.preventDefault();
if (isFolderId(currentDragId) && currentDragId != e.currentTarget.parentNode.id) {
const rect = e.currentTarget.getBoundingClientRect();
const isBottom = (e.clientY - rect.top) > (rect.height / 2);
e.currentTarget.parentNode.classList.remove('drop-top', 'drop-bottom');
e.currentTarget.parentNode.classList.add(isBottom ? 'drop-bottom' : 'drop-top');
}
});
folderHeader.addEventListener('dragleave', (e) => {
e.preventDefault();
if (isFolderId(currentDragId) && currentDragId != e.currentTarget.parentNode.id) {
e.currentTarget.parentNode.classList.remove('drop-top', 'drop-bottom');
}
});
folderHeader.addEventListener('drop', (e) => {
e.preventDefault();
if (isFolderId(currentDragId) && currentDragId != e.currentTarget.parentNode.id) {
const rect = e.currentTarget.getBoundingClientRect();
const isBottom = (e.clientY - rect.top) > (rect.height / 2);
e.currentTarget.parentNode.classList.remove('drop-top', 'drop-bottom');
const originalFolderId = e.dataTransfer.getData('text/plain');
const targetFolderId = e.currentTarget.parentNode.id;
const newFolderSeq = [];
FOLDER_SEQ.forEach(folderId => {
if (folderId == originalFolderId) {
} else if (folderId == targetFolderId) {
if (isBottom) {
newFolderSeq.push(targetFolderId);
newFolderSeq.push(originalFolderId);
} else {
newFolderSeq.push(originalFolderId);
newFolderSeq.push(targetFolderId);
}
} else {
newFolderSeq.push(folderId);
}
});
FOLDER_SEQ = newFolderSeq;
GM_setValue('folder_seq', JSON.stringify(FOLDER_SEQ));
const originalFolder = document.getElementById(originalFolderId);
const targetFolder = document.getElementById(targetFolderId);
originalFolder.remove();
if (isBottom) {
insertAfter(originalFolder, targetFolder);
} else {
targetFolder.parentNode.insertBefore(originalFolder, targetFolder);
}
}
});
newFolder.appendChild(folderHeader);
newFolder.addEventListener('dragover', (e) => {
e.preventDefault();
if (isChatId(currentDragId)) {
if (!currentDragId.endsWith('-copy') || currentDragId.slice(-21, -5) != folderId) {
newFolder.style.border = '1.5px solid blue';
}
}
});
newFolder.addEventListener('dragleave', (e) => {
e.preventDefault();
if (isChatId(currentDragId)) {
if (!currentDragId.endsWith('-copy') || currentDragId.slice(-21, -5) != folderId) {
newFolder.style.border = '';
}
}
});
newFolder.addEventListener('drop', (e) => {
e.preventDefault();
if (isChatId(currentDragId)) {
newFolder.style.border = '';
let chatId = e.dataTransfer.getData('text/plain');
if (chatId.endsWith('-copy')) {
chatId = chatId.slice(0, -22);
}
let inFolder = false;
Array.from(newFolder.children).forEach(child => {
if (child.id == chatId + '-' + folderId + '-copy') {
inFolder = true;
}
});
if (!inFolder) {
if (chatId in CHATS) {
CHATS[chatId].push(folderId);
} else {
CHATS[chatId] = [folderId];
}
GM_setValue('chats', JSON.stringify(CHATS));
const chatAnchorCopy = addCopyedAnchor(chatId, folderId);
chatAnchorCopy.style.display = folderHeader.classList.contains('active') ? 'flex' :'none';
newFolder.insertBefore(chatAnchorCopy, newFolder.children[1]);
}
}
});
return newFolder;
}
function addMenu(folderMenuBtn) {
document.querySelectorAll('.temp-menu').forEach(m => m.remove());
const menu = document.createElement('div');
menu.classList.add('temp-menu', 'ds-dropdown-menu', 'ds-elevated', 'ds-fade-in-zoom-in-enter', 'ds-fade-in-zoom-in-active');
menu.style.cssText = `
position: absolute;
z-index: 9999;
`;
const rect = folderMenuBtn.getBoundingClientRect();
menu.style.left = (rect.left + window.scrollX + 20) + 'px';
menu.style.top = rect.bottom + window.scrollY + 'px';
document.body.appendChild(menu);
const renameBtn = document.createElement('div');
renameBtn.classList.add('ds-dropdown-menu-option', 'ds-dropdown-menu-option--none');
renameBtn.addEventListener('click', () => {
const folderHeader = folderMenuBtn.parentNode;
const currentFolder = folderHeader.parentNode;
const folderHeaderText = folderHeader.children[0];
const folderName = prompt('重命名文件夹:', FOLDERS[currentFolder.id]);
if (folderName !== null) {
const folderId = currentFolder.id;
FOLDERS[folderId] = folderName;
GM_setValue('folders', JSON.stringify(FOLDERS));
folderHeaderText.textContent = folderName;
}
menu.remove();
});
const renameIcon = document.createElement('i');
renameIcon.className = 'fa-solid fa-pen-to-square';
renameIcon.classList.add('ds-dropdown-menu-option__icon');
renameBtn.appendChild(renameIcon);
const renameBtnText = document.createElement('div');
renameBtnText.classList.add('ds-dropdown-menu-option__label');
renameBtnText.textContent = 'Rename';
renameBtn.appendChild(renameBtnText);
menu.appendChild(renameBtn);
const deleteBtn = document.createElement('div');
deleteBtn.classList.add('ds-dropdown-menu-option', 'ds-dropdown-menu-option--error');
deleteBtn.addEventListener('click', () => {
const folderHeader = folderMenuBtn.parentNode;
const currentFolder = folderHeader.parentNode;
let result = confirm('确定删除文件夹:' + FOLDERS[currentFolder.id]);
if (result) {
const folderId = currentFolder.id;
for (let chatId in CHATS) {
CHATS[chatId] = CHATS[chatId].filter(x => x !== folderId);
}
delete FOLDERS[folderId];
delete FOLDER_STATE[folderId];
FOLDER_SEQ = FOLDER_SEQ.filter(x => x != folderId);
GM_setValue('chats', JSON.stringify(CHATS));
GM_setValue('folders', JSON.stringify(FOLDERS));
GM_setValue('folder_state', JSON.stringify(FOLDER_STATE));
GM_setValue('folder_seq', JSON.stringify(FOLDER_SEQ));
currentFolder.remove();
}
menu.remove();
});
const deleteIcon = document.createElement('i');
deleteIcon.className = 'fa-solid fa-trash';
deleteIcon.classList.add('ds-dropdown-menu-option__icon');
deleteBtn.appendChild(deleteIcon);
const deleteBtnText = document.createElement('div');
deleteBtnText.classList.add('ds-dropdown-menu-option__label');
deleteBtnText.textContent = 'Delete';
deleteBtnText.style.marginLeft = '2px';
deleteBtn.appendChild(deleteBtnText);
menu.appendChild(deleteBtn);
const removeMenu = (e) => {
if (!menu.contains(e.target) && e.target !== folderMenuBtn) {
menu.remove();
document.removeEventListener('click', removeMenu);
}
};
setTimeout(() => document.addEventListener('click', removeMenu), 0);
return menu;
}
function addCopyedAnchor(chatId, folderId) {
const chatAnchorCopy = document.getElementById(chatId).cloneNode(true);
chatAnchorCopy.draggable = true;
chatAnchorCopy.id = chatId + '-' + folderId + '-copy';
chatAnchorCopy.classList.add('chat');
chatAnchorCopy.children[1].remove();
chatAnchorCopy.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', e.target.id);
currentDragId = e.target.id;
});
chatAnchorCopy.addEventListener('click', (e) => {
e.preventDefault();
document.getElementById(chatId).click();
});
return chatAnchorCopy;
}
// 页面初始化
function initUISettings() {
const scrollArea = getScrollArea();
scrollArea.style.height = '40%';
const btnArea = addBtnArea();
scrollArea.parentNode.insertBefore(btnArea, scrollArea);
const newFolderBtn = addNewFolderBtn();
btnArea.appendChild(newFolderBtn);
const importFoldersBtn = addImportFoldersBtn();
btnArea.appendChild(importFoldersBtn);
const exportFoldersBtn = addExportFoldersBtn();
btnArea.appendChild(exportFoldersBtn);
const folderArea = addFolderArea();
scrollArea.parentNode.insertBefore(folderArea, scrollArea);
const horizontalLine = document.createElement('div');
horizontalLine.style.cssText = `
height: 0.8px;
background-color: #C0C0C0;
width: 95%;
margin: 0 auto;
margin-top: 5px;
`;
scrollArea.parentNode.insertBefore(horizontalLine, scrollArea);
scrollArea.addEventListener('dragover', (e) => {
e.preventDefault();
if (isChatId(currentDragId) && currentDragId.endsWith('-copy')) {
scrollArea.style.border = '1.5px solid blue';
}
});
scrollArea.addEventListener('dragleave', (e) => {
e.preventDefault();
if (isChatId(currentDragId) && currentDragId.endsWith('-copy')) {
scrollArea.style.border = '';
}
});
scrollArea.addEventListener('drop', (e) => {
e.preventDefault();
if (isChatId(currentDragId)) {
let chatId = e.dataTransfer.getData('text/plain');
if (chatId.endsWith('-copy')) {
scrollArea.style.border = '';
document.getElementById(chatId).remove();
const folderId = chatId.slice(-21, -5);
chatId = chatId.slice(0, -22);
CHATS[chatId] = CHATS[chatId].filter(x => x != folderId);
GM_setValue('chats', JSON.stringify(CHATS));
}
}
});
}
function setOriginalAnchorsDraggable() {
const chatAnchors = getOriginalAnchors();
chatAnchors.forEach(chatAnchor => {
chatAnchor.draggable = true;
chatAnchor.id = getChatId(chatAnchor);
chatAnchor.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', e.target.id);
currentDragId = e.target.id;
});
});
}
function initFoldersLoading() {
// FOLDER_STATE、FOLDER_SEQ都与FOLDER保持一致。
const folderArea = document.getElementById('folder-area');
for (let folderId in FOLDERS) {
if (!(folderId in FOLDER_STATE)) {
FOLDER_STATE[folderId] = false;
}
}
const removedFolderState = [];
for (let folderId in FOLDER_STATE) {
if (!(folderId in FOLDERS)) {
removedFolderState.push(folderId);
}
}
removedFolderState.forEach(folderId => delete FOLDER_STATE[folderId]);
for (let folderId in FOLDERS) {
if (!FOLDER_SEQ.includes(folderId)) {
FOLDER_SEQ.push(folderId);
}
}
FOLDER_SEQ = [...new Set(FOLDER_SEQ)];
const removedFolderSeq = [];
FOLDER_SEQ.forEach(folderId => {
if (folderId in FOLDERS) {
const newFolder = addNewFolder(FOLDERS[folderId], folderId);
const folderHeader = newFolder.children[0];
folderHeader.classList.toggle('active', FOLDER_STATE[folderId]);
folderArea.appendChild(newFolder);
} else {
removedFolderSeq.push(folderId);
}
});
removedFolderSeq.forEach(folderId => {
FOLDER_SEQ = FOLDER_SEQ.filter(x => x != folderId);
});
GM_setValue('folder_state', JSON.stringify(FOLDER_STATE));
GM_setValue('folder_seq', JSON.stringify(FOLDER_SEQ));
}
function initAnchorsLoading() {
const removedChatIds = [];
for (let chatId in CHATS) {
if (!document.getElementById(chatId)) {
removedChatIds.push(chatId);
}
}
const chatAnchors = getOriginalAnchors();
chatAnchors.forEach(chatAnchor => {
const chatId = getChatId(chatAnchor);
if (chatId in CHATS) {
const belongFolders = CHATS[chatId];
const activeFolders = [];
belongFolders.forEach(folderId => {
if (document.getElementById(folderId)) {
activeFolders.push(folderId);
const belongFolder = document.getElementById(folderId);
const folderHeader = belongFolder.children[0];
let inFolder = false;
Array.from(belongFolder.children).forEach(child => {
if (child.id == chatId + '-' + folderId + '-copy') {
inFolder = true;
}
});
if (!inFolder) {
const chatAnchorCopy = addCopyedAnchor(chatId, folderId);
chatAnchorCopy.style.display = folderHeader.classList.contains('active') ? 'flex' :'none';
belongFolder.appendChild(chatAnchorCopy);
}
}
});
CHATS[chatId] = activeFolders;
}
});
removedChatIds.forEach(chatId => delete CHATS[chatId]);
GM_setValue('chats', JSON.stringify(CHATS));
}
function observeScrollArea () {
const scrollArea = getScrollArea();
const observer = new MutationObserver((mutationList) => {
for (const mutation of mutationList) {
if (mutation.type !== "childList") continue;
/* eslint-disable no-loop-func */
mutation.addedNodes.forEach((node) => {
if (node.nodeType !== 1) return;
let chatAnchor = null;
if (node.tagName === "A") {
chatAnchor = node;
} else {
chatAnchor = node.querySelector("a");
}
if (chatAnchor) {
chatAnchor.draggable = true;
chatAnchor.id = getChatId(chatAnchor);
chatAnchor.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', e.target.id);
currentDragId = e.target.id;
});
}
});
mutation.removedNodes.forEach((node) => {
if (node.nodeType !== 1) return;
let chatAnchor = null;
if (node.tagName === "A") {
chatAnchor = node;
} else {
chatAnchor = node.querySelector("a");
}
if (chatAnchor) {
const chatId = getChatId(chatAnchor);
delete CHATS[chatId];
GM_setValue('chats', JSON.stringify(CHATS));
for (let folderId in FOLDERS) {
if (document.getElementById(chatId + '-' + folderId + '-copy')) {
document.getElementById(chatId + '-' + folderId + '-copy').remove();
}
}
}
});
}
});
observer.observe(scrollArea, {
childList: true,
subtree: true
});
}
function listenDomain() {
function updateSelectedState() {
const chatId = extractIdFromUrl(location.href);
const copyedAnchors = document.getElementById('folder-area').querySelectorAll('a[href^="/a/chat/s/"]');
copyedAnchors.forEach(anchor => {
anchor.classList.remove(getAnchorSelectedClass());
});
if (chatId) {
const selectedCopyedAnchors = document.getElementById('folder-area').querySelectorAll(`a[href="/a/chat/s/${chatId}"]`);
selectedCopyedAnchors.forEach(anchor => {
anchor.classList.add(getAnchorSelectedClass());
});
}
}
window.addEventListener("popstate", updateSelectedState);
window.addEventListener("hashchange", updateSelectedState);
["pushState", "replaceState"].forEach(fn => {
const orig = history[fn];
history[fn] = function (...args) {
const ret = orig.apply(this, args);
updateSelectedState();
return ret;
};
});
updateSelectedState();
}
function main() {
addCSSClass();
waitFor(existChatAnchors, () => {
initUISettings();
setOriginalAnchorsDraggable();
initFoldersLoading();
initAnchorsLoading();
observeScrollArea();
listenDomain();
});
}
main();
})();