hortimagic 1.0.7 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hortimagic.iife.js +2 -2
- package/dist/hortimagic.js +4 -4
- package/dist/hortimagic.txt +4 -4
- package/dist/hortimagic.user.js +4 -4
- package/package.json +4 -3
- package/src/apps/config-app.ts +132 -0
- package/src/apps/dialog-app.ts +62 -0
- package/src/apps/index.ts +5 -0
- package/src/apps/log-app.ts +251 -0
- package/src/apps/main-app.ts +72 -0
- package/src/apps/script-app.ts +225 -0
- package/src/components/hm-swipe-cell.ts +2 -2
- package/src/core/Emitter.ts +129 -0
- package/src/core/Message.ts +179 -0
- package/src/core/decoder.ts +207 -0
- package/src/core/elements-hooks.ts +168 -0
- package/src/core/encoder.ts +154 -0
- package/src/core/index.ts +10 -0
- package/src/core/log-tools.ts +69 -0
- package/src/core/script-tools.ts +121 -0
- package/src/core/socket-tools.ts +118 -0
- package/src/core/store.ts +149 -0
- package/src/core/tools.ts +318 -0
- package/src/easy-tools.ts +141 -0
- package/src/holders/dialog.ts +9 -0
- package/src/holders/index.ts +4 -0
- package/src/holders/menu.ts +20 -0
- package/src/holders/move-panel.ts +9 -0
- package/src/holders/notification.ts +9 -0
- package/src/main.ts +49 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { logger } from "./log-tools";
|
|
2
|
+
import { HortimagicStore } from "./store";
|
|
3
|
+
|
|
4
|
+
const Tag = "script-tools";
|
|
5
|
+
export const ingectedUrlList: string[] = [];
|
|
6
|
+
/** 脚本类 */
|
|
7
|
+
export class Script {
|
|
8
|
+
/** 名字 */
|
|
9
|
+
name: string;
|
|
10
|
+
/** 唯一链接 */
|
|
11
|
+
url: string;
|
|
12
|
+
/** 是否启用,默认启用 */
|
|
13
|
+
enable: boolean;
|
|
14
|
+
constructor(
|
|
15
|
+
name: string,
|
|
16
|
+
url: string,
|
|
17
|
+
enable: boolean = true,
|
|
18
|
+
) {
|
|
19
|
+
this.name = name;
|
|
20
|
+
this.url = url;
|
|
21
|
+
this.enable = enable;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** 添加脚本到列表
|
|
26
|
+
* @param script 脚本对象
|
|
27
|
+
* @returns 是否添加成功
|
|
28
|
+
*/
|
|
29
|
+
export function addScriptToList(script: Script) {
|
|
30
|
+
logger.debug(Tag, `添加${script.name},${script.url}`);
|
|
31
|
+
/** 如果脚本的URL或名称已经存在,则不添加 */
|
|
32
|
+
if (findScriptByUrl(script.url) >= 0 || findScriptByName(script.name) >= 0) {
|
|
33
|
+
logger.warn(Tag, `脚本${script.name}${script.url}已经存在`);
|
|
34
|
+
// HortimagicStore.scriptList.push(script);
|
|
35
|
+
return false;
|
|
36
|
+
} else {
|
|
37
|
+
HortimagicStore.scriptList.push(script);
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function updateScriptInList(script: Script) {
|
|
43
|
+
logger.debug(Tag, `更新脚本${script.name}${script.url}`);
|
|
44
|
+
for (let i = 0; i < HortimagicStore.scriptList.length; i++) {
|
|
45
|
+
if (HortimagicStore.scriptList[i].name === script.name) {
|
|
46
|
+
HortimagicStore.scriptList[i] = script;
|
|
47
|
+
return true;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
if (HortimagicStore.scriptList[i].url === script.url) {
|
|
51
|
+
HortimagicStore.scriptList[i] = script;
|
|
52
|
+
return true;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function removeScriptFromList(script: Script) {
|
|
60
|
+
logger.debug(Tag, `删除${script.name},${script.url}`);
|
|
61
|
+
let index = findScriptByName(script.name);
|
|
62
|
+
if (index >= 0) {
|
|
63
|
+
HortimagicStore.scriptList.splice(index, 1);
|
|
64
|
+
return true;
|
|
65
|
+
} else {
|
|
66
|
+
index = findScriptByUrl(script.url);
|
|
67
|
+
if (index >= 0) {
|
|
68
|
+
HortimagicStore.scriptList.splice(index, 1);
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function findScriptByUrl(url: string): number {
|
|
77
|
+
for (let i = 0; i < HortimagicStore.scriptList.length; i++) {
|
|
78
|
+
if (HortimagicStore.scriptList[i].url == url) {
|
|
79
|
+
return i;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return -1;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function findScriptByName(name: string): number {
|
|
86
|
+
for (let i = 0; i < HortimagicStore.scriptList.length; i++) {
|
|
87
|
+
if (HortimagicStore.scriptList[i].name == name) {
|
|
88
|
+
return i;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return -1;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function clearScriptList() {
|
|
95
|
+
HortimagicStore.scriptList = [];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** 注入脚本,不论它是否使能
|
|
99
|
+
* @param script 脚本对象
|
|
100
|
+
*/
|
|
101
|
+
export function ingecteScript(script: Script) {
|
|
102
|
+
if (ingectedUrlList.includes(script.url)) {
|
|
103
|
+
logger.warn(Tag, `脚本${script.name}${script.url}已经注入`);
|
|
104
|
+
return false;
|
|
105
|
+
} else {
|
|
106
|
+
const scriptElement = document.createElement("script");
|
|
107
|
+
scriptElement.src = script.url;
|
|
108
|
+
document.body.appendChild(scriptElement);
|
|
109
|
+
ingectedUrlList.push(script.url);
|
|
110
|
+
logger.debug(Tag, `注入${script.name}`);
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function ingecteScriptList() {
|
|
116
|
+
HortimagicStore.scriptList.forEach((script) => {
|
|
117
|
+
if (script.enable && !ingectedUrlList.includes(script.url)) {
|
|
118
|
+
ingecteScript(script);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { decodeMessage, judegMessageClass, messageObjList } from "./decoder";
|
|
2
|
+
import { Emitter } from "./Emitter";
|
|
3
|
+
import { logger } from "./log-tools";
|
|
4
|
+
import { HortimagicStore } from "./store";
|
|
5
|
+
import { sleep } from "./tools";
|
|
6
|
+
|
|
7
|
+
const Tag = 'socket-tools';
|
|
8
|
+
export const messageEmitter = new Emitter();
|
|
9
|
+
// 发送消息
|
|
10
|
+
async function beforeSend(message: string): Promise<string | null> {
|
|
11
|
+
return message;
|
|
12
|
+
}
|
|
13
|
+
function originalSend(message: string) { return message; }
|
|
14
|
+
function afterSend(message: string) {
|
|
15
|
+
return message;
|
|
16
|
+
}
|
|
17
|
+
async function send(message: string) {
|
|
18
|
+
if (HortimagicStore.messageLogFlag.send) logger.debug(Tag, '发送', { message });
|
|
19
|
+
let temp = await socketTools.beforeSend(message);
|
|
20
|
+
try {
|
|
21
|
+
if (temp != null) {
|
|
22
|
+
socketTools.originalSend(temp);
|
|
23
|
+
socketTools.afterSend(temp);
|
|
24
|
+
}
|
|
25
|
+
} catch (error) {
|
|
26
|
+
logger.error(Tag, error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// 接收消息
|
|
30
|
+
async function beforeOnmessage(message: string): Promise<string | null> {
|
|
31
|
+
if (HortimagicStore.messageLogFlag.decode) logger.debug(Tag, '解码', { message });
|
|
32
|
+
decodeMessage(message);
|
|
33
|
+
return message;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function originalOnmessage(message: string) { return message; }
|
|
37
|
+
async function afterOnmessage(message: string) {
|
|
38
|
+
// logger.debug(Tag,'准备触发', message, messageObjList);
|
|
39
|
+
for (let messageObj of messageObjList) {
|
|
40
|
+
if (HortimagicStore.messageLogFlag.emit) {
|
|
41
|
+
logger.debug(Tag, `触发${judegMessageClass(messageObj)}消息`, {
|
|
42
|
+
message,
|
|
43
|
+
messageObj
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
messageEmitter.emit(judegMessageClass(messageObj), messageObj)
|
|
47
|
+
};
|
|
48
|
+
return message;
|
|
49
|
+
}
|
|
50
|
+
async function onmessage(message: string) {
|
|
51
|
+
if (HortimagicStore.messageLogFlag.receive) { logger.debug(Tag, '接收', { message }); }
|
|
52
|
+
let temp = await socketTools.beforeOnmessage(message);
|
|
53
|
+
try {
|
|
54
|
+
if (temp != null) {
|
|
55
|
+
socketTools.originalOnmessage(temp);
|
|
56
|
+
// 不等待异步函数实现“多线程”的目的
|
|
57
|
+
socketTools.afterOnmessage(temp);
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
logger.error('捕获到错误', error);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
// 初始化fSocket
|
|
66
|
+
export async function initSocket() {
|
|
67
|
+
logger.debug(Tag, '代理网络');
|
|
68
|
+
for (let index = 0; index < 30; index++) {
|
|
69
|
+
try {
|
|
70
|
+
logger.debug(Tag, '等待网络连接', index);
|
|
71
|
+
// @ts-ignore
|
|
72
|
+
if (window["socket"].__onmessage == undefined && window["socket"]._onmessage != undefined && window["socket"].send != undefined) {
|
|
73
|
+
logger.debug(Tag, '网络连接成功');
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// 等待一下
|
|
78
|
+
await sleep(500);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
} catch (error) {
|
|
82
|
+
logger.error(Tag, error);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
if (window["socket"].__onmessage == undefined && window["socket"]._onmessage != undefined && window["socket"].send != undefined) {
|
|
87
|
+
} else {
|
|
88
|
+
logger.error('连接失败')
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
// 等待一下
|
|
92
|
+
// await sleep(500);
|
|
93
|
+
// 发送
|
|
94
|
+
// @ts-ignore
|
|
95
|
+
socketTools.originalSend = window["socket"].send;
|
|
96
|
+
// 覆写原来的发送函数
|
|
97
|
+
// @ts-ignore
|
|
98
|
+
window["socket"].send = socketTools.send;
|
|
99
|
+
// 接收
|
|
100
|
+
// @ts-ignore
|
|
101
|
+
socketTools.originalOnmessage = window["socket"]._onmessage;
|
|
102
|
+
// 覆写接收函数
|
|
103
|
+
// @ts-ignore
|
|
104
|
+
window["socket"]._onmessage = socketTools.onmessage;
|
|
105
|
+
}
|
|
106
|
+
export const socketTools = {
|
|
107
|
+
beforeSend,
|
|
108
|
+
originalSend,
|
|
109
|
+
afterSend,
|
|
110
|
+
send,
|
|
111
|
+
beforeOnmessage,
|
|
112
|
+
originalOnmessage,
|
|
113
|
+
afterOnmessage,
|
|
114
|
+
onmessage,
|
|
115
|
+
initSocket
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { proxy, subscribe, snapshot } from 'valtio/vanilla';
|
|
2
|
+
|
|
3
|
+
import { logger } from "./log-tools";
|
|
4
|
+
import type { Script } from './script-tools';
|
|
5
|
+
|
|
6
|
+
const Tag = 'store'
|
|
7
|
+
|
|
8
|
+
const storKey = 'HortimagicStore';
|
|
9
|
+
/**
|
|
10
|
+
* 导出valtio响应式状态管理库常用方法
|
|
11
|
+
* @example
|
|
12
|
+
* // 创建响应式状态
|
|
13
|
+
* const state = reactive.proxy({ count: 0 })
|
|
14
|
+
*
|
|
15
|
+
* // 订阅状态变化
|
|
16
|
+
* reactive.subscribe(state, () => {
|
|
17
|
+
* console.log('state has changed to', state)
|
|
18
|
+
* })
|
|
19
|
+
*
|
|
20
|
+
* // 获取状态快照
|
|
21
|
+
* const snap = reactive.snapshot(state)
|
|
22
|
+
*
|
|
23
|
+
* // 在组件中使用(注意:snapshot返回的是只读快照,不能直接修改)
|
|
24
|
+
* // 需要通过原始proxy对象进行修改
|
|
25
|
+
* const updateState = () => {
|
|
26
|
+
* state.count++ // 直接修改原始proxy对象
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* // 无React环境使用示例:
|
|
30
|
+
* // 1. 创建状态
|
|
31
|
+
* const counterStore = proxy({ count: 0 });
|
|
32
|
+
*
|
|
33
|
+
* // 2. 修改状态
|
|
34
|
+
* counterStore.count++;
|
|
35
|
+
*
|
|
36
|
+
* // 3. 获取快照(用于显示)
|
|
37
|
+
* const snap = snapshot(counterStore);
|
|
38
|
+
* console.log(snap.count); // 输出当前值
|
|
39
|
+
*
|
|
40
|
+
* // 4. 订阅变化
|
|
41
|
+
* subscribe(counterStore, () => {
|
|
42
|
+
* console.log('counter changed');
|
|
43
|
+
* });
|
|
44
|
+
*/
|
|
45
|
+
export const reactive = {
|
|
46
|
+
proxy,
|
|
47
|
+
subscribe,
|
|
48
|
+
/**
|
|
49
|
+
* 获取快照
|
|
50
|
+
* @param {object} store
|
|
51
|
+
* @returns {object} 一个静态的快照
|
|
52
|
+
*/
|
|
53
|
+
snapshot
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* hortiMagicStore存储库
|
|
57
|
+
*/
|
|
58
|
+
export const HortimagicStore = proxy({
|
|
59
|
+
/** 是否自动保存 */
|
|
60
|
+
autoSave: false,
|
|
61
|
+
/** 日志是否开启 */
|
|
62
|
+
logFlag: {
|
|
63
|
+
log: false,
|
|
64
|
+
info: true,
|
|
65
|
+
debug: true,
|
|
66
|
+
warn: true,
|
|
67
|
+
error: true
|
|
68
|
+
},
|
|
69
|
+
/** 消息日志是否开启 */
|
|
70
|
+
messageLogFlag: {
|
|
71
|
+
send: false,
|
|
72
|
+
decode: false,
|
|
73
|
+
emit: true,
|
|
74
|
+
receive: false,
|
|
75
|
+
},
|
|
76
|
+
/** 日志列表最大长度 */
|
|
77
|
+
logListLength: 20,
|
|
78
|
+
/** 脚本列表 */
|
|
79
|
+
scriptList: [] as Script[],
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 保存store
|
|
86
|
+
*/
|
|
87
|
+
export function saveStore() {
|
|
88
|
+
localStorage.setItem(storKey, JSON.stringify(HortimagicStore));
|
|
89
|
+
logger.debug(Tag, "保存至本地存储");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* 加载store
|
|
94
|
+
*/
|
|
95
|
+
export function loadStore() {
|
|
96
|
+
let res = localStorage.getItem(storKey);
|
|
97
|
+
if (res != null) {
|
|
98
|
+
const parsedRes = JSON.parse(res);
|
|
99
|
+
if (parsedRes.autoSave) {
|
|
100
|
+
HortimagicStore.autoSave = parsedRes.autoSave == true;
|
|
101
|
+
} else {
|
|
102
|
+
HortimagicStore.autoSave = false;
|
|
103
|
+
}
|
|
104
|
+
if (parsedRes.logFlag) {
|
|
105
|
+
HortimagicStore.logFlag = parsedRes.logFlag;
|
|
106
|
+
} else {
|
|
107
|
+
// 兼容旧格式
|
|
108
|
+
if (isNaN(parsedRes.logLevel)) {
|
|
109
|
+
HortimagicStore.logFlag = parsedRes.logLevel;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (parsedRes.scriptList) {
|
|
114
|
+
HortimagicStore.scriptList = parsedRes.scriptList;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (parsedRes.logListLength) {
|
|
118
|
+
HortimagicStore.logListLength = parsedRes.logListLength;
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
// 默认日志配置
|
|
122
|
+
HortimagicStore.logFlag.log = true;
|
|
123
|
+
HortimagicStore.logFlag.info = true;
|
|
124
|
+
HortimagicStore.logFlag.debug = true;
|
|
125
|
+
HortimagicStore.logFlag.warn = true;
|
|
126
|
+
HortimagicStore.logFlag.error = true;
|
|
127
|
+
//
|
|
128
|
+
HortimagicStore.autoSave = true;
|
|
129
|
+
HortimagicStore.logListLength = 20;
|
|
130
|
+
HortimagicStore.messageLogFlag.decode = false;
|
|
131
|
+
HortimagicStore.messageLogFlag.emit = true;
|
|
132
|
+
HortimagicStore.messageLogFlag.send = false;
|
|
133
|
+
HortimagicStore.messageLogFlag.receive = false;
|
|
134
|
+
HortimagicStore.scriptList = [];
|
|
135
|
+
logger.debug(Tag, '没有读取到配置,使用默认配置');
|
|
136
|
+
saveStore();
|
|
137
|
+
}
|
|
138
|
+
logger.debug(Tag, "从本地存储加载");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function initStore() {
|
|
142
|
+
loadStore();
|
|
143
|
+
// 订阅状态变化,当 autoSave 为 true 时自动保存
|
|
144
|
+
subscribe(HortimagicStore, () => {
|
|
145
|
+
if (HortimagicStore.autoSave) {
|
|
146
|
+
saveStore();
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 异步延时函数
|
|
3
|
+
* @param ms
|
|
4
|
+
*/
|
|
5
|
+
export async function sleep(ms: number) {
|
|
6
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 去除html字符串中的多余空白字符、注释
|
|
10
|
+
* @param html 要压缩的html字符串
|
|
11
|
+
* @returns 去除空白字符的字符串
|
|
12
|
+
*/
|
|
13
|
+
export function compressHTML(html: string): string {
|
|
14
|
+
// 去除HTML中的多余空白字符
|
|
15
|
+
html = html.replace(/>\s+</g, "><"); // 去除标签之间的多余空白
|
|
16
|
+
html = html.replace(/\s{2,}/g, " "); // 去除多余的空格
|
|
17
|
+
html = html.replace(/<!--[\s\S]*?-->/g, ""); // 去除HTML注释
|
|
18
|
+
html = html.trim(); // 去除首尾空白
|
|
19
|
+
return html;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 去除css字符串中的多余空白字符、注释
|
|
23
|
+
* @param css 要压缩的css字符串
|
|
24
|
+
* @returns 去除空白字符的字符串
|
|
25
|
+
*/
|
|
26
|
+
export function compressCSS(css: string): string {
|
|
27
|
+
// 去除CSS中的多余空白字符
|
|
28
|
+
css = css.replace(/\s{2,}/g, " "); // 去除多余的空格
|
|
29
|
+
css = css.replace(/\/\*[\s\S]*?\*\//g, ""); // 去除CSS注释
|
|
30
|
+
css = css.replace(/\s*([{};:,])\s*/g, "$1"); // 去除属性和选择器之间的多余空白
|
|
31
|
+
css = css.replace(/;\s*}/g, "}"); // 去除分号后的多余空白
|
|
32
|
+
css = css.trim(); // 去除首尾空白
|
|
33
|
+
return css;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 向页面添加一个样式元素
|
|
37
|
+
* @param css css字符串
|
|
38
|
+
*/
|
|
39
|
+
export function addStyle(css: string) {
|
|
40
|
+
let s = document.createElement("style");
|
|
41
|
+
s.innerText = css;
|
|
42
|
+
document.body.append(s);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* html特殊符号转义
|
|
46
|
+
* @param {string} e
|
|
47
|
+
* @returns {string}
|
|
48
|
+
*/
|
|
49
|
+
export function htmlSpecialCharsEscape(e: string): string {
|
|
50
|
+
e = e.replace(`&`, "&");
|
|
51
|
+
e = e.replace(`<`, "<");
|
|
52
|
+
e = e.replace(`>`, ">");
|
|
53
|
+
e = e.replace(`"`, """);
|
|
54
|
+
e = e.replace(`'`, "'");
|
|
55
|
+
e = e.replace(`\\`, "\");
|
|
56
|
+
return e;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* html特殊符号反转义
|
|
60
|
+
* @param {string} e
|
|
61
|
+
* @returns {string}
|
|
62
|
+
*/
|
|
63
|
+
export function htmlSpecialCharsDecode(e: string): string {
|
|
64
|
+
e = e.replace("<", `<`);
|
|
65
|
+
e = e.replace(">", `>`);
|
|
66
|
+
e = e.replace(""", `"`);
|
|
67
|
+
e = e.replace("'", `'`);
|
|
68
|
+
e = e.replace("\", `\\`);
|
|
69
|
+
e = e.replace("&", `&`);
|
|
70
|
+
return e;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 获取当前用户的名字
|
|
75
|
+
* @returns 返回当前用户的名字,没找到返回null
|
|
76
|
+
*/
|
|
77
|
+
export function getUserName(): string | null {
|
|
78
|
+
// @ts-ignore
|
|
79
|
+
if (window["myself"]) return window["myself"];
|
|
80
|
+
else return null;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 获取当前用户的UID
|
|
84
|
+
* @returns 返回当前用户的UID,没找到返回null
|
|
85
|
+
*/
|
|
86
|
+
export function getUserUid(): string | null {
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
if (window["uid"]) return window["uid"];
|
|
89
|
+
else return null;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* 获取当前房间ID
|
|
93
|
+
* @returns 返回当前用户的UID,没找到返回null
|
|
94
|
+
*/
|
|
95
|
+
export function getRoomId(): string | null {
|
|
96
|
+
// @ts-ignore
|
|
97
|
+
if (window["roomn"]) return window["roomn"];
|
|
98
|
+
else return null;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 通过房间id返回房间消息
|
|
102
|
+
* @param roomId 房间的id
|
|
103
|
+
* @returns 返回返回消息
|
|
104
|
+
*/
|
|
105
|
+
export function getRoomInfoById(roomId: string): {
|
|
106
|
+
name: string;
|
|
107
|
+
roomPath: Array<string>;
|
|
108
|
+
color: string;
|
|
109
|
+
description: string;
|
|
110
|
+
roomImage: string;
|
|
111
|
+
currentUserNum: number | "hidden";
|
|
112
|
+
ownerName: string;
|
|
113
|
+
member: Array<{ name: string; auth: "member" | "admin" | "unknow" }>;
|
|
114
|
+
} | null {
|
|
115
|
+
// @ts-ignore
|
|
116
|
+
let roomInfoArray = window.Objs.mapHolder?.Assets?.roomJson?.[roomId];
|
|
117
|
+
if (roomInfoArray) {
|
|
118
|
+
/** @type {Array<Array<string>>} */
|
|
119
|
+
let roomInfoPart: Array<Array<string>> = roomInfoArray[5]
|
|
120
|
+
.split("&&")
|
|
121
|
+
.map((o: string) => o.split(" & "));
|
|
122
|
+
let imageAndDescription = htmlSpecialCharsDecode(roomInfoPart[0][0]);
|
|
123
|
+
let firstSpaceIndex = imageAndDescription.indexOf(" ");
|
|
124
|
+
return {
|
|
125
|
+
name: roomInfoArray[1],
|
|
126
|
+
color: roomInfoArray[2],
|
|
127
|
+
roomPath: roomInfoArray /** @type {string} */[0]
|
|
128
|
+
.split("_"),
|
|
129
|
+
description: imageAndDescription.slice(firstSpaceIndex + 1),
|
|
130
|
+
roomImage: imageAndDescription.slice(0, firstSpaceIndex),
|
|
131
|
+
currentUserNum:
|
|
132
|
+
typeof roomInfoArray[7] == "number" ? roomInfoArray[7] : "hidden",
|
|
133
|
+
ownerName: roomInfoPart[1][0],
|
|
134
|
+
member: roomInfoPart[4].map((o: string) => ({
|
|
135
|
+
name: htmlSpecialCharsDecode(o.slice(1)),
|
|
136
|
+
auth: o[0] == "0" ? "member" : o[0] == "1" ? "admin" : "unknow",
|
|
137
|
+
})),
|
|
138
|
+
};
|
|
139
|
+
} else return null;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 通过uid获取在线用户的信息
|
|
143
|
+
* @param {string} uid
|
|
144
|
+
* @returns 用户消息
|
|
145
|
+
*/
|
|
146
|
+
export function getOnlineUserInfoById(uid: string): {
|
|
147
|
+
name: string;
|
|
148
|
+
uid: string;
|
|
149
|
+
color: string;
|
|
150
|
+
avatar: string;
|
|
151
|
+
roomId: string;
|
|
152
|
+
personalizedSignature: string;
|
|
153
|
+
} | null {
|
|
154
|
+
uid = String(uid);
|
|
155
|
+
// @ts-ignore
|
|
156
|
+
let userInfoArray = window.Objs.mapHolder?.function?.findUserByUid?.(uid);
|
|
157
|
+
if (userInfoArray) {
|
|
158
|
+
return {
|
|
159
|
+
name: userInfoArray[2],
|
|
160
|
+
uid: uid,
|
|
161
|
+
color: userInfoArray[3],
|
|
162
|
+
avatar: userInfoArray[0],
|
|
163
|
+
roomId: userInfoArray[4],
|
|
164
|
+
personalizedSignature: userInfoArray[6],
|
|
165
|
+
};
|
|
166
|
+
} else return null;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* 获取所有在线用户的信息
|
|
170
|
+
* @returns 用户消息列表
|
|
171
|
+
*/
|
|
172
|
+
export function getAllOnlineUserInfo():
|
|
173
|
+
| {
|
|
174
|
+
name: any;
|
|
175
|
+
uid: any;
|
|
176
|
+
color: any;
|
|
177
|
+
avatar: any;
|
|
178
|
+
roomId: any;
|
|
179
|
+
personalizedSignature: any;
|
|
180
|
+
}[]
|
|
181
|
+
| null {
|
|
182
|
+
// @ts-ignore
|
|
183
|
+
let userInfoMapObj = window.Objs.mapHolder.Assets.userJson;
|
|
184
|
+
if (userInfoMapObj) {
|
|
185
|
+
return Object.keys(userInfoMapObj).map((key) => {
|
|
186
|
+
let o = userInfoMapObj[key];
|
|
187
|
+
return {
|
|
188
|
+
name: o[2],
|
|
189
|
+
uid: o[8],
|
|
190
|
+
color: o[3],
|
|
191
|
+
avatar: o[0],
|
|
192
|
+
roomId: o[4],
|
|
193
|
+
personalizedSignature: o[6],
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
} else return null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* 切换房间
|
|
201
|
+
* @param {string} roomId 房间ID
|
|
202
|
+
*/
|
|
203
|
+
export function changeRoom(roomId: string) {
|
|
204
|
+
roomId = String(roomId);
|
|
205
|
+
if (roomId)
|
|
206
|
+
// @ts-ignore
|
|
207
|
+
window.Objs.mapHolder?.function?.roomchanger(roomId);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* 获取用户蔷薇头像url
|
|
212
|
+
* @returns {string}
|
|
213
|
+
*/
|
|
214
|
+
function getUserProfilePictureUrl(): string | null {
|
|
215
|
+
// @ts-ignore
|
|
216
|
+
if (window.avatar2 && window.avatarconv)
|
|
217
|
+
// @ts-ignore
|
|
218
|
+
return window.avatarconv(window.avatar2);
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* 获取用户蔷薇输入颜色
|
|
224
|
+
* @returns 获取不到返回null
|
|
225
|
+
*/
|
|
226
|
+
export function getUserInputColor(): string | null {
|
|
227
|
+
// @ts-ignore
|
|
228
|
+
if (window.inputcolorhex) return window.inputcolorhex;
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* 创造一个新的私聊气泡,搭配静默发送私聊消息才能和“正常一样使用。
|
|
234
|
+
* @param {string} targetUid 目标UID
|
|
235
|
+
* @param {string} content 正文
|
|
236
|
+
* @param {string} messageId 消息气泡的ID
|
|
237
|
+
*/
|
|
238
|
+
export function generatePrivateMessageBubble(
|
|
239
|
+
targetUid: string,
|
|
240
|
+
content: string,
|
|
241
|
+
messageId: string
|
|
242
|
+
) {
|
|
243
|
+
// @ts-ignore
|
|
244
|
+
if (window.privatechatfunc)
|
|
245
|
+
// @ts-ignore
|
|
246
|
+
window.privatechatfunc(
|
|
247
|
+
[
|
|
248
|
+
Math.floor(Date.now() / 1000).toString(10), // 0
|
|
249
|
+
getUserUid(), // 1
|
|
250
|
+
htmlSpecialCharsEscape(getUserName() as string), // 2
|
|
251
|
+
htmlSpecialCharsEscape(getUserProfilePictureUrl() as string), // 3
|
|
252
|
+
htmlSpecialCharsEscape(content), // 4
|
|
253
|
+
htmlSpecialCharsEscape(getUserInputColor() as string), // 5
|
|
254
|
+
"", // 6
|
|
255
|
+
htmlSpecialCharsEscape(getUserInputColor() as string), // 7
|
|
256
|
+
"", // 8
|
|
257
|
+
"", // 9
|
|
258
|
+
messageId, // 10
|
|
259
|
+
targetUid, // 11
|
|
260
|
+
"", // 12
|
|
261
|
+
"", // 13
|
|
262
|
+
"", // 14
|
|
263
|
+
"", // 15
|
|
264
|
+
"", // 16
|
|
265
|
+
].join(">")
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* 切换房间
|
|
271
|
+
* @param {string} roomId
|
|
272
|
+
*/
|
|
273
|
+
export function switchRoom(roomId: string) {
|
|
274
|
+
// @ts-ignore
|
|
275
|
+
if (window.Objs.mapHolder?.function?.roomchanger)
|
|
276
|
+
// @ts-ignore
|
|
277
|
+
window.Objs.mapHolder.function.roomchanger(roomId);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// /**
|
|
281
|
+
// * 在当前用户所在的页面发送信息
|
|
282
|
+
// * @param {string} content
|
|
283
|
+
// */
|
|
284
|
+
// function sendCurrentPageMessage(content: string) {
|
|
285
|
+
// elementsAndHooks.refreshAll();
|
|
286
|
+
// let inputBox: HTMLInputElement = elementsAndHooks.elements.moveinput as HTMLInputElement;
|
|
287
|
+
// let old = inputBox.value;
|
|
288
|
+
// inputBox.value = content;
|
|
289
|
+
// // @ts-ignore
|
|
290
|
+
// inputBox.oninput(null);
|
|
291
|
+
// // @ts-ignore
|
|
292
|
+
// iiroseElements.inputSendBtn.onclick(null);
|
|
293
|
+
// inputBox.value = old;
|
|
294
|
+
// }
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* 工具集
|
|
298
|
+
*/
|
|
299
|
+
// export {
|
|
300
|
+
// sleep,
|
|
301
|
+
// compressHTML,
|
|
302
|
+
// compressCSS,
|
|
303
|
+
// addStyle,
|
|
304
|
+
// htmlSpecialCharsEscape,
|
|
305
|
+
// htmlSpecialCharsDecode,
|
|
306
|
+
// getUserName,
|
|
307
|
+
// getUserUid,
|
|
308
|
+
// getRoomId,
|
|
309
|
+
// getRoomInfoById,
|
|
310
|
+
// getOnlineUserInfoById,
|
|
311
|
+
// getAllOnlineUserInfo,
|
|
312
|
+
// changeRoom,
|
|
313
|
+
// getUserProfilePictureUrl,
|
|
314
|
+
// getUserInputColor,
|
|
315
|
+
// generatePrivateMessageBubble,
|
|
316
|
+
// switchRoom,
|
|
317
|
+
// // sendCurrentPageMessage
|
|
318
|
+
// };
|