为csp的素材商店网页-我的下载页面 增加“按素材类型排序”和按素材类型筛选快捷按钮
当前为
// ==UserScript==
// @name ecsa
// @namespace boni
// @version 1.09
// @description 为csp的素材商店网页-我的下载页面 增加“按素材类型排序”和按素材类型筛选快捷按钮
// @match https://assets.clip-studio.com/*/download-list
// @match https://assets.clip-studio.com/*/download-list?*
// @match https://assets.clip-studio.com/*/starred*
// @grant none
// @license GPL-3.0-only
// @description:zh 为csp的素材商店网页-我的下载页面 增加“按素材类型排序”和按素材类型筛选快捷按钮
// @description:en Support sorting and filtering on Clip Studio Assets favorites and downloads page
// @description:ja Clip Studio Assetsのマイリストとマイダウンロードページでのソートとフィルタリングをサポート
// @description:de Für die Favoriten und Downloads Seite von Clip Studio Assets Unterstützung für das Sortieren und Filtern hinzufügen
// @description:es Agregar soporte para ordenar y filtrar en la página de favoritos y descargas de Clip Studio Assets
// @description:fr Ajouter la prise en charge du tri et du filtrage sur la page des favoris et des téléchargements de Clip Studio Assets
// @description:ko Clip Studio Assets의 즐겨찾기 및 다운로드 페이지에서 정렬 및 필터링 지원
// ==/UserScript==
(function() {
'use strict';
const getSortBtnLabel = () => {
// Get the current URL
const currentURL = window.location.href;
const withoutProtocol = currentURL.replace("https://", "");
// Split by "/"
const urlSegments = withoutProtocol.split("/");
// Get the first part
const lang = urlSegments[1];
const translations = {
"zh-tw": {
category: "按素材类别排序",
time: "按下载时间排序",
},
"ja-jp": {
category: "素材タイプ別に並べ替え",
time: "ダウンロード時間別に並べ替え",
},
"en-us": {
category: "Sort by Category",
time: "Sort by Download Time"
},
"de-de": {
category: "Nach Kategorie sortieren",
time: "Nach Download-Zeit sortieren"
},
"es-es": {
category: "Ordenar por categoría",
time: "Ordenar por tiempo de descarga"
},
"fr-fr": {
category: "Trier par catégorie",
time: "Trier par heure de téléchargement"
},
"ko-kr": {
category: "카테고리별 정렬",
time: "다운로드 시간별 정렬"
}
};
return translations[lang]
}
// text for "all" option
const getAllText = () => {
if (window.location.href.includes("starred")) {
// Find the first <a> element inside the .btn-group.selectFilter
const selectFilter = document.querySelector('.btn-group.selectFilter');
if (selectFilter) {
const firstOption = selectFilter.querySelector('a');
if (firstOption) {
const firstOptionText = firstOption.textContent.trim();
return firstOptionText
}
}
} else {
// Find the <ul> element inside the .dropdown.selectFilter
const dropdown = document.querySelector('.dropdown.selectFilter');
if (dropdown) {
const ul = dropdown.querySelector('ul.dropdown-menu');
if (ul) {
const firstOption = ul.querySelector('li:first-child a');
if (firstOption) {
const firstOptionText = firstOption.textContent.trim();
return firstOptionText
}
}
}
}
}
// Define liElementsByType in the global scope
const liElementsByType = {};
let container = document.querySelector("ul.layput__cardPanel");
let sortAsset = false;
let orig = container.innerHTML;
let types = []
let allText = getAllText()
let sortBtnText = getSortBtnLabel()
let currentLocation = ''
if (window.location.href.includes("starred")) {
currentLocation = 's'
} else {
currentLocation = 'd'
}
const toggleSort = (sort) => {
// Set a value in localStorage
localStorage.setItem( currentLocation +'sorted', sort === true ? 1 : 0);
sortAsset = sort
const sortButton = document.getElementById("sortButton");
sortButton.textContent = sortAsset ? sortBtnText.time : sortBtnText.category;
// sortButton.disabled = type !== allText;
if (sort) {
// Clear the existing content on the page
container.innerHTML = '';
// Sort the <li> elements by type value (custom sorting logic)
const sortedTypes = Object.keys(liElementsByType).sort();
// Reconstruct the sorted list of <li> elements
const sortedLiElements = [];
sortedTypes.forEach((type) => {
sortedLiElements.push(...liElementsByType[type]);
});
// Append the sorted <li> elements back to the container
sortedLiElements.forEach((li) => {
container.appendChild(li);
});
} else {
container.innerHTML = orig;
}
}
// Function to sort the <li> elements by type
const preprocessAssets = () => {
const liElements = document.querySelectorAll("li.materialCard");
liElements.forEach((li) => {
const materialTypeLink = li.querySelector("a[href*='/search?type=']");
if (materialTypeLink) {
const type = materialTypeLink.textContent.trim(); // Get the text content of the <a> tag
if (!types.includes(type)) {
types.push(type)
}
if (type) {
if (!liElementsByType[type]) {
liElementsByType[type] = [];
}
liElementsByType[type].push(li);
}
}
});
// Find the existing button element
const existingButton = document.querySelector(".btn.btn-default.operationButton.favoriteButton");
if (existingButton) {
// Create a new button element
const sortButton = document.createElement("button");
sortButton.type = "button";
sortButton.className = "btn btn-primary ";
sortButton.id = "sortButton";
sortButton.textContent = sortBtnText.category;
sortButton.style.marginLeft = '10px'
// Add an event listener to the new button if needed
sortButton.addEventListener("click", function() {
// Handle button click event
sortAsset = !sortAsset
sortButton.textContent = sortAsset ? sortBtnText.time : sortBtnText.category;
toggleSort(sortAsset)
});
// Insert the new button after the existing button
existingButton.parentNode.insertBefore(sortButton, existingButton.nextSibling);
const options = [...types];
options.unshift(allText)
const dropdown = createDropdown(options);
existingButton.parentNode.insertBefore(dropdown, sortButton.nextSibling);
}
const filterBtn = document.getElementById("filterButton");
if(filterBtn.textContent === getAllText()) {
// Read a value from localStorage
const sorted = localStorage.getItem(currentLocation + 'sorted');
// Check if the value exists
if (sorted == 1) {
// Use the value
toggleSort(true)
} else {
}
}
};
// Create a function to generate the dropdown HTML
function createDropdown(types) {
const dropdown = document.createElement("div");
dropdown.className = "dropdown selectFilter ";
dropdown.style.display = 'inline-block'
dropdown.style.marginLeft = '10px'
dropdown.style.marginTop = '0px'
const button = document.createElement("button");
button.className = "btn btn-default dropdown-toggle filterButton";
button.id = "filterButton"
button.type = "button";
button.setAttribute("data-toggle", "dropdown");
button.setAttribute("aria-haspopup", "true");
button.setAttribute("aria-expanded", "true");
const filterOption = localStorage.getItem(currentLocation + 'filtered');
// set sort button text but only allow change when 'all' option is selected
const sorted = localStorage.getItem(currentLocation +'sorted');
sortButton.textContent = sorted ? sortBtnText.time : sortBtnText.category;
// toggleSort()
if( types.includes(filterOption) && filterOption !== getAllText() ) {
const sortButton = document.getElementById("sortButton");
// sortButton.textContent = sorted ? sortBtnText.time : sortBtnText.category;
sortButton.disabled = true
button.textContent =filterOption
container.innerHTML = '';
liElementsByType[filterOption].forEach((li) => {
container.appendChild(li);
});
} else {
button.textContent = types[0]; // Set the default text
}
button.style.borderRadius = '0px'
button.style.textAlign = 'left'
const caret = document.createElement("span");
caret.className = "caret";
caret.style.position = "absolute";
if (window.location.href.includes("starred")) {
// The URL contains "starred"
caret.style.top = "15px"
} else {
// The URL does not contain "starred"
}
caret.style.right = "10px";
const ul = document.createElement("ul");
ul.className = "dropdown-menu";
// Create options from the 'types' array
types.forEach((type) => {
const li = document.createElement("li");
const a = document.createElement("a");
a.textContent = type;
li.appendChild(a);
ul.appendChild(li);
li.addEventListener("click", function(event) {
localStorage.setItem(currentLocation + 'filtered', type);
// Prevent the default behavior of following the link (if it's an anchor)
event.preventDefault();
container.innerHTML = '';
// Enable or disable the new button based on the selected option
const sortButton = document.getElementById("sortButton");
sortButton.disabled = type !== allText;
button.firstChild.textContent = type;
const h4Element = document.querySelector("h4.text-right");
if (type !== allText) {
liElementsByType[type].forEach((li) => {
container.appendChild(li);
});
localStorage.setItem(currentLocation +'filtered', type);
} else {
container.innerHTML = orig;
const sorted = localStorage.getItem(currentLocation + 'sorted');
// Check if the value exists
if (sorted == 1) {
// Use the value
toggleSort(true)
} else {
}
}
});
});
// Append elements to the dropdown
button.appendChild(caret);
dropdown.appendChild(button);
dropdown.appendChild(ul);
return dropdown;
}
// Wait for the page to fully load before executing the sorting function
window.onload = function() {
preprocessAssets();
};
})();