Skip to content

Commit 7f16aca

Browse files
committed
feat: Add modnotes
1 parent 96d9ec7 commit 7f16aca

1 file changed

Lines changed: 110 additions & 0 deletions

File tree

src/ps/commands/modnote.tsx

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import { HSL, formatText } from 'ps-client/tools';
2+
3+
import { isGlobalBot, prefix } from '@/config/ps';
4+
import { toId } from '@/tools';
5+
import { ChatError } from '@/utils/chatError';
6+
import { Button, Form } from '@/utils/components/ps';
7+
8+
import type { ToTranslate } from '@/i18n/types';
9+
import type { PSCommand } from '@/types/chat';
10+
11+
function isStaff(userString: string): boolean {
12+
return /^[%@*#]/.test(userString);
13+
}
14+
15+
export const command: PSCommand = {
16+
name: 'modnote',
17+
help: 'Creates a modnote in chat.',
18+
syntax: 'CMD [room], [message]',
19+
aliases: ['mn'],
20+
flags: { pmOnly: true, allowPMs: true },
21+
categories: ['utility'],
22+
children: {
23+
open: {
24+
name: 'open',
25+
help: 'Opens the modchat UI.',
26+
syntax: 'CMD [room]',
27+
async run({ message, arg }) {
28+
const targetRoom = toId(arg);
29+
const nonGlobalPrefix = !isGlobalBot ? `/msgroom ${targetRoom},` : '';
30+
31+
message.author.pageHTML(
32+
<center>
33+
<Form value={`${nonGlobalPrefix}/botmsg ${message.parent.status.userid},${prefix}modnote send ${targetRoom}, {msg}`}>
34+
<br />
35+
<br />
36+
<input name="msg" type="text" style={{ width: 500 }} />
37+
<br />
38+
<br />
39+
<input type="submit" value="Modnote" name="Modnote" />
40+
</Form>
41+
</center>,
42+
{ name: `modnote-${targetRoom}` }
43+
);
44+
},
45+
},
46+
send: {
47+
name: 'send',
48+
help: 'Sends a modnote to the given room.',
49+
syntax: 'CMD [room], [message]',
50+
async run({ arg, message, $T, run }) {
51+
const [target, content] = arg.lazySplit(/[,|]/, 1);
52+
const targetRoom = message.parent.getRoom(target);
53+
if (!targetRoom) throw new ChatError($T('INVALID_ROOM_ID'));
54+
const userInRoom = targetRoom.users.find(user => toId(user) === message.author.id);
55+
if (!userInRoom) throw new ChatError($T('NOT_IN_ROOM'));
56+
if (!isStaff(userInRoom)) throw new ChatError($T('ACCESS_DENIED'));
57+
58+
const [h, s, l] = HSL(message.author.id).hsl;
59+
targetRoom.sendHTML(
60+
<div className="infobox">
61+
<div className="chat chatmessage-partbot" style={{ display: 'inline-block' }}>
62+
<small>[MODNOTE] </small>
63+
<strong style={{ color: `hsl(${h},${s}%,${l}%)` }}>
64+
<small>{userInRoom.charAt(0)}</small>
65+
<span className="username" data-roomgroup={userInRoom.charAt(0)} data-name={message.author.name}>
66+
{message.author.name}
67+
</span>
68+
:
69+
</strong>
70+
<em dangerouslySetInnerHTML={{ __html: formatText(content) }} />
71+
</div>
72+
<br />
73+
<span style={{ color: '#444', fontSize: 10 }}>
74+
Note: Only users ranked % and above can see this. Use{' '}
75+
<span style={{ background: '#4444', border: '1px dashed #8884' }}>{prefix}modnote</span> in my DMs to reply.
76+
</span>
77+
</div>,
78+
{ rank: '*' }
79+
);
80+
81+
run(`modnote open ${targetRoom.id}`);
82+
},
83+
},
84+
},
85+
async run({ arg, message, run }) {
86+
if (!arg) {
87+
const rooms = [
88+
...message.parent.rooms.values().filter(room => room.users.find(user => toId(user) === message.author.id && isStaff(user))),
89+
];
90+
if (!rooms.length) throw new ChatError("We don't have any common rooms where you're staff..." as ToTranslate);
91+
if (rooms.length === 1) return run(`modnote open ${rooms[0].id}`);
92+
93+
message.author.sendHTML(
94+
<>
95+
Which room?
96+
<br />
97+
{rooms.map(room => (
98+
<Button
99+
value={`${!isGlobalBot ? `/msgroom ${room.id},` : ''}/botmsg ${message.parent.status.userid},${prefix}modnote open ${room.id}`}
100+
>
101+
{room.title}
102+
</Button>
103+
))}
104+
</>
105+
);
106+
return;
107+
}
108+
return run(`modnote send ${arg}`);
109+
},
110+
};

0 commit comments

Comments
 (0)