您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Save your filters from the Latest Update Page & load them when you need it!
// ==UserScript== // @name F95 Latest Update Saver // @namespace 1330126-edexal // @match *://f95zone.to/sam/latest_alpha/* // @grant GM.setValue // @grant GM.getValue // @grant GM.deleteValue // @grant GM.listValues // @icon https://external-content.duckduckgo.com/ip3/f95zone.to.ico // @license Unlicense // @version 2.0 // @author Edexal // @description Save your filters from the Latest Update Page & load them when you need it! // ==/UserScript== (async function () { /*NOTE: F95 uses FontAwesome v5.15.4*/ const storageKeys = { A: "Slot A", B: "Slot B", C: "Slot C", D: "Slot D", LastSlot: "LastSlot", CanAutoLoad: "CanAutoLoad" }; //Apply custom styles in a style tag function applyCSS(css) { let styleEl = document.querySelector("style"); if (styleEl === null) { styleEl = document.createElement('style'); } styleEl.appendChild(document.createTextNode(css)); document.head.appendChild(styleEl); } function getStyles() { return ` @keyframes notice { 0% {opacity:0;} 30% {opacity:1;} 60% {opacity:1;} 100% {opacity:0;}; } #save-notice { position: fixed; z-index: 8; top: 33%; left: 40vw; background-color:#2d2d2d; color: yellow; border-radius: 10px; border: 2pt outset #6ce65b; box-shadow: -1px 0px 5px #cece92; width: 120px; padding-top:15px; padding-bottom:15px; font-size: 18px; font-weight:bold; text-align:center; opacity: 0; } .save-anim { animation: 3s notice ease-in-out; } .save-bg { opacity: 0.6; } #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_SlotA a::before, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_SlotB a::before, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_SlotC a::before, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_SlotD a::before { color: orange !important; } #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_SlotA a:not(.filter-selected).has-save::before, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_SlotB a:not(.filter-selected).has-save::before, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_SlotC a:not(.filter-selected).has-save::before, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_SlotD a:not(.filter-selected).has-save::before { color: #8cf048 !important; } #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_SlotA a.filter-selected::before, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_SlotB a.filter-selected::before, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_SlotC a.filter-selected::before, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_SlotD a.filter-selected::before, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_Load a::before, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_Save a::before, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_Delete a::before, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_Auto-Load a::before{ color: yellow !important; } #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings a.filter-selected::before, #btn-settings_Delete a:active, #btn-settings_Load a:active, #btn-settings_Save a:active, #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings a.auto-selected::before { background-color: #641c1c !important; } #btn-settings_Delete a:active, #btn-settings_Load a:active, #btn-settings_Save a:active { opacity: 0.6; } #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_Save a { border-right: 2px solid #ffe722; } #latest-page_filter-wrap #latest-page_filter-wrap_inner #filter-block_settings #btn-settings_Auto-Load a { border-left: 2px solid #ffe722; } div#filter-block_settings h4 { color: #fc9b46 !important; } `; } function addSaveNotice() { let notice = document.createElement('div'); notice.id = 'save-notice'; let txtNode = document.createTextNode('Saved!'); notice.append(txtNode); document.body.append(notice); applyCSS(getStyles()); } function createSection() { let section = document.createElement('div'); section.id = 'filter-block_settings'; section.classList.add('filter-block'); return section; } function createHeader() { let h = document.createElement('h4'); h.classList.add('filter-block_title'); let txtNode = document.createTextNode('Settings'); h.append(txtNode); return h; } function createSectWrap() { let outerContainer = document.createElement('div'); outerContainer.classList.add('filter-block_content', 'filter-block_h'); return outerContainer; } //Utility function for creating buttons function createBtn(name, eventFunc, classNames) { let innerContainer = document.createElement('div'); innerContainer.id = `btn-settings_${name.replace(/ /, "")}`; innerContainer.classList.add('filter-block_button-wrap'); let a = document.createElement('a'); a.href = "#"; a.setAttribute('data-settings', name); a.classList.add('filter-block_button'); if (!!classNames) { a.classList.add(...classNames); } a.addEventListener('click', eventFunc); let label = document.createElement('div'); label.classList.add('filter-block_button-label'); let labelTxtNode = document.createTextNode(`${name[0].toUpperCase()}${name.substring(1)}`); label.append(labelTxtNode); innerContainer.append(a, label); return innerContainer; } function getSelectedSlot() { return document.querySelector("#filter-block_settings a.filter-selected"); } function getSlotByName(name) { return document.querySelector(`[data-settings="${name}"]`); } function addHasSaveStyle(slot) { slot.classList.add('has-save'); } function addAutoLoadStyle() { const autoBtn = document.querySelector('#btn-settings_Auto-Load a'); autoBtn.classList.add('auto-selected'); } function removeHasSaveStyle(slot) { slot.classList.remove('has-save'); } function removeAutoLoadStyle() { const autoBtn = document.querySelector('#btn-settings_Auto-Load a'); autoBtn.classList.remove('auto-selected'); } function saveEvent(e) { e.preventDefault(); let chosenSlot = getSelectedSlot(); if (!!!chosenSlot) { return; } GM.setValue(chosenSlot.dataset.settings, location.href); addHasSaveStyle(chosenSlot); let saveNotice = document.querySelector('#save-notice'); let saveNoticeBG = document.querySelector('#top'); if (!!!saveNotice.classList.contains('save-anim')) { saveNotice.classList.add('save-anim'); saveNoticeBG.classList.add('save-bg'); setTimeout(() => { saveNotice.classList.remove('save-anim'); saveNoticeBG.classList.remove('save-bg'); }, 3000) } } async function loadAsyncEvent(e) { e.preventDefault(); try { let chosenSlot = getSelectedSlot(); if (!!chosenSlot) { let url = await GM.getValue(chosenSlot.dataset.settings); if (!!url) { location.href = url; } } } catch (err) { console.error(err); } } function slotSelectEvent(e) { e.preventDefault(); const classAtrribute = 'filter-selected'; const currentSlot = getSelectedSlot(); if (!!currentSlot && currentSlot.dataset.settings !== e.target.dataset.settings) { currentSlot.classList.remove(classAtrribute); } e.target.classList.add(classAtrribute); GM.setValue(storageKeys.LastSlot, e.target.dataset.settings); } function deleteEvent(e) { e.preventDefault(); const slot = getSelectedSlot(); if (!!slot) { GM.deleteValue(slot.dataset.settings); removeHasSaveStyle(slot); } } async function autoLoadEvent(e) { e.preventDefault(); const canAutoLoad = await GM.getValue(storageKeys.CanAutoLoad); GM.setValue(storageKeys.CanAutoLoad, !!!canAutoLoad); if (canAutoLoad) { removeAutoLoadStyle(); } else { addAutoLoadStyle(); } } function createBtns(names, eventFunc, classNames) { let buttons = []; for (let i = 0; i < names.length; i++) { buttons.push(createBtn(names[i], eventFunc, classNames)); } return buttons; } async function initHasSave() { let saveSlotNames = await GM.listValues(); const excludeList = Object.keys(storageKeys).slice(4); saveSlotNames = saveSlotNames.filter(name => !excludeList.includes(name)); for (const slotName of saveSlotNames) { let saveSlot = getSlotByName(slotName); addHasSaveStyle(saveSlot); } } async function initAutoLoad() { const canAutoLoad = await GM.getValue(storageKeys.CanAutoLoad); if (!!!canAutoLoad) { return; } const lastSlotName = await GM.getValue(storageKeys.LastSlot); if (!!lastSlotName) { const slot = getSlotByName(lastSlotName); slot.click(); const loadBtn = document.querySelector('#btn-settings_Load a'); loadBtn.click(); } addAutoLoadStyle(); } function getSettingsSect() { let settingsSect = createSection(); let header = createHeader(); let contentWrap = createSectWrap(); let btnList = [createBtn('Load', loadAsyncEvent, ['fas', 'fa-upload']), createBtn('Save', saveEvent, ['fas', 'fa-save'])]; btnList.push(...createBtns([storageKeys.A, storageKeys.B, storageKeys.C, storageKeys.D], slotSelectEvent, ['fas', 'fa-hdd'])); btnList.push(createBtn('Auto-Load', autoLoadEvent, ['fas', 'fa-magic'])); btnList.push(createBtn('Delete', deleteEvent, ['fas', 'fa-trash-alt'])); contentWrap.append(...btnList); settingsSect.append(header, contentWrap); return settingsSect; } function addSettingsSect() { let titleEl = document.querySelector('.content-block_filter-title'); titleEl.after(getSettingsSect()); addSaveNotice(); } addSettingsSect(); initHasSave(); initAutoLoad(); })().catch(err => console.error(err));