Finished up with css-only flair implementation.
This commit is contained in:
parent
5b5f495853
commit
9dbbc4e924
|
|
@ -1,10 +1,17 @@
|
|||
[
|
||||
{
|
||||
"name": "glitter",
|
||||
"name": "gold",
|
||||
"displayName": "Gold",
|
||||
"rank": "gold"
|
||||
},
|
||||
{
|
||||
"name": "negativeGlitter",
|
||||
"ranke": "gold"
|
||||
"name": "black-gold",
|
||||
"displayName": "Black Gold",
|
||||
"rank": "gold"
|
||||
},
|
||||
{
|
||||
"name": "lightning",
|
||||
"displayName": "Lightning",
|
||||
"rank": "gold"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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}'!`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
@ -202,6 +202,7 @@ input#chat-panel-prompt{
|
|||
.user-entry{
|
||||
margin: 0.2em;
|
||||
font-size: 1em;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
#media-panel-aspect-lock-icon{
|
||||
|
|
|
|||
16
www/css/flair.css
Normal file
16
www/css/flair.css
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
.flair-gold, .flair-black-gold, .flair-lightning{
|
||||
background-image: url('/img/flair/gold.gif');
|
||||
border-radius: 0.3em;
|
||||
box-shadow: 0.1em 0.1em 3px #fff4b6 inset, -0.1em 0.1em 3px #fff4b6 inset, 0.1em -0.1em 3px #fff4b6 inset, -0.1em -0.1em 3px #fff4b6 inset;
|
||||
color: rgb(121, 106, 23);
|
||||
text-shadow: 1px 1px 1px #fff4b6, -1px 1px 1px #fff4b6, 1px -1px 1px #fff4b6, -1px -1px 1px #fff4b6;
|
||||
padding: 0.1em 0.4em;
|
||||
}
|
||||
|
||||
.flair-black-gold{
|
||||
filter: invert(1) grayscale(0.9);
|
||||
}
|
||||
|
||||
.flair-lightning{
|
||||
filter: invert(1) grayscale(0.5);
|
||||
}
|
||||
BIN
www/img/flair/gold.gif
Normal file
BIN
www/img/flair/gold.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 694 KiB |
|
|
@ -43,9 +43,19 @@ class channel{
|
|||
document.title = `${this.channelName} - Connected`
|
||||
});
|
||||
|
||||
this.socket.on("error", (data) => {
|
||||
console.log(data);
|
||||
});
|
||||
this.socket.on("clientMetadata", this.handleClientInfo.bind(this));
|
||||
|
||||
this.socket.on("error", console.log);
|
||||
}
|
||||
|
||||
handleClientInfo(data){
|
||||
this.user = {
|
||||
id: data.user.id,
|
||||
name: data.user.name,
|
||||
rank: data.user.rank
|
||||
}
|
||||
|
||||
this.chatBox.handleClientInfo(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ class chatBox{
|
|||
|
||||
//Element Nodes
|
||||
this.chatPanel = document.querySelector("#chat-panel-div");
|
||||
this.highLevel = document.querySelector("#chat-panel-high-level-select");
|
||||
this.highSelect = document.querySelector("#chat-panel-high-level-select");
|
||||
this.flairSelect = document.querySelector("#chat-panel-flair-select");
|
||||
this.chatBuffer = document.querySelector("#chat-panel-buffer-div");
|
||||
this.chatPrompt = document.querySelector("#chat-panel-prompt");
|
||||
this.settingsIcon = document.querySelector("#chat-panel-settings-icon");
|
||||
|
|
@ -57,6 +58,7 @@ class chatBox{
|
|||
this.aspectLockIcon.addEventListener("click", this.lockAspect.bind(this));
|
||||
this.showChatIcon.addEventListener("click", ()=>{this.toggleUI()});
|
||||
this.hideChatIcon.addEventListener("click", ()=>{this.toggleUI()});
|
||||
this.flairSelect.addEventListener("change", this.setFlair.bind(this));
|
||||
|
||||
//Clickdragger/Resize
|
||||
this.clickDragger.handle.addEventListener("mousedown", this.unlockAspect.bind(this));
|
||||
|
|
@ -69,6 +71,92 @@ class chatBox{
|
|||
});
|
||||
}
|
||||
|
||||
displayChat(chat){
|
||||
//Create chat-entry span
|
||||
var chatEntry = document.createElement('span');
|
||||
chatEntry.classList.add("chat-panel-buffer","chat-entry",`chat-entry-${chat.user}`);
|
||||
|
||||
//Create high-level label
|
||||
var highLevel = document.createElement('p');
|
||||
highLevel.classList.add("chat-panel-buffer","chat-entry-high-level");
|
||||
highLevel.innerHTML = `${chat.high}`;
|
||||
chatEntry.appendChild(highLevel);
|
||||
|
||||
//Create username label
|
||||
var userLabel = document.createElement('p');
|
||||
userLabel.classList.add("chat-panel-buffer","chat-entry-username");
|
||||
|
||||
if(chat.flair != ""){
|
||||
var flair = `flair-${chat.flair}`;
|
||||
}else{
|
||||
var flair = this.client.userList.colorMap.get(chat.user);
|
||||
}
|
||||
|
||||
//Create color span
|
||||
var colorSpan = document.createElement('span');
|
||||
colorSpan.classList.add("chat-entry-flair-span", flair);
|
||||
colorSpan.innerHTML = `${chat.user}`;
|
||||
userLabel.innerHTML = `${colorSpan.outerHTML}: `;
|
||||
|
||||
chatEntry.appendChild(userLabel);
|
||||
|
||||
//Create chat body
|
||||
var chatBody = document.createElement('p');
|
||||
chatBody.classList.add("chat-panel-buffer","chat-entry-body");
|
||||
chatBody.innerHTML = chat.msg;
|
||||
chatEntry.appendChild(chatBody);
|
||||
|
||||
this.chatBuffer.appendChild(chatEntry);
|
||||
}
|
||||
|
||||
async send(event){
|
||||
if((!event || !event.key || event.key == "Enter") && this.chatPrompt.value){
|
||||
this.client.socket.emit("chatMessage",{msg: this.chatPrompt.value, high: this.highSelect.value});
|
||||
this.chatPrompt.value = "";
|
||||
}
|
||||
}
|
||||
|
||||
handleClientInfo(data){
|
||||
this.updateFlairSelect(data.flairList, data.user.flair);
|
||||
}
|
||||
|
||||
setFlair(event){
|
||||
const flair = event.target.value;
|
||||
|
||||
this.client.socket.emit("setFlair", {flair});
|
||||
}
|
||||
|
||||
|
||||
|
||||
updateFlairSelect(flairList, flair){
|
||||
//clear current flair select
|
||||
this.flairSelect.innerHTML = "";
|
||||
|
||||
//Inject flair object for standard flair like the hack we are
|
||||
flairList.push({
|
||||
name: "",
|
||||
displayName: "Classic"
|
||||
});
|
||||
|
||||
//For each flair in flairlist
|
||||
flairList.forEach((flair) => {
|
||||
//Create an option
|
||||
var flairOption = document.createElement('option');
|
||||
//Set the name and innerHTML
|
||||
flairOption.value = flair.name;
|
||||
flairOption.innerHTML = flair.displayName;
|
||||
|
||||
//Append it to the select
|
||||
this.flairSelect.appendChild(flairOption);
|
||||
});
|
||||
|
||||
//Set the selected flair in the UI
|
||||
this.flairSelect.value = flair;
|
||||
//Re-style the UI, do this in two seperate steps in-case we're running for the first time and have nothing to replace.
|
||||
this.flairSelect.className = this.flairSelect.className.replace(/flair-\S*/, "");
|
||||
this.flairSelect.classList.add(`flair-${flair}`);
|
||||
}
|
||||
|
||||
lockAspect(event){
|
||||
//prevent the user from breaking shit :P
|
||||
if(this.chatPanel.style.display != "none"){
|
||||
|
|
@ -112,44 +200,4 @@ class chatBox{
|
|||
this.client.player.hideVideoIcon.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
displayChat(chat){
|
||||
//Create chat-entry span
|
||||
var chatEntry = document.createElement('span');
|
||||
chatEntry.classList.add("chat-panel-buffer","chat-entry",`chat-entry-${chat.user}`);
|
||||
|
||||
//Create high-level label
|
||||
var highLevel = document.createElement('p');
|
||||
highLevel.classList.add("chat-panel-buffer","chat-entry-high-level");
|
||||
highLevel.innerHTML = `${chat.high}`;
|
||||
chatEntry.appendChild(highLevel);
|
||||
|
||||
//Create username label
|
||||
var userLabel = document.createElement('p');
|
||||
userLabel.classList.add("chat-panel-buffer","chat-entry-username");
|
||||
|
||||
//Create color span
|
||||
var colorSpan = document.createElement('span');
|
||||
colorSpan.classList.add(this.client.userList.colorMap.get(chat.user));
|
||||
colorSpan.innerHTML = `${chat.user}`;
|
||||
userLabel.innerHTML = `${colorSpan.outerHTML}: `;
|
||||
|
||||
chatEntry.appendChild(userLabel);
|
||||
|
||||
//Create chat body
|
||||
var chatBody = document.createElement('p');
|
||||
chatBody.classList.add("chat-panel-buffer","chat-entry-body");
|
||||
chatBody.innerHTML = chat.msg;
|
||||
chatEntry.appendChild(chatBody);
|
||||
|
||||
this.chatBuffer.appendChild(chatEntry);
|
||||
}
|
||||
|
||||
async send(event){
|
||||
if((!event || !event.key || event.key == "Enter") && this.chatPrompt.value){
|
||||
this.client.socket.emit("chatMessage",{msg: this.chatPrompt.value, high: this.highLevel.value});
|
||||
this.chatPrompt.value = "";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ class userList{
|
|||
}
|
||||
|
||||
defineListeners(){
|
||||
this.client.socket.on('user-list', (data) => {
|
||||
this.client.socket.on('userList', (data) => {
|
||||
this.updateList(data);
|
||||
});
|
||||
}
|
||||
|
|
@ -72,12 +72,12 @@ class userList{
|
|||
var color = this.userColors[Math.floor(Math.random()*this.userColors.length)]
|
||||
|
||||
//if this user was in the previous colormap
|
||||
if(this.colorMap.get(user) != null){
|
||||
if(this.colorMap.get(user.user) != null){
|
||||
//Override with previous color
|
||||
color = this.colorMap.get(user);
|
||||
color = this.colorMap.get(user.user);
|
||||
}
|
||||
|
||||
newMap.set(user, color);
|
||||
newMap.set(user.user, color);
|
||||
this.renderUser(user, color);
|
||||
});
|
||||
|
||||
|
|
@ -87,8 +87,14 @@ class userList{
|
|||
renderUser(user, color){
|
||||
var userEntry = document.createElement('p');
|
||||
|
||||
userEntry.innerText = user;
|
||||
userEntry.id = `user-entry-${user}`;
|
||||
userEntry.innerText = user.user;
|
||||
userEntry.id = `user-entry-${user.user}`;
|
||||
|
||||
//Override color with flair
|
||||
if(user.flair != ""){
|
||||
color = `flair-${user.flair}`;
|
||||
}
|
||||
|
||||
userEntry.classList.add("chat-panel-users","user-entry",color);
|
||||
|
||||
this.userList.appendChild(userEntry);
|
||||
|
|
|
|||
Loading…
Reference in a new issue