From f4f961ee7391db87f6f7a3ccc57d9fd5bbb33286 Mon Sep 17 00:00:00 2001 From: AwAjie <139576615+ajdgg@users.noreply.github.com> Date: Thu, 2 May 2024 01:36:06 +0800 Subject: [PATCH] feat(RightTopicon): add RightTopicon --- src/RightTopicons/RightTopicons.ts | 198 +++++++++++--------- src/RightTopicons/modules/PermissionData.ts | 69 +++++++ 2 files changed, 174 insertions(+), 93 deletions(-) create mode 100644 src/RightTopicons/modules/PermissionData.ts diff --git a/src/RightTopicons/RightTopicons.ts b/src/RightTopicons/RightTopicons.ts index 7fffd04..b240400 100644 --- a/src/RightTopicons/RightTopicons.ts +++ b/src/RightTopicons/RightTopicons.ts @@ -1,12 +1,12 @@ -import {LIBdictionary} from './PermissionData.ts'; -$(function(){ - let WikiURLName = window.location.pathname; - let matchResult = /^\/wiki\/User:[^\/]*$/.test(WikiURLName); - if (!matchResult) { - return; - } - let userNameMatch = (WikiURLName.match(/User:(.*)$/) || [])[1]; - let UserMessage = `${mw.config.get('wgServer')}/api.php?action=query&list=users&usprop=groups&format=json&ususers=${userNameMatch}`; +import {LIBdictionary} from './modules/PermissionData'; +$(() => { + const WikiURLName = window.location.pathname; + const matchResult = /^\/wiki\/User:[^/]*$/.test(WikiURLName); + if (!matchResult) { + return; + } + const [_, userNameMatch] = WikiURLName.match(/User:(.*)$/) || []; + const UserMessage = `${mw.config.get('wgServer')}/api.php?action=query&list=users&usprop=groups&format=json&ususers=${userNameMatch}`; type VirtualDOMNode = { tag: string; @@ -14,105 +14,117 @@ $(function(){ children?: VirtualDOMNode[]; }; - function createVirtualLinkImg(href: string, aimgsrc: string) { - return { - tag: 'a', - props: { - href: href, - style: 'display: inline-block;' - }, - children: [{ - tag: 'img', - props: { - src: aimgsrc, - style: 'width: 39px; margin: 0 3px;' - } - }] - }; - } + const createVirtualLinkImg = (href: string, aimgsrc: string): object => { + return { + tag: 'a', + props: { + href, + style: 'display: inline-block;', + }, + children: [ + { + tag: 'img', + props: { + src: aimgsrc, + style: 'width: 39px; margin: 0 3px;', + }, + }, + ], + }; + }; + + const renderVirtualDOM = (virtualDOM: VirtualDOMNode[], container: JQuery) => { + if (!(container instanceof jQuery)) { + container = $(container); + } - function renderVirtualDOM(virtualDOM: VirtualDOMNode[], container: JQuery) { - if (!(container instanceof jQuery)) { - container = $(container); - } - function createRealNode(virtualNode: VirtualDOMNode): JQuery { - const { tag, props, children } = virtualNode; - const realNode = $('<' + tag + '>'); - Object.keys(props).forEach(propName => { + const createRealNode = (virtualNode: VirtualDOMNode): JQuery => { + const {tag, props, children} = virtualNode; + const realNode = $(`<${tag}>`); + for (const propName of Object.keys(props)) { realNode.attr(propName, String(props[propName])); - }); + } if (children) { - children.forEach(childVirtualNode => { + for (const childVirtualNode of children) { const childRealNode = createRealNode(childVirtualNode); realNode.append(childRealNode); - }); + } } + return realNode; + }; + const realNodes = virtualDOM.map((virtualNode) => { + const realNode = createRealNode(virtualNode); return realNode; + }); + + for (const node of realNodes) { + container.append(node); } - const realNodes = virtualDOM.map(virtualNode => createRealNode(virtualNode)); - realNodes.forEach(node => { - container.append(node); - }); - } - function ArrayDataSort(dataArray: DataType[]): DataType[] { - dataArray.sort((a, b) => a.id - b.id); - if (dataArray.length > 3) { - return dataArray.slice(0, 3); - } - return dataArray; - } + }; + const ArrayDataSort = (dataArray: DataType[]) => { + dataArray.sort((a, b) => { + return a.id - b.id; + }); + if (dataArray.length > 3) { + return dataArray.slice(0, 3); + } + return dataArray; + }; type UserData = { groups: string[]; }; - function fetchUserData(): Promise { - return new Promise((resolve, reject) => { + const fetchUserData = (): Promise => { + return new Promise((resolve, reject) => { if (!UserMessage) { - return reject(new Error('UserMessage is not defined')); + reject(new Error('UserMessage is not defined')); } - $.get(UserMessage, function(data) { - const userData: UserData = data.query.users[0].groups ; - resolve(userData); - }, 'json').fail(reject); - }); - } - - - let retryCount = 0; + $.get( + UserMessage, + (data) => { + const userData: UserData = { + groups: data.query.users[0].groups as string[], + }; + console.log(userData); + resolve(userData); + }, + 'json' + ) + .then(() => {}) + .catch(reject); + }); + }; - function fetchUserDataWithRetry(): Promise { - return fetchUserData().catch(error => { - retryCount++; - if (retryCount <= 3) { - console.warn(`请求失败,正在进行第${retryCount}次重试...`); - return fetchUserDataWithRetry(); - } else { - console.error('请求失败,已达到最大重试次数:', error); - throw error; - } - }); - } + fetchUserData() + .then((userData: UserData) => { + if (!userData || !Array.isArray(userData.groups)) { + console.error(new Error('Invalid userData.groups: expected an array but received none or a non-array.')); + return; + } - fetchUserDataWithRetry().then((UserData: UserData) => { - if (!UserData || !Array.isArray(UserData)) { - console.error('谢特', UserData); - return; - } + const matchedGroups = userData.groups + .filter((group): group is string => { + return typeof group === 'string' && Object.hasOwn(LIBdictionary, group); + }) + .map((group) => { + return LIBdictionary[group]; + }); - let matchedGroups = UserData - .filter(group => LIBdictionary.hasOwnProperty(group)) - .map(group => LIBdictionary[group]); - let firstThreeItems = ArrayDataSort(matchedGroups as unknown as { - src: any; - aimgsrc: any; - id: number - }[]); - const virtualDOM = firstThreeItems.map((imgData) => - (imgData?.src && imgData?.aimgsrc ? createVirtualLinkImg(imgData.src, imgData.aimgsrc) : null) as VirtualDOMNode); - let dommountpoint = $('#content header.mw-body-header .page-heading .mw-indicators'); - renderVirtualDOM(virtualDOM, dommountpoint); - }).catch(error => { - console.error('最终请求失败,不再重试:', error); - }); -}) + interface ImageItem { + src: string; + aimgsrc: string; + id: number; + } + const firstThreeItems = ArrayDataSort(matchedGroups as unknown as ImageItem[]); + const virtualDOM = firstThreeItems.map((imgData) => { + return imgData?.src && imgData?.aimgsrc ? createVirtualLinkImg(imgData.src, imgData.aimgsrc) : null; + }) as VirtualDOMNode[]; + const $body: JQuery = $('body'); + const $dommountpoint: JQuery = $body.find('#content header.mw-body-header .page-heading .mw-indicators'); + renderVirtualDOM(virtualDOM, $dommountpoint); + }) + .catch((error) => { + console.error('最终请求失败,不再重试:', error); + }); +}); diff --git a/src/RightTopicons/modules/PermissionData.ts b/src/RightTopicons/modules/PermissionData.ts new file mode 100644 index 0000000..12ee049 --- /dev/null +++ b/src/RightTopicons/modules/PermissionData.ts @@ -0,0 +1,69 @@ +type LIBDictionaryEntry = { + id: string; + aimgsrc: string; + src: string; +}; +// 责,理,管,监,界,巡,模,机,优,发,确 + +export const LIBdictionary: Record = { + responsibleoperator: { + id: '1', + aimgsrc: + 'https://youshou.wiki/images/d/d6/%E8%B4%A3%E4%BB%BB%E8%BF%90%E8%90%A5%E6%9D%83%E9%99%90%E6%A0%87%E8%AF%86.svg', + src: 'https://youshou.wiki/wiki/%E6%9C%89%E5%85%BD%E6%A1%A3%E6%A1%88%E9%A6%86:%E7%94%A8%E6%88%B7%E6%9D%83%E9%99%90#%E8%B4%A3%E4%BB%BB%E8%BF%90%E8%90%A5', + }, + steward: { + id: '2', + aimgsrc: + 'https://youshou.wiki/images/a/a4/%E6%A1%A3%E6%A1%88%E7%90%86%E4%BA%8B%E5%91%98%E6%9D%83%E9%99%90%E6%A0%87%E8%AF%86.svg', + src: 'https://youshou.wiki/wiki/%E6%9C%89%E5%85%BD%E6%A1%A3%E6%A1%88%E9%A6%86:%E6%A1%A3%E6%A1%88%E7%90%86%E4%BA%8B%E5%9B%A2%E9%98%9F', + }, + sysop: { + id: '3', + aimgsrc: 'https://youshou.wiki/images/3/3e/%E7%AE%A1%E7%90%86%E5%91%98%E6%9D%83%E9%99%90%E6%A0%87%E8%AF%86.svg', + src: 'https://youshou.wiki/wiki/%E6%9C%89%E5%85%BD%E6%A1%A3%E6%A1%88%E9%A6%86:%E7%AE%A1%E7%90%86%E5%91%98', + }, + templateeditor: { + id: '4', + aimgsrc: + 'https://youshou.wiki/images/4/47/%E6%A8%A1%E6%9D%BF%E7%BC%96%E8%BE%91%E5%91%98%E6%9D%83%E9%99%90%E6%A0%87%E8%AF%86.svg', + src: 'https://youshou.wiki/wiki/%E6%9C%89%E5%85%BD%E6%A1%A3%E6%A1%88%E9%A6%86:%E6%A8%A1%E6%9D%BF%E7%BC%96%E8%BE%91%E5%91%98', + }, + 'interface-admin': { + id: '5', + aimgsrc: + 'https://youshou.wiki/images/e/ea/%E7%95%8C%E9%9D%A2%E7%AE%A1%E7%90%86%E5%91%98%E6%9D%83%E9%99%90%E6%A0%87%E8%AF%86.svg', + src: 'https://youshou.wiki/wiki/%E6%9C%89%E5%85%BD%E6%A1%A3%E6%A1%88%E9%A6%86:%E7%95%8C%E9%9D%A2%E7%AE%A1%E7%90%86%E5%91%98', + }, + patroller: { + id: '6', + aimgsrc: 'https://youshou.wiki/images/6/67/%E5%B7%A1%E6%9F%A5%E5%91%98%E6%9D%83%E9%99%90%E6%A0%87%E8%AF%86.svg', + src: 'https://youshou.wiki/wiki/%E6%9C%89%E5%85%BD%E6%A1%A3%E6%A1%88%E9%A6%86:%E5%B7%A1%E6%9F%A5%E6%9D%A1%E4%BE%8B#%E5%B7%A1%E6%9F%A5%E5%91%98', + }, + suppress: { + id: '7', + aimgsrc: 'https://youshou.wiki/images/3/3d/%E7%9B%91%E7%9D%A3%E5%91%98%E6%9D%83%E9%99%90%E6%A0%87%E8%AF%86.svg', + src: 'https://youshou.wiki/wiki/%E6%9C%89%E5%85%BD%E6%A1%A3%E6%A1%88%E9%A6%86:%E7%9B%91%E7%9D%A3%E6%9D%A1%E4%BE%8B#%E7%9B%91%E7%9D%A3%E5%91%98', + }, + bot: { + id: '8', + aimgsrc: 'https://youshou.wiki/images/f/f0/%E6%9C%BA%E5%99%A8%E4%BA%BA%E6%9D%83%E9%99%90%E6%A0%87%E8%AF%86.svg', + src: 'https://youshou.wiki/wiki/%E6%9C%89%E5%85%BD%E6%A1%A3%E6%A1%88%E9%A6%86:%E6%9C%BA%E5%99%A8%E4%BA%BA', + }, + autopatrolled: { + id: '9', + aimgsrc: + 'https://youshou.wiki/images/1/1e/%E4%BC%98%E8%B4%A8%E7%BC%96%E8%BE%91%E8%80%85%E6%9D%83%E9%99%90%E6%A0%87%E8%AF%86.svg', + src: 'https://youshou.wiki/wiki/%E6%9C%89%E5%85%BD%E6%A1%A3%E6%A1%88%E9%A6%86:%E4%BC%98%E8%B4%A8%E7%BC%96%E8%BE%91%E8%80%85', + }, + 'massmessage-sender': { + id: '10', + aimgsrc: 'https://youshou.wiki/images/c/cd/大量消息发送者权限标识.svg', + src: 'https://youshou.wiki/wiki/有兽档案馆:大量消息发送者', + }, + autoconfirmed: { + id: '11', + aimgsrc: 'https://youshou.wiki/images/4/49/确认用户权限标识.svg', + src: 'https://youshou.wiki/wiki/有兽档案馆:用户权限#自动确认用户', + }, +};