Finished up with css-only flair implementation.

This commit is contained in:
rainbownapkin 2024-11-21 08:42:21 -05:00
parent 5b5f495853
commit 9dbbc4e924
13 changed files with 231 additions and 60 deletions

View file

@ -14,6 +14,10 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
//local imports
const flairModel = require('../../schemas/flairSchema');
const permissionModel = require('../../schemas/permissionSchema');
module.exports = class{
constructor(server, name){
this.server = server;
@ -21,7 +25,7 @@ module.exports = class{
this.userList = new Map();
}
handleConnection(userDB, socket){
async handleConnection(userDB, socket){
//get current user object from the userlist
var userObj = this.userList.get(userDB.user);
@ -45,6 +49,9 @@ module.exports = class{
//if everything looks good, admit the connection to the channel
socket.join(socket.chan);
//Make sure the client receives important client-info before userlist
await this.sendClientMetadata(userDB, socket);
//Send out the userlist
this.broadcastUserList(socket.chan);
}
@ -71,13 +78,59 @@ module.exports = class{
this.broadcastUserList(socket.chan);
}
async sendClientMetadata(userObj, socket){
const flairListDB = await flairModel.find({});
var flairList = [];
const user = {
id: userObj.id,
user: userObj.user,
rank: userObj.rank,
flair: userObj.flair
}
flairListDB.forEach((flair)=>{
if(permissionModel.rankToNum(flair.rank) <= permissionModel.rankToNum(userObj.rank)){
flairList.push({
name: flair.name,
displayName: flair.displayName
});
}
});
socket.emit("clientMetadata", {user, flairList});
}
broadcastUserList(){
var userList = [];
this.userList.forEach((userObj, user) => {
userList.push(user);
userList.push({
user: user,
flair: userObj.flair
});
});
this.server.io.in(this.name).emit("user-list", userList);
this.server.io.in(this.name).emit("userList", userList);
}
updateFlair(user, flair){
const userObj = this.userList.get(user);
userObj.flair = flair;
this.userList.set(user, userObj);
//Quick hack to make this compatible with sendClientMetadata. make sure we do this AFTER setting the object in the userList map...
userObj.name = user;
//Crawl through user's sockets (lol)
userObj.sockets.forEach((sockid) => {
//Send metadata to each one
const socket = this.server.io.sockets.sockets.get(sockid);
this.sendClientMetadata(userObj, socket);
});
this.broadcastUserList();
}
}

View file

@ -116,4 +116,19 @@ module.exports = class{
const channel = this.activeChannels.get(socket.chan);
return channel.userList.get(socket.user.user);
}
getConnectedChannels(socket){
var chanList = [];
this.activeChannels.forEach((channel) => {
const foundUser = channel.userList.get(socket.user.user);
//If we found a user and this channel hasn't been added to the list
if(foundUser){
chanList.push(channel);
}
});
return chanList;
}
}

View file

@ -20,7 +20,6 @@ const validator = require('validator');//No express here, so regular validator i
//local imports
const loggerUtils = require('../../utils/loggerUtils');
const userModel = require('../../schemas/userSchema');
const channelManager = require('./channelManager');
module.exports = class{
constructor(server){
@ -54,13 +53,20 @@ module.exports = class{
}
async setFlair(socket, data){
const userDB = await userModel.findOne({user: socket.user.user});
var userDB = await userModel.findOne({user: socket.user.user});
const chanList = this.server.getConnectedChannels(socket)
if(userDB){
try{
//We can take this data raw since our schema checks it against existing flairs, and mongoose sanatizes queries
userDB.flair = data.flair;
await userDB.save();
userDB = await userDB.save();
chanList.forEach((channel) => {
channel.updateFlair(userDB.user, userDB.flair);
});
}catch(err){
return loggerUtils.socketExceptionHandler(socket, err);
}

View file

@ -26,6 +26,10 @@ const flairSchema = new mongoose.Schema({
type: mongoose.SchemaTypes.String,
required: true
},
displayName:{
type: mongoose.SchemaTypes.String,
required: true
},
rank: {
type: mongoose.SchemaTypes.String,
enum: permissionModel.rankEnum,

View file

@ -105,6 +105,10 @@ userSchema.pre('save', async function (next){
//Throw a shit fit. Do not pass go. Do not collect $200.
throw new Error("Invalid flair!");
}
if(permissionModel.rankToNum(this.rank) < permissionModel.rankToNum(foundFlair.rank)){
throw new Error(`User '${this.user}' does not have a high enough rank for flair '${foundFlair.displayName}'!`);
}
}
}

View file

@ -15,4 +15,5 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.-->
<link rel="stylesheet" href="/lib/bootstrap-icons/font/bootstrap-icons.css">
<link rel="stylesheet" type="text/css" href="/css/global.css">
<link rel="stylesheet" type="text/css" href="/css/flair.css">
<link rel="stylesheet" type="text/css" href="/css/theme/movie-night.css">