Skip to content

Commit

Permalink
feat(RightTopicon): add RightTopicon
Browse files Browse the repository at this point in the history
  • Loading branch information
ajdgg authored May 1, 2024
1 parent 742517f commit f4f961e
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 93 deletions.
198 changes: 105 additions & 93 deletions src/RightTopicons/RightTopicons.ts
Original file line number Diff line number Diff line change
@@ -1,118 +1,130 @@
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;
props: Record<string, string | number | boolean>;
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<HTMLElement>) => {
if (!(container instanceof jQuery)) {
container = $(container);
}

function renderVirtualDOM(virtualDOM: VirtualDOMNode[], container: JQuery<HTMLElement>) {
if (!(container instanceof jQuery)) {
container = $(container);
}
function createRealNode(virtualNode: VirtualDOMNode): JQuery<HTMLElement> {
const { tag, props, children } = virtualNode;
const realNode = $('<' + tag + '>');
Object.keys(props).forEach(propName => {
const createRealNode = (virtualNode: VirtualDOMNode): JQuery<HTMLElement> => {
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<DataType extends { id: number }>(dataArray: DataType[]): DataType[] {
dataArray.sort((a, b) => a.id - b.id);
if (dataArray.length > 3) {
return dataArray.slice(0, 3);
}
return dataArray;
}
};
const ArrayDataSort = <DataType extends {id: number}>(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<UserData> {
return new Promise((resolve, reject) => {
const fetchUserData = (): Promise<UserData> => {
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<UserData> {
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<HTMLBodyElement> = $('body');
const $dommountpoint: JQuery = $body.find('#content header.mw-body-header .page-heading .mw-indicators');
renderVirtualDOM(virtualDOM, $dommountpoint);
})
.catch((error) => {
console.error('最终请求失败,不再重试:', error);
});
});
69 changes: 69 additions & 0 deletions src/RightTopicons/modules/PermissionData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
type LIBDictionaryEntry = {
id: string;
aimgsrc: string;
src: string;
};
// 责,理,管,监,界,巡,模,机,优,发,确

export const LIBdictionary: Record<string, LIBDictionaryEntry> = {
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/有兽档案馆:用户权限#自动确认用户',
},
};

0 comments on commit f4f961e

Please sign in to comment.