import { DataPaging, DOMUtils, log, pops, utils } from "@/env"; import { NetDiskRegularExtractor } from "@/main/NetDiskRegularExtractor"; import { NetDiskGlobalData } from "@/main/data/NetDiskGlobalData"; import { NetDiskPops } from "@/main/pops/NetDiskPops"; import { NetDiskViewRightClickMenu } from "@/main/view/NetDiskViewRightClickMenu"; import { GM_getValue, GM_setValue } from "ViteGM"; import { NetDiskView } from "../NetDiskView"; import { NetDiskLinkView } from "../link-view/NetDiskLinkView"; import { NetDiskLinkViewEvent } from "../link-view/NetDiskLinkViewEvent"; import indexCSS from "./index.css?raw"; export const NetDiskHistoryMatchView = { /** * 本地存储的keyName */ storageKey: "netDiskHistoryMatch", /** * 是否已设置其它DOM事件 */ isSetOtherEvent: false, /** * 分页 */ dataPaging: void 0 as any as (typeof DataPaging)["prototype"], /** * 显示弹窗 */ show() { let data = this.getStorageData(); let dataHTML = ""; data = this.orderNetDiskHistoryMatchData(data); dataHTML = /*html*/ `
`; NetDiskView.$el.$historyView = NetDiskPops.confirm( { title: { text: "历史匹配记录", position: "center", }, content: { text: dataHTML, html: true, }, btn: { reverse: true, position: "space-between", close: { callback: () => { this.destory(); }, }, ok: { enable: false, callback: () => { this.destory(); }, }, cancel: { enable: true, text: "关闭", callback: () => { this.destory(); }, }, other: { enable: true, text: `清空所有(${data.length})`, type: "xiaomi-primary", callback: () => { NetDiskPops.confirm({ title: { text: "删除", position: "center", }, content: { text: "确定清空所有的记录?", html: false, }, btn: { ok: { enable: true, callback: (clearAllDialog) => { this.clearStorageData(); this.clearLinkElements(); this.clearPageNavigator(); clearAllDialog.close(); const $recordPage = NetDiskView.$el.$historyView.$shadowRoot.querySelector(".netdiskrecord-page")!; const $btnOther = NetDiskView.$el.$historyView.$shadowRoot.querySelector(".pops-confirm-btn-other")!; DOMUtils.html($recordPage, ""); DOMUtils.text($btnOther, DOMUtils.text($btnOther).replace(/[\d]+/gi, "0")); }, }, cancel: { text: "取消", enable: true, }, }, }); }, }, }, mask: { clickEvent: { toClose: false, }, clickCallBack: () => { this.destory(); }, }, class: "whitesevPopNetDiskHistoryMatch", style: indexCSS, }, NetDiskView.$config.viewSizeConfig.historyMatchView ); this.addLinkElements(data.slice(0, 9)); this.setDataPaging(data); this.setEvent(NetDiskView.$el.$historyView.$shadowRoot); this.setSearchEvent(); NetDiskViewRightClickMenu.setRightClickMenu( NetDiskView.$el.$historyView.$shadowRoot.querySelector(".whitesevPopNetDiskHistoryMatch")!, ".netdiskrecord-link a", true ); }, /** * 销毁弹窗 */ destory() { NetDiskView.$el.$historyView?.close(); // @ts-expect-error NetDiskView.$el.$historyView = void 0; }, /** * 获取链接项的容器 */ getLinkContainer() { let $linkContainer = NetDiskView.$el.$historyView.$shadowRoot.querySelector(".netdiskrecord-table ul")!; return $linkContainer; }, /** * 添加链接元素 */ addLinkElements(data: NetDiskHistoryDataOption | NetDiskHistoryDataOption[]) { if (!Array.isArray(data)) { data = [data]; } let documentFragment = document.createDocumentFragment(); for (let index = 0; index < data.length; index++) { let dataItem = data[index]; let $item = this.createLinkItemElementInfo(dataItem); documentFragment.appendChild($item.$liItemContainer); } let $linkContainer = this.getLinkContainer(); $linkContainer.appendChild(documentFragment); }, /** * 获取显示出的每一项的信息 * @param data */ createLinkItemElementInfo(data: NetDiskHistoryDataOption) { /** 获取处理后的显示的链接 */ let uiLink = NetDiskRegularExtractor.extractShowLink({ ruleKeyName: data.ruleKeyName, ruleIndex: data.ruleIndex, shareCode: data.shareCode, accessCode: data.accessCode, matchText: data.matchText, }); let $liItemContainer = DOMUtils.createElement("li", { innerHTML: /*html*/ `

网盘

网址

${data.url}

网址标题

${data.title}

记录时间

${utils.formatTime(data.addTime)}

更新时间

${utils.formatTime(data.updateTime)}

功能

`, }); let $link = $liItemContainer.querySelector(".netdiskrecord-link")!; let $linkAnchor = $link.querySelector("a")!; let $icon = $liItemContainer.querySelector(".netdiskrecord-icon"); let $iconImg = $liItemContainer!.querySelector(".netdisk-icon-img")!; let $url = $liItemContainer.querySelector(".netdiskrecord-url")!; let $urlTitle = $liItemContainer.querySelector(".netdiskrecord-url-title")!; let $addTime = $liItemContainer.querySelector(".netdiskrecord-add-time"); let $updateTime = $liItemContainer.querySelector(".netdiskrecord-update-time")!; let $features = $liItemContainer.querySelector(".netdiskrecord-functions"); let $featuresBtnDelete = $features!.querySelector(".btn-delete")!; NetDiskLinkView.handleBoxAttrRuleInfo( { ruleKeyName: data.ruleKeyName, ruleIndex: data.ruleIndex, shareCode: data.shareCode, accessCode: data.accessCode, }, $linkAnchor ); $iconImg.style.cssText = `background: url(${NetDiskView.$inst.icon.getIcon(data.ruleKeyName)}) no-repeat;background-size:100%`; if (data.url !== data.topURL) { // 添加top信息 let $topUrl = DOMUtils.createElement("div", { className: "netdiskrecord-top-url", innerHTML: /*html*/ `

Top网址

${data.topURL} `, }); DOMUtils.after($url, $topUrl); } $featuresBtnDelete.setAttribute("data-json", JSON.stringify(data)); Reflect.set($featuresBtnDelete, "data-json", data); return { $liItemContainer, $link, $linkAnchor, $icon, $iconImg, $url, $urlTitle, $addTime, $updateTime, $features, $featuresBtnDelete, html: $liItemContainer.outerHTML, }; }, /** * 清空链接元素 */ clearLinkElements() { let $liItemContainer = this.getLinkContainer(); DOMUtils.empty($liItemContainer); $liItemContainer.scrollTo(0, 0); }, /** * 清空分页元素 */ clearPageNavigator() { DOMUtils.remove(NetDiskView.$el.$historyView.$shadowRoot.querySelectorAll(".netdiskrecord-page > *")); }, /** * 设置只执行一次的事件 * @param target */ setEvent(target: HTMLElement | ShadowRoot) { let that = this; NetDiskLinkViewEvent.setNetDiskUrlClickEvent(target, ".netdiskrecord-link a"); /** * 设置删除按钮点击事件 */ DOMUtils.on(target, "click", ".netdiskrecord-functions button.btn-delete", function (event) { let $btnOther = target.querySelector(".pops-confirm-btn-other")!; // 删除中的遮罩层 let deleteLoading = NetDiskPops.loading({ $parent: that.getLinkContainer(), content: { text: "删除中...", }, only: true, addIndexCSS: false, }); let clickNode = event.target as HTMLElement; let dataJSON = clickNode.getAttribute("data-json")!; clickNode.closest("li")?.remove(); that.deleteStorageData(dataJSON); deleteLoading?.close(); let totalNumberText = DOMUtils.text($btnOther); let totalNumberMatch = totalNumberText.match(/[\d]+/gi)!; let totalNumber = parseInt(totalNumberMatch[totalNumberMatch.length - 1]); totalNumber--; totalNumberText = totalNumberText.replace(/[\d]+/gi, totalNumber.toString()); DOMUtils.text($btnOther, totalNumberText); let data = that.getStorageData(); data = that.orderNetDiskHistoryMatchData(data); that.dataPaging.refresh(data); that.pageChangeCallBack(data, that.dataPaging.CONFIG.currentPage); }); }, /** * 页码改变的回调 * @param data * @param page */ pageChangeCallBack(data: NetDiskHistoryDataOption[], page: number) { let startIndex = (page - 1) * 10; let startData = data.slice(startIndex, startIndex + 9); this.clearLinkElements(); this.addLinkElements(startData); }, /** * 设置分页 * @param data */ setDataPaging(data: NetDiskHistoryDataOption[]) { let that = this; let dataPaging = new DataPaging({ data: data, pageShowDataMaxCount: 10, pageMaxStep: pops.isPhone() ? 2 : 4, currentPage: 1, pageChangeCallBack: function (page) { that.pageChangeCallBack(data, page); }, }); this.dataPaging = dataPaging; dataPaging.addCSS(NetDiskView.$el.$historyView.$shadowRoot); const $paginationWrapper = NetDiskView.$el.$historyView.$shadowRoot.querySelector( ".whitesevPopNetDiskHistoryMatch .netdiskrecord-page" )!; dataPaging.append($paginationWrapper); }, /** * 设置搜索框的回车事件 */ setSearchEvent() { let isSeaching = false; // 当前搜索的状态 let $searchLoading = void 0 as undefined | ReturnType<(typeof NetDiskPops)["loading"]>; // 搜索中的遮罩层 let that = this; function searchEvent() { if (isSeaching) { return; } isSeaching = true; $searchLoading = NetDiskPops.loading({ $parent: that.getLinkContainer(), content: { text: "搜索中...", }, only: true, addIndexCSS: false, }); let searchText = NetDiskView.$el.$historyView.$shadowRoot .querySelector(".whitesevPopNetDiskHistoryMatch .netdiskrecord-search input")! .value.trim(); let data = that.getStorageData(); data = that.orderNetDiskHistoryMatchData(data); if (searchText === "") { // 输入空就关闭遮罩层且恢复style that.clearLinkElements(); that.clearPageNavigator(); that.addLinkElements(data.slice(0, 9)); $searchLoading?.close(); isSeaching = false; that.setDataPaging(data); return; } log.info(`历史匹配记录-搜索:` + searchText); /** 搜索到的链接 */ let searchData = data.filter((dataOption) => { let uiLink = NetDiskRegularExtractor.extractShowLink({ ruleKeyName: dataOption.ruleKeyName, ruleIndex: dataOption.ruleIndex, shareCode: dataOption.shareCode, accessCode: dataOption.accessCode, matchText: dataOption.matchText, showToast: false, }); if (!uiLink) { log.info(dataOption); } let searchTextRegExp = utils.toRegExp(searchText, "i"); if ( (typeof uiLink === "string" && uiLink.match(searchTextRegExp)) || dataOption.shareCode.match(searchTextRegExp) || dataOption.url.match(searchTextRegExp) || dataOption.topURL.match(searchTextRegExp) || dataOption.title.match(searchTextRegExp) ) { // 匹配到 return true; } }); that.clearLinkElements(); that.clearPageNavigator(); that.addLinkElements(searchData); $searchLoading?.close(); $searchLoading = void 0; isSeaching = false; } DOMUtils.onKeyboard( NetDiskView.$el.$historyView.$shadowRoot.querySelector( ".whitesevPopNetDiskHistoryMatch .netdiskrecord-search input" )!, "keyup", (keyName) => { if (keyName === "Enter") { searchEvent(); } } ); }, /** * 排序数据 * @param data */ orderNetDiskHistoryMatchData(data: NetDiskHistoryDataOption[]) { let localOrder = NetDiskGlobalData.historyMatch["netdisk-history-match-ordering-rule"].value; let isDesc = localOrder.indexOf("降序") !== -1 ? true : false; // 降序 let orderField = localOrder.indexOf("记录时间") !== -1 ? "addTime" : "updateTime"; // 排序字段 utils.sortListByProperty( data, (item) => { return item[orderField as keyof NetDiskHistoryDataOption]!; }, isDesc ); return data; }, /** * 查询访问码 * @param ruleKeyName * @param shareCode * @param isNotNull 查询的访问码是否不为空 * + true 不能是空的 * + false 允许为空 */ queryAccessCode(ruleKeyName: string, shareCode: string, isNotNull: boolean) { let storageDataList = this.getStorageData(); for (let index = 0; index < storageDataList.length; index++) { const localData = storageDataList[index]; if (localData.ruleKeyName === ruleKeyName && localData.shareCode === shareCode) { if (isNotNull && utils.isNotNull(localData.accessCode)) { // 不要空的 return localData.accessCode; } return localData.accessCode; } } }, /** * 同步访问码 * @param ruleKeyName 规则名称 * @param ruleIndex 规则的索引下标 * @param shareCode 分享码 * @param accessCode 新的访问码 */ syncAccessCode(ruleKeyName: string, ruleIndex: number, shareCode: string, accessCode: AccessCodeType) { if (NetDiskGlobalData.historyMatch.saveMatchNetDisk.value) { let flag = NetDiskHistoryMatchView.changeMatchedDataAccessCode(ruleKeyName, ruleIndex, shareCode, accessCode); if (flag) { log.success("已成功同步访问码至历史匹配记录"); return true; } else { log.error("同步访问码至历史匹配记录失败"); } } return false; }, /** * 修改存储的数据的访问码 * @param ruleKeyName 规则名称 * @param ruleIndex 规则的索引下标 * @param shareCode 分享码 * @param accessCode 新的访问码 */ changeMatchedDataAccessCode(ruleKeyName: string, ruleIndex: number, shareCode: string, accessCode: AccessCodeType) { let storageDataList = this.getStorageData(); let flag = false; for (let index = 0; index < storageDataList.length; index++) { const localData = storageDataList[index]; if ( localData.ruleKeyName === ruleKeyName && String(localData.ruleIndex) === String(ruleIndex) && localData.shareCode === shareCode ) { flag = true; storageDataList[index].accessCode = accessCode; storageDataList[index].updateTime = Date.now(); } } if (flag) { this.saveStorageData(storageDataList); } return flag; }, /** * 存储匹配到的链接 * @param ruleKeyName 规则名称 * @param ruleIndex 规则的索引下标 * @param shareCode 分享码 * @param accessCode 访问码 * @param matchText 匹配到的文本 */ changeMatchedData( ruleKeyName: string, ruleIndex: number, shareCode: string, accessCode: AccessCodeType, matchText: string ) { if (!NetDiskGlobalData.historyMatch.saveMatchNetDisk.value) { return false; } let storageDataList = this.getStorageData(); let flag = false; // 先从已有的数据中查找是否存在相同的 // 有的话修改,没有的话添加新的 for (let index = 0; index < storageDataList.length; index++) { const localData = storageDataList[index]; // 按照匹配的网址的区分的 if ( localData.ruleKeyName === ruleKeyName && shareCode.startsWith(localData.shareCode) && localData.ruleIndex === ruleIndex ) { if ( NetDiskGlobalData.historyMatch["netdisk-history-match-merge-same-link"].value || (localData.url === window.location.href && localData.topURL === top!.window.location.href) ) { flag = true; let editFlag = false; if (matchText.trim() !== "" && localData.matchText !== matchText) { // 修改/设置新的matchText editFlag = true; log.success("匹配历史记录 -> 设置新的matchText", [matchText]); storageDataList[index].matchText = matchText; } if (utils.isNotNull(accessCode) && localData.accessCode !== accessCode) { // 修改accessCode editFlag = true; log.success("匹配历史记录 -> 修改accessCode"); storageDataList[index].accessCode = accessCode; } if (editFlag) { storageDataList[index].updateTime = Date.now(); if (storageDataList[index].title) { storageDataList[index].title = document.title; } if (NetDiskGlobalData.historyMatch["netdisk-history-match-merge-same-link"].value) { storageDataList[index].url = window.location.href; storageDataList[index].topURL = top!.window.location.href; } break; } } } } if (!flag) { flag = true; log.success("匹配历史记录 -> 增加新的"); let time = Date.now(); storageDataList = [ ...storageDataList, { url: window.location.href, topURL: top!.window.location.href, ruleKeyName: ruleKeyName, ruleIndex: ruleIndex, shareCode: shareCode, accessCode, addTime: time, updateTime: time, title: document.title || top!.document.title, matchText: matchText, }, ]; } this.saveStorageData(storageDataList); return true; }, /** * 检测并尝试修复本地的数据 */ checkAndRepairLocalData() { let repairCount = 0; let data = GM_getValue(this.storageKey); if (Array.isArray(data)) { for (let index = 0; index < data.length; index++) { let repairFlag = false; const itemData = data[index]; if (typeof itemData.matchText !== "string") { itemData.matchText = ""; repairFlag = true; } if ( typeof itemData.ruleKeyName !== "string" && // @ts-expect-error typeof itemData.netDiskName === "string" ) { // @ts-expect-error itemData.ruleKeyName = itemData.netDiskName; // @ts-expect-error delete itemData.netDiskName; repairFlag = true; } if ( typeof itemData.ruleIndex !== "number" && // @ts-expect-error typeof itemData.netDiskIndex === "number" ) { // @ts-expect-error itemData.ruleIndex = itemData.netDiskIndex; // @ts-expect-error delete itemData.netDiskIndex; repairFlag = true; } repairFlag && repairCount++; } } else { data = []; } this.saveStorageData(data); return { count: data.length, repairCount: repairCount, }; }, /** * 获取历史匹配到的链接 */ getStorageData(): NetDiskHistoryDataOption[] { let data = GM_getValue(this.storageKey, []); if (data == null) { data = []; this.saveStorageData(data); } return data; }, /** * 保存数据到本地存储的链接数据 */ saveStorageData(data: NetDiskHistoryDataOption[]) { GM_setValue(this.storageKey, data); }, /** * 删除存储的某个项 * @param dataJSONText */ deleteStorageData(dataJSONText: string) { let isSuccess = false; let data = this.getStorageData(); for (let index = 0; index < data.length; index++) { if (JSON.stringify(data[index]) === dataJSONText) { log.success("删除 ===> ", data[index]); data.splice(index, 1); isSuccess = true; break; } } if (isSuccess) { this.saveStorageData(data); } return isSuccess; }, /** * 清空所有配置 */ clearStorageData() { this.saveStorageData([]); }, };