forked from AnYiEE/AwesomeGadgets
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(RightTopicon): add RightTopicon
- Loading branch information
Showing
2 changed files
with
174 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/有兽档案馆:用户权限#自动确认用户', | ||
}, | ||
}; |