Spaces:
Running
Running
File size: 7,178 Bytes
5c2ed06 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
import { FS, Utils } from '../../lib';
const STORAGE_PATH = 'config/chat-plugins/quotes.json';
const MAX_QUOTES = 300;
interface Quote {
userid: string;
quote: string;
date: number;
}
const quotes: { [room: string]: Quote[] } = JSON.parse(FS(STORAGE_PATH).readIfExistsSync() || "{}");
// migrate quotes out of roomsettings
function convertOldQuotes() {
for (const room of Rooms.rooms.values()) {
if ((room.settings as any).quotes) {
quotes[room.roomid] = (room.settings as any).quotes;
delete (room.settings as any).quotes;
room.saveSettings();
saveQuotes();
}
}
}
function saveQuotes() {
FS(STORAGE_PATH).writeUpdate(() => JSON.stringify(quotes));
}
convertOldQuotes();
export const commands: Chat.ChatCommands = {
randquote(target, room, user) {
room = this.requireRoom();
const roomQuotes = quotes[room.roomid];
if (!roomQuotes?.length) return this.errorReply(`This room has no quotes.`);
this.runBroadcast(true);
const { quote, date, userid } = roomQuotes[Math.floor(Math.random() * roomQuotes.length)];
const time = Chat.toTimestamp(new Date(date), { human: true });
const attribution = toID(target) === 'showauthor' ? `<hr /><small>Added by ${userid} on ${time}</small>` : '';
return this.sendReplyBox(`${Chat.getReadmoreBlock(quote)}${attribution}`);
},
randquotehelp: [`/randquote [showauthor] - Show a random quote from the room. Add 'showauthor' to see who added it and when.`],
addquote(target, room, user) {
room = this.requireRoom();
if (!room.persist) {
return this.errorReply("This command is unavailable in temporary rooms.");
}
target = target.trim();
this.checkCan('mute', null, room);
if (!target) {
return this.parse(`/help addquote`);
}
if (!quotes[room.roomid]) quotes[room.roomid] = [];
const roomQuotes = quotes[room.roomid];
if (this.filter(target) !== target) {
return this.errorReply(`Invalid quote.`);
}
if (roomQuotes.filter(item => item.quote === target).length) {
return this.errorReply(`"${target}" is already quoted in this room.`);
}
if (target.length > 8192) {
return this.errorReply(`Your quote cannot exceed 8192 characters.`);
}
if (room.settings.isPrivate && roomQuotes.length >= MAX_QUOTES) {
return this.errorReply(`This room already has ${MAX_QUOTES} quotes, which is the maximum for private rooms.`);
}
roomQuotes.push({ userid: user.id, quote: target, date: Date.now() });
saveQuotes();
this.refreshPage(`quotes-${room.roomid}`);
const collapsedQuote = target.replace(/\n/g, ' ');
this.privateModAction(`${user.name} added a new quote: "${collapsedQuote}".`);
return this.modlog(`ADDQUOTE`, null, collapsedQuote);
},
addquotehelp: [`/addquote [quote] - Adds [quote] to the room's quotes. Requires: % @ # ~`],
removequote(target, room, user) {
room = this.requireRoom();
this.checkCan('mute', null, room);
if (!quotes[room.roomid]?.length) return this.errorReply(`This room has no quotes.`);
const roomQuotes = quotes[room.roomid];
const index = toID(target) === 'last' ? roomQuotes.length - 1 : parseInt(toID(target)) - 1;
if (isNaN(index)) {
return this.errorReply(`Invalid index.`);
}
if (!roomQuotes[index]) {
return this.errorReply(`Quote not found.`);
}
const [removed] = roomQuotes.splice(index, 1);
const collapsedQuote = removed.quote.replace(/\n/g, ' ');
this.privateModAction(`${user.name} removed quote indexed at ${index + 1}: "${collapsedQuote}" (originally added by ${removed.userid}).`);
this.modlog(`REMOVEQUOTE`, null, collapsedQuote);
saveQuotes();
this.refreshPage(`quotes-${room.roomid}`);
},
removequotehelp: [`/removequote [index] - Removes the quote from the room's quotes. Requires: % @ # ~`],
viewquote(target, room, user) {
room = this.requireRoom();
const roomQuotes = quotes[room.roomid];
if (!roomQuotes?.length) return this.errorReply(`This room has no quotes.`);
const [num, showAuthor] = Utils.splitFirst(target, ',');
const index = num === 'last' ? roomQuotes.length - 1 : parseInt(num) - 1;
if (isNaN(index)) {
return this.errorReply(`Invalid index.`);
}
if (!roomQuotes[index]) {
return this.errorReply(`Quote not found.`);
}
this.runBroadcast(true);
const { quote, date, userid } = roomQuotes[index];
const time = Chat.toTimestamp(new Date(date), { human: true });
const attribution = toID(showAuthor) === 'showauthor' ? `<hr /><small>Added by ${userid} on ${time}</small>` : '';
return this.sendReplyBox(`${Chat.formatText(quote, false, true)}${attribution}`);
},
viewquotehelp: [
`/viewquote [index][, params] - View the quote from the room's quotes.`,
`If 'showauthor' is used for the [params] argument, it shows who added the quote and when.`,
],
viewquotes: 'quotes',
quotes(target, room) {
const targetRoom = target ? Rooms.search(target) : room;
if (!targetRoom) return this.errorReply(`Invalid room.`);
this.parse(`/join view-quotes-${targetRoom.roomid}`);
},
quoteshelp: [`/quotes [room] - Shows all quotes for [room]. Defaults the room the command is used in.`],
quote() {
this.sendReply(`/quote as a method of adding quotes has been deprecated. Use /addquote instead.`);
return this.parse(`/help quote`);
},
quotehelp: [
"/randquote [showauthor] - Show a random quote from the room. Add 'showauthor' to see who added it and when.",
"/removequote [index] - Removes the quote from the room's quotes. Requires: % @ # ~",
"/viewquote [index][, params] - View the quote from the room's quotes.",
"If 'showauthor' is used for the [params] argument, it shows who added the quote and when.",
"/quotes [room] - Shows all quotes for [room]. Defaults the room the command is used in.",
],
};
export const pages: Chat.PageTable = {
quotes(args, user) {
const room = this.requireRoom();
this.title = `[Quotes]`;
// allow it for users if they can access the room
if (!room.checkModjoin(user)) {
return this.errorReply(`Access denied.`);
}
let buffer = `<div class="pad">`;
buffer += `<button style="float:right;" class="button" name="send" value="/join view-quotes-${room.roomid}"><i class="fa fa-refresh"></i> Refresh</button>`;
const roomQuotes = quotes[room.roomid];
if (!roomQuotes?.length) {
return `${buffer}<h2>This room has no quotes.</h2></div>`;
}
buffer += Utils.html`<h2>Quotes for ${room.title} (${roomQuotes.length}):</h2>`;
for (const [i, quoteObj] of roomQuotes.entries()) {
const index = i + 1;
const { quote, userid, date } = quoteObj;
buffer += `<div class="infobox">#${index}: ${Chat.formatText(quote, false, true)}`;
buffer += `<br /><hr /><small>Added by ${userid} on ${Chat.toTimestamp(new Date(date), { human: true })}</small>`;
if (user.can('mute', null, room)) {
buffer += ` <button class="button" name="send" value="/msgroom ${room.roomid},/removequote ${index}">Remove</button>`;
}
buffer += `</div>`;
}
buffer += `</div>`;
return buffer;
},
};
export const handlers: Chat.Handlers = {
onRenameRoom(oldID, newID) {
if (quotes[oldID]) {
if (!quotes[newID]) quotes[newID] = [];
quotes[newID].push(...quotes[oldID]);
delete quotes[oldID];
saveQuotes();
}
},
};
|