Skip to content

Commit bed2de3

Browse files
committed
Invite notifications
1 parent 9231f92 commit bed2de3

15 files changed

Lines changed: 671 additions & 11 deletions

File tree

server-src/commands.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,14 @@ class CommandHandler {
255255
addCommand(
256256
"popcat",
257257
function (args, userInfo, senderClient) {
258-
sendClientCommand(senderClient, "popcat", args[0]);
258+
var numb = +args[0] || 5;
259+
if (numb > 5) {
260+
numb = 5;
261+
}
262+
if (numb < 0.1) {
263+
numb = 0.1;
264+
}
265+
sendClientCommand(senderClient, "popcat", numb);
259266
},
260267
"<Seconds>[br]Pop pop pop pop pop",
261268
true

server-src/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ e.MAX_SOCKETS_PER_GUEST_IP = 30; //Max user guest connected sockets.
2525

2626
e.DISPLAYNAME_CHAR_SET =
2727
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~`!@#$%^&*()-_=+{[]}|\\'\";:/?.>,<";
28+
e.MAX_NOTIFICATIONS = 20; //Max real time notifcations per user.
2829

2930
module.exports = e;

server-src/server.js

Lines changed: 129 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,109 @@ function generateWebsocketID() {
12661266
return _websocketIDCounter + "_" + Math.round(Math.random() * 9999999);
12671267
}
12681268

1269+
var notifyWSS = new ws.WebSocketServer({ noServer: true, ...wssServerOptions });
1270+
var notificationsForUsers = {};
1271+
var notificationUserTimeouts = {};
1272+
notifyWSS.on("connection", (ws, request) => {
1273+
(async function () {
1274+
var usercookie = getCookie("account", getCookieFromRequest(request));
1275+
if (usercookie) {
1276+
var decryptedUserdata = encryptor.decrypt(usercookie);
1277+
decryptedUserdata.username = (decryptedUserdata.username || "")
1278+
.toLowerCase()
1279+
.trim();
1280+
var validation = await validateUserCookie(decryptedUserdata);
1281+
if (validation.valid) {
1282+
ws._rrUsername = decryptedUserdata.username.toLowerCase().trim();
1283+
ws._rrDisplayName = validation.displayName;
1284+
} else {
1285+
ws.terminate();
1286+
return;
1287+
}
1288+
} else {
1289+
ws.terminate();
1290+
return;
1291+
}
1292+
terminateGhostSockets(ws);
1293+
if (!notificationsForUsers[ws._rrUsername]) {
1294+
notificationsForUsers[ws._rrUsername] = [];
1295+
}
1296+
clearTimeout(notificationUserTimeouts[ws._rrUsername]);
1297+
notificationUserTimeouts[ws._rrUsername] = undefined;
1298+
ws.on("message", (data) => {
1299+
var json = JSON.parse(data.toString());
1300+
if (json.type == "read") {
1301+
if (typeof json.id == "number") {
1302+
notificationsForUsers[ws._rrUsername] = notificationsForUsers[
1303+
ws._rrUsername
1304+
].filter((n) => json.id !== n.id);
1305+
for (var client of notifyWSS.clients) {
1306+
if (client._rrUsername == ws._rrUsername) {
1307+
client.send(
1308+
JSON.stringify({
1309+
type: "current",
1310+
notifications: notificationsForUsers[ws._rrUsername],
1311+
})
1312+
);
1313+
}
1314+
}
1315+
}
1316+
}
1317+
if (json.type == "readAll") {
1318+
notificationsForUsers[ws._rrUsername] = [];
1319+
for (var client of notifyWSS.clients) {
1320+
if (client._rrUsername == ws._rrUsername) {
1321+
client.send(
1322+
JSON.stringify({
1323+
type: "current",
1324+
notifications: notificationsForUsers[ws._rrUsername],
1325+
})
1326+
);
1327+
}
1328+
}
1329+
}
1330+
});
1331+
ws.on("close", () => {
1332+
notificationUserTimeouts[ws._rrUsername] = setTimeout(
1333+
() => {
1334+
notificationsForUsers[ws._rrUsername] = undefined;
1335+
notificationUserTimeouts[ws._rrUsername] = undefined;
1336+
},
1337+
1000 * 60 * 10
1338+
); //10 Minutes before all notifications are cleared.
1339+
});
1340+
ws.send(
1341+
JSON.stringify({
1342+
type: "current",
1343+
notifications: notificationsForUsers[ws._rrUsername],
1344+
})
1345+
);
1346+
})();
1347+
});
1348+
function sendNotify(username, notifyjson = {}) {
1349+
if (!notificationsForUsers[username]) {
1350+
notificationsForUsers[username] = [];
1351+
}
1352+
var notifyContent = {
1353+
id: Date.now(),
1354+
...notifyjson,
1355+
};
1356+
notificationsForUsers[username].push(notifyContent);
1357+
notificationsForUsers[username] = notificationsForUsers[username].slice(
1358+
-cons.MAX_NOTIFICATIONS
1359+
);
1360+
for (var client of notifyWSS.clients) {
1361+
if (client._rrUsername == username.trim()) {
1362+
client.send(
1363+
JSON.stringify({
1364+
type: "new",
1365+
notification: notifyContent,
1366+
})
1367+
);
1368+
}
1369+
}
1370+
}
1371+
12691372
async function startRoomWSS(roomid) {
12701373
var wss = new ws.WebSocketServer({ noServer: true, ...wssServerOptions });
12711374
roomWebsockets[roomid.toString()] = "loading";
@@ -1482,6 +1585,9 @@ async function startRoomWSS(roomid) {
14821585
};
14831586
if (usercookie) {
14841587
var decryptedUserdata = encryptor.decrypt(usercookie);
1588+
decryptedUserdata.username = (decryptedUserdata.username || "")
1589+
.toLowerCase()
1590+
.trim();
14851591
var validation = await validateUserCookie(decryptedUserdata);
14861592
for (var cli of wss.clients) {
14871593
if (cli._rrUsername && cli._rrLoggedIn) {
@@ -1891,8 +1997,6 @@ async function startRoomWSS(roomid) {
18911997
);
18921998
return;
18931999
}
1894-
messageChatNumber += 1;
1895-
wss._rrRoomMessages = wss._rrRoomMessages.slice(-100);
18962000
wss.clients.forEach((cli) => {
18972001
if (!cli._rrIsReady) {
18982002
return;
@@ -1914,13 +2018,15 @@ async function startRoomWSS(roomid) {
19142018

19152019
if (!json.message.trim().startsWith(";")) {
19162020
//Filter out command messages in history.
2021+
messageChatNumber += 1;
19172022
wss._rrRoomMessages.push({
19182023
displayName: displayName,
19192024
username: ws._rrUsername,
19202025
message: json.message,
19212026
color: ws._rrUserColor,
19222027
font: ws._rrUserFont,
19232028
});
2029+
wss._rrRoomMessages = wss._rrRoomMessages.slice(-50);
19242030
}
19252031
}
19262032
}
@@ -3954,6 +4060,12 @@ const server = http.createServer(async function (req, res) {
39544060
}
39554061
}
39564062
profilejson.rooms = rooms;
4063+
sendNotify(json.username.toLowerCase().trim(), {
4064+
type: "invite",
4065+
from: decryptedUserdata.username.toLowerCase().trim(),
4066+
roomName: json.name,
4067+
roomID: json.id,
4068+
});
39574069
await storage.uploadFile(
39584070
profileFile,
39594071
JSON.stringify(profilejson),
@@ -4470,6 +4582,12 @@ server.on("upgrade", async function upgrade(request, socket, head) {
44704582
var id = urlsplit[1];
44714583
var wss = null;
44724584
try {
4585+
if (id == "notifications") {
4586+
notifyWSS.handleUpgrade(request, socket, head, function done(ws) {
4587+
notifyWSS.emit("connection", ws, request);
4588+
});
4589+
return;
4590+
}
44734591
if (id) {
44744592
id = id.toLowerCase();
44754593
var roomWs = roomWebsockets[id.toString()];
@@ -4514,6 +4632,15 @@ setInterval(() => {
45144632
debugLogOnlineSockets();
45154633
}, 2000);*/
45164634

4635+
/*setInterval(() => {
4636+
for (var username of Object.keys(notificationsForUsers)) {
4637+
sendNotify(username, {
4638+
type: "test",
4639+
});
4640+
console.log("Send to: " + username);
4641+
}
4642+
}, 5000);*/
4643+
45174644
var serverPort = 3000;
45184645
if (process.env.serverPort) {
45194646
serverPort = Number(process.env.serverPort);

src/chat/elementjson/chat-styles.css

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,3 +1560,52 @@ a {
15601560
background: #23d100;
15611561
cursor: pointer;
15621562
}
1563+
1564+
.notificationDot {
1565+
position: absolute;
1566+
top: 2px;
1567+
left: 23px;
1568+
color: white;
1569+
background: rgb(189, 0, 0);
1570+
border-radius: 30%;
1571+
font-size: 12px;
1572+
font-weight: bold;
1573+
pointer-events: none;
1574+
padding: 2px 4px;
1575+
}
1576+
.notificationImage {
1577+
width: 40px;
1578+
height: 40px;
1579+
transition: 0.05s;
1580+
filter: brightness(1);
1581+
position: absolute;
1582+
}
1583+
.notificationImage:hover {
1584+
filter: brightness(10);
1585+
}
1586+
1587+
.notificationsDiv {
1588+
display: flex;
1589+
flex-direction: column;
1590+
}
1591+
1592+
.notificationContainer {
1593+
height: fit-content;
1594+
padding: 10px 10px;
1595+
background: hsl(
1596+
var(--accent-default-hue),
1597+
var(--accent-default-saturation),
1598+
78%
1599+
);
1600+
border-color: hsl(
1601+
var(--accent-default-hue),
1602+
var(--accent-default-saturation),
1603+
40%
1604+
);
1605+
border-style: solid;
1606+
border-width: 4px;
1607+
border-radius: 5px;
1608+
color: hsl(var(--accent-default-hue), var(--accent-default-saturation), 15%);
1609+
margin-bottom: 10px;
1610+
filter: drop-shadow(4px 4px 3px rgba(0, 0, 0, 0.4));
1611+
}

0 commit comments

Comments
 (0)