Started work on personal emotes.
This commit is contained in:
parent
db5fac83ab
commit
a4a1f6a65b
|
|
@ -56,7 +56,8 @@ module.exports = class{
|
||||||
//await this.sendClientMetadata(userDB, socket);
|
//await this.sendClientMetadata(userDB, socket);
|
||||||
await userObj.sendClientMetadata();
|
await userObj.sendClientMetadata();
|
||||||
await userObj.sendSiteEmotes();
|
await userObj.sendSiteEmotes();
|
||||||
await userObj.sendChanEmotes();
|
await userObj.sendChanEmotes(chanDB);
|
||||||
|
await userObj.sendPersonalEmotes(userDB);
|
||||||
|
|
||||||
//Send out the userlist
|
//Send out the userlist
|
||||||
this.broadcastUserList(socket.chan);
|
this.broadcastUserList(socket.chan);
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
//local imports
|
//local imports
|
||||||
const commandPreprocessor = require('./commandPreprocessor');
|
const commandPreprocessor = require('./commandPreprocessor');
|
||||||
const loggerUtils = require('../../utils/loggerUtils');
|
const loggerUtils = require('../../utils/loggerUtils');
|
||||||
|
const linkUtils = require('../../utils/linkUtils');
|
||||||
|
const emoteValidator = require('../../validators/emoteValidator');
|
||||||
const {userModel} = require('../../schemas/userSchema');
|
const {userModel} = require('../../schemas/userSchema');
|
||||||
|
|
||||||
module.exports = class{
|
module.exports = class{
|
||||||
|
|
@ -29,6 +31,7 @@ module.exports = class{
|
||||||
socket.on("chatMessage", (data) => {this.handleChat(socket, data)});
|
socket.on("chatMessage", (data) => {this.handleChat(socket, data)});
|
||||||
socket.on("setFlair", (data) => {this.setFlair(socket, data)});
|
socket.on("setFlair", (data) => {this.setFlair(socket, data)});
|
||||||
socket.on("setHighLevel", (data) => {this.setHighLevel(socket, data)});
|
socket.on("setHighLevel", (data) => {this.setHighLevel(socket, data)});
|
||||||
|
socket.on("addPersonalEmote", (data) => {this.addPersonalEmote(socket, data)});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChat(socket, data){
|
handleChat(socket, data){
|
||||||
|
|
@ -79,6 +82,36 @@ module.exports = class{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async addPersonalEmote(socket, data){
|
||||||
|
//Sanatize and Validate input
|
||||||
|
const name = emoteValidator.manualName(data.name);
|
||||||
|
const link = emoteValidator.manualLink(data.link);
|
||||||
|
|
||||||
|
//If we received good input
|
||||||
|
if(link && name){
|
||||||
|
//Generate marked link object
|
||||||
|
var emote = await linkUtils.markLink(link);
|
||||||
|
|
||||||
|
//If the link we have is an image or video
|
||||||
|
if(emote.type == 'image' || emote.type == 'video'){
|
||||||
|
//Get user document from DB
|
||||||
|
const userDB = await userModel.findOne({user: socket.user.user})
|
||||||
|
|
||||||
|
//if we have a user in the DB
|
||||||
|
if(userDB != null){
|
||||||
|
//Convert marked link into emote object with 1 ez step for only $19.95
|
||||||
|
emote.name = name;
|
||||||
|
|
||||||
|
//add emote to user document emotes list
|
||||||
|
userDB.emotes.push(emote);
|
||||||
|
|
||||||
|
//Save user doc
|
||||||
|
await userDB.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
relayUserChat(socket, msg, type, links){
|
relayUserChat(socket, msg, type, links){
|
||||||
const user = this.server.getSocketInfo(socket);
|
const user = this.server.getSocketInfo(socket);
|
||||||
this.relayChat(user.user, user.flair, user.highLevel, msg, type, socket.chan, links)
|
this.relayChat(user.user, user.flair, user.highLevel, msg, type, socket.chan, links)
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ module.exports = class commandPreprocessor{
|
||||||
|
|
||||||
//split the command
|
//split the command
|
||||||
this.splitCommand();
|
this.splitCommand();
|
||||||
|
|
||||||
//Process the command
|
//Process the command
|
||||||
await this.processServerCommand();
|
await this.processServerCommand();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ const channelModel = require('../../schemas/channel/channelSchema');
|
||||||
const permissionModel = require('../../schemas/permissionSchema');
|
const permissionModel = require('../../schemas/permissionSchema');
|
||||||
const flairModel = require('../../schemas/flairSchema');
|
const flairModel = require('../../schemas/flairSchema');
|
||||||
const emoteModel = require('../../schemas/emoteSchema');
|
const emoteModel = require('../../schemas/emoteSchema');
|
||||||
|
const { userModel } = require('../../schemas/userSchema');
|
||||||
|
|
||||||
module.exports = class{
|
module.exports = class{
|
||||||
constructor(userDB, chanRank, channel, socket){
|
constructor(userDB, chanRank, channel, socket){
|
||||||
|
|
@ -111,6 +112,20 @@ module.exports = class{
|
||||||
this.emit('chanEmotes', emoteList);
|
this.emit('chanEmotes', emoteList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendPersonalEmotes(userDB){
|
||||||
|
//if we wherent handed a channel document
|
||||||
|
if(userDB == null){
|
||||||
|
//Pull it based on channel name
|
||||||
|
userDB = await userModel.findOne({user: this.user});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Pull emotes from channel
|
||||||
|
const emoteList = userDB.getEmotes();
|
||||||
|
|
||||||
|
//Send it off to the user
|
||||||
|
this.emit('personalEmotes', emoteList);
|
||||||
|
}
|
||||||
|
|
||||||
updateFlair(flair){
|
updateFlair(flair){
|
||||||
this.flair = flair;
|
this.flair = flair;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,17 @@ const {mongoose} = require('mongoose');
|
||||||
const {validationResult, matchedData} = require('express-validator');
|
const {validationResult, matchedData} = require('express-validator');
|
||||||
|
|
||||||
//Local Imports
|
//Local Imports
|
||||||
|
//Server
|
||||||
const server = require('../../server');
|
const server = require('../../server');
|
||||||
|
//DB Models
|
||||||
const statModel = require('../statSchema');
|
const statModel = require('../statSchema');
|
||||||
const {userModel} = require('../userSchema');
|
const {userModel} = require('../userSchema');
|
||||||
const permissionModel = require('../permissionSchema');
|
const permissionModel = require('../permissionSchema');
|
||||||
const emoteModel = require('../emoteSchema');
|
const emoteModel = require('../emoteSchema');
|
||||||
|
//DB Schemas
|
||||||
const channelPermissionSchema = require('./channelPermissionSchema');
|
const channelPermissionSchema = require('./channelPermissionSchema');
|
||||||
const channelBanSchema = require('./channelBanSchema');
|
const channelBanSchema = require('./channelBanSchema');
|
||||||
|
//Utils
|
||||||
const { exceptionHandler, errorHandler } = require('../../utils/loggerUtils');
|
const { exceptionHandler, errorHandler } = require('../../utils/loggerUtils');
|
||||||
|
|
||||||
const channelSchema = new mongoose.Schema({
|
const channelSchema = new mongoose.Schema({
|
||||||
|
|
@ -77,7 +81,7 @@ const channelSchema = new mongoose.Schema({
|
||||||
type: mongoose.SchemaTypes.String,
|
type: mongoose.SchemaTypes.String,
|
||||||
required: true
|
required: true
|
||||||
}],
|
}],
|
||||||
//Not re-using the site-wide schema because post save should call different functions
|
//Not re-using the site-wide schema because post/pre save should call different functions
|
||||||
emotes: [{
|
emotes: [{
|
||||||
name:{
|
name:{
|
||||||
type: mongoose.SchemaTypes.String,
|
type: mongoose.SchemaTypes.String,
|
||||||
|
|
@ -178,6 +182,7 @@ channelSchema.pre('save', async function (next){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if emotes where modified
|
||||||
if(this.isModified('emotes')){
|
if(this.isModified('emotes')){
|
||||||
//Get the active Channel object from the application side of the house
|
//Get the active Channel object from the application side of the house
|
||||||
const activeChannel = server.channelManager.activeChannels.get(this.name);
|
const activeChannel = server.channelManager.activeChannels.get(this.name);
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
const {mongoose} = require('mongoose');
|
const {mongoose} = require('mongoose');
|
||||||
|
|
||||||
//local imports
|
//local imports
|
||||||
|
//server
|
||||||
const server = require('../server');
|
const server = require('../server');
|
||||||
|
//DB Models
|
||||||
const statModel = require('./statSchema');
|
const statModel = require('./statSchema');
|
||||||
const flairModel = require('./flairSchema');
|
const flairModel = require('./flairSchema');
|
||||||
const permissionModel = require('./permissionSchema');
|
const permissionModel = require('./permissionSchema');
|
||||||
|
const emoteModel = require('./emoteSchema');
|
||||||
|
//Utils
|
||||||
const hashUtil = require('../utils/hashUtils');
|
const hashUtil = require('../utils/hashUtils');
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -40,7 +44,9 @@ const userSchema = new mongoose.Schema({
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
email: {
|
email: {
|
||||||
type: mongoose.SchemaTypes.String
|
type: mongoose.SchemaTypes.String,
|
||||||
|
optional: true,
|
||||||
|
default: ""
|
||||||
},
|
},
|
||||||
date: {
|
date: {
|
||||||
type: mongoose.SchemaTypes.Date,
|
type: mongoose.SchemaTypes.Date,
|
||||||
|
|
@ -92,7 +98,24 @@ const userSchema = new mongoose.Schema({
|
||||||
type: mongoose.SchemaTypes.ObjectID,
|
type: mongoose.SchemaTypes.ObjectID,
|
||||||
default: null,
|
default: null,
|
||||||
ref: "flair"
|
ref: "flair"
|
||||||
}
|
},
|
||||||
|
//Not re-using the site-wide schema because post/pre save should call different functions
|
||||||
|
emotes: [{
|
||||||
|
name:{
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
link:{
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
type:{
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true,
|
||||||
|
enum: emoteModel.typeEnum,
|
||||||
|
default: emoteModel.typeEnum[0]
|
||||||
|
}
|
||||||
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
//This is one of those places where you really DON'T want to use an arrow function over an anonymous one!
|
//This is one of those places where you really DON'T want to use an arrow function over an anonymous one!
|
||||||
|
|
@ -124,6 +147,15 @@ userSchema.pre('save', async function (next){
|
||||||
await this.killAllSessions("Your site-wide rank has changed. Sign-in required.");
|
await this.killAllSessions("Your site-wide rank has changed. Sign-in required.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if emotes where modified
|
||||||
|
if(this.isModified('emotes')){
|
||||||
|
//Get the active Channel object from the application side of the house
|
||||||
|
server.channelManager.crawlConnections(this.user, (conn)=>{
|
||||||
|
//Send out emotes to each one
|
||||||
|
conn.sendPersonalEmotes(this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
//All is good, continue on saving.
|
//All is good, continue on saving.
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
@ -347,6 +379,24 @@ userSchema.methods.getTokeCount = function(){
|
||||||
return tokeCount;
|
return tokeCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
userSchema.methods.getEmotes = function(){
|
||||||
|
//Create an empty array to hold our emote list
|
||||||
|
const emoteList = [];
|
||||||
|
|
||||||
|
//For each channel emote
|
||||||
|
this.emotes.forEach((emote) => {
|
||||||
|
//Push an object with select information from the emote to the emote list
|
||||||
|
emoteList.push({
|
||||||
|
name: emote.name,
|
||||||
|
link: emote.link,
|
||||||
|
type: emote.type
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//return the emote list
|
||||||
|
return emoteList;
|
||||||
|
}
|
||||||
|
|
||||||
//note: if you gotta call this from a request authenticated by it's user, make sure to kill that session first!
|
//note: if you gotta call this from a request authenticated by it's user, make sure to kill that session first!
|
||||||
userSchema.methods.killAllSessions = async function(reason = "A full log-out from all devices was requested for your account."){
|
userSchema.methods.killAllSessions = async function(reason = "A full log-out from all devices was requested for your account."){
|
||||||
//get authenticated sessions
|
//get authenticated sessions
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,34 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
|
|
||||||
//NPM Imports
|
//NPM Imports
|
||||||
const { check } = require('express-validator');
|
const { check } = require('express-validator');
|
||||||
|
const validator = require('validator');//We need validators for express-less code too!
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: (field = 'name') => check(field).escape().trim().isAlphanumeric().isLength({min: 1, max: 14}),
|
name: (field = 'name') => check(field).escape().trim().isAlphanumeric().isLength({min: 1, max: 14}),
|
||||||
link: (field = 'link') => check(field).trim().isURL()
|
link: (field = 'link') => check(field).trim().isURL(),
|
||||||
|
manualName: (input) => {
|
||||||
|
//Trim and sanatize input
|
||||||
|
const clean = validator.trim(validator.escape(input));
|
||||||
|
|
||||||
|
//if cleaned input is a proper emote name
|
||||||
|
if(validator.isLength(clean, {min: 1, max: 14}) && validator.isAlphanumeric(clean)){
|
||||||
|
//return cleaned input
|
||||||
|
return clean;
|
||||||
|
}
|
||||||
|
|
||||||
|
//otherwise return false
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
manualLink: (input) => {
|
||||||
|
//Trim the input
|
||||||
|
const clean = validator.trim(input)
|
||||||
|
|
||||||
|
//If we have a URL return the trimmed input
|
||||||
|
if(validator.isURL(clean)){
|
||||||
|
return clean;
|
||||||
|
}
|
||||||
|
|
||||||
|
//otherwise return false
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -64,7 +64,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.-->
|
||||||
<option>Flair</option>
|
<option>Flair</option>
|
||||||
</select>
|
</select>
|
||||||
<span class="chat-panel panel-head-spacer-span" id="chat-panel-head-spacer-span"></span>
|
<span class="chat-panel panel-head-spacer-span" id="chat-panel-head-spacer-span"></span>
|
||||||
<p class="chat-panel panel-head-element" id="chat-panel-user-count">NULL Users</p>
|
<p class="chat-panel panel-head-element interactive" id="chat-panel-user-count">NULL Users</p>
|
||||||
<i class="chat-panel panel-head-element bi-caret-down-fill" id="chat-panel-users-toggle"></i>
|
<i class="chat-panel panel-head-element bi-caret-down-fill" id="chat-panel-users-toggle"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="chat-panel" id="chat-panel-main-div">
|
<div class="chat-panel" id="chat-panel-main-div">
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,6 @@ span.user-entry{
|
||||||
#chat-panel-user-count{
|
#chat-panel-user-count{
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
cursor:pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#media-panel-show-chat-icon{
|
#media-panel-show-chat-icon{
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,11 @@ div.dynamic-container{
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.interactive{
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* Navbar */
|
/* Navbar */
|
||||||
#navbar{
|
#navbar{
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,10 @@
|
||||||
div.emote-panel-list-emote{
|
div.emote-panel-list-emote{
|
||||||
width: 9em;
|
width: 9em;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
position: relative;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 0.5em 0;
|
padding: 0.5em 0;
|
||||||
margin: 0.5em;
|
margin: 0.5em;
|
||||||
user-select: none;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,6 +43,7 @@ p.emote-list-title{
|
||||||
max-height: 8em;
|
max-height: 8em;
|
||||||
max-width: 8em;
|
max-width: 8em;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.emote-list-big-media{
|
.emote-list-big-media{
|
||||||
|
|
@ -63,3 +64,19 @@ div.panel-control-prompt{
|
||||||
#new-emote-button{
|
#new-emote-button{
|
||||||
margin-left: 0.3em;
|
margin-left: 0.3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span.emote-list-trash-icon{
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
width: 1.5em;
|
||||||
|
height: 1.5em;
|
||||||
|
border-radius: 1em;
|
||||||
|
top: -0.5em;
|
||||||
|
right: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.emote-list-trash-icon{
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
@ -366,3 +366,8 @@ div.emote-panel-list-emote{
|
||||||
border: 1px solid var(--focus0-alt1);
|
border: 1px solid var(--focus0-alt1);
|
||||||
box-shadow: var(--focus-glow0-alt0), var(--focus-glow0-alt0-inset);
|
box-shadow: var(--focus-glow0-alt0), var(--focus-glow0-alt0-inset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span.emote-list-trash-icon{
|
||||||
|
background-color: var(--bg2);
|
||||||
|
border: 1px solid var(--accent0)
|
||||||
|
}
|
||||||
|
|
@ -32,6 +32,7 @@ class chatPostprocessor{
|
||||||
|
|
||||||
//Inject the pre-processed chat into the chatEntry node
|
//Inject the pre-processed chat into the chatEntry node
|
||||||
this.injectBody();
|
this.injectBody();
|
||||||
|
|
||||||
//Return the pre-processed node
|
//Return the pre-processed node
|
||||||
return this.chatEntry;
|
return this.chatEntry;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ class commandPreprocessor{
|
||||||
//When we receive site-wide emote list
|
//When we receive site-wide emote list
|
||||||
this.client.socket.on("siteEmotes", this.setSiteEmotes.bind(this));
|
this.client.socket.on("siteEmotes", this.setSiteEmotes.bind(this));
|
||||||
this.client.socket.on("chanEmotes", this.setChanEmotes.bind(this));
|
this.client.socket.on("chanEmotes", this.setChanEmotes.bind(this));
|
||||||
|
this.client.socket.on("personalEmotes", this.setPersonalEmotes.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
preprocess(command){
|
preprocess(command){
|
||||||
|
|
@ -104,6 +105,10 @@ class commandPreprocessor{
|
||||||
this.emotes.chan = data;
|
this.emotes.chan = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setPersonalEmotes(data){
|
||||||
|
this.emotes.personal = data;
|
||||||
|
}
|
||||||
|
|
||||||
getEmoteByLink(link){
|
getEmoteByLink(link){
|
||||||
//Create an empty variable to hold the found emote
|
//Create an empty variable to hold the found emote
|
||||||
var foundEmote = null;
|
var foundEmote = null;
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,11 @@ class cPanel{
|
||||||
this.activePanel.docSwitch();
|
this.activePanel.docSwitch();
|
||||||
}
|
}
|
||||||
|
|
||||||
hideActivePanel(){
|
hideActivePanel(event, keepAlive = false){
|
||||||
|
if(!keepAlive){
|
||||||
|
this.activePanel.closer();
|
||||||
|
}
|
||||||
|
|
||||||
//Hide the panel
|
//Hide the panel
|
||||||
this.activePanelDiv.style.display = "none";
|
this.activePanelDiv.style.display = "none";
|
||||||
//Clear out the panel
|
//Clear out the panel
|
||||||
|
|
@ -84,12 +88,12 @@ class cPanel{
|
||||||
|
|
||||||
pinPanel(){
|
pinPanel(){
|
||||||
this.setPinnedPanel(this.activePanel, this.activePanelDoc.innerHTML);
|
this.setPinnedPanel(this.activePanel, this.activePanelDoc.innerHTML);
|
||||||
this.hideActivePanel();
|
this.hideActivePanel(null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
popActivePanel(){
|
popActivePanel(){
|
||||||
this.popPanel(this.activePanel, this.activePanelDoc.innerHTML);
|
this.popPanel(this.activePanel, this.activePanelDoc.innerHTML);
|
||||||
this.hideActivePanel();
|
this.hideActivePanel(null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setPinnedPanel(panel, panelBody){
|
async setPinnedPanel(panel, panelBody){
|
||||||
|
|
@ -113,19 +117,24 @@ class cPanel{
|
||||||
this.pinnedPanelDragger.fixCutoff();
|
this.pinnedPanelDragger.fixCutoff();
|
||||||
}
|
}
|
||||||
|
|
||||||
hidePinnedPanel(){
|
hidePinnedPanel(event, keepAlive = false){
|
||||||
this.pinnedPanelDiv.style.display = "none";
|
this.pinnedPanelDiv.style.display = "none";
|
||||||
|
|
||||||
|
if(!keepAlive){
|
||||||
|
this.pinnedPanel.closer();
|
||||||
|
}
|
||||||
|
|
||||||
this.pinnedPanel = null;
|
this.pinnedPanel = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
unpinPanel(){
|
unpinPanel(){
|
||||||
this.setActivePanel(this.pinnedPanel, this.pinnedPanelDoc.innerHTML);
|
this.setActivePanel(this.pinnedPanel, this.pinnedPanelDoc.innerHTML);
|
||||||
this.hidePinnedPanel();
|
this.hidePinnedPanel(null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
popPinnedPanel(){
|
popPinnedPanel(){
|
||||||
this.popPanel(this.pinnedPanel, this.pinnedPanelDoc.innerHTML);
|
this.popPanel(this.pinnedPanel, this.pinnedPanelDoc.innerHTML);
|
||||||
this.hidePinnedPanel();
|
this.hidePinnedPanel(null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
popPanel(panel, panelBody){
|
popPanel(panel, panelBody){
|
||||||
|
|
@ -154,6 +163,10 @@ class panelObj{
|
||||||
|
|
||||||
docSwitch(){
|
docSwitch(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closer(){
|
||||||
|
console.log('closer');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class poppedPanel{
|
class poppedPanel{
|
||||||
|
|
@ -174,6 +187,8 @@ class poppedPanel{
|
||||||
//Functions
|
//Functions
|
||||||
this.cPanel = cPanel;
|
this.cPanel = cPanel;
|
||||||
|
|
||||||
|
this.keepAlive = false;
|
||||||
|
|
||||||
//Continue constructor asynchrnously
|
//Continue constructor asynchrnously
|
||||||
this.asyncConstructor();
|
this.asyncConstructor();
|
||||||
}
|
}
|
||||||
|
|
@ -221,13 +236,19 @@ class poppedPanel{
|
||||||
}
|
}
|
||||||
|
|
||||||
closer(){
|
closer(){
|
||||||
this.cPanel.poppedPanels.splice(this.cPanel.poppedPanels.indexOf(this),1);
|
if(!this.keepAlive){
|
||||||
|
this.panel.closer();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cPanel.poppedPanels.splice(this.cPanel.poppedPanels.indexOf(this),1);
|
||||||
}
|
}
|
||||||
|
|
||||||
unpop(){
|
unpop(){
|
||||||
//Set active panel
|
//Set active panel
|
||||||
this.cPanel.setActivePanel(this.panel, this.panelDoc.innerHTML);
|
this.cPanel.setActivePanel(this.panel, this.panelDoc.innerHTML);
|
||||||
|
|
||||||
|
this.keepAlive = true;
|
||||||
|
|
||||||
//Close the popped window
|
//Close the popped window
|
||||||
this.window.close();
|
this.window.close();
|
||||||
}
|
}
|
||||||
|
|
@ -235,6 +256,8 @@ class poppedPanel{
|
||||||
pin(){
|
pin(){
|
||||||
this.cPanel.setPinnedPanel(this.panel, this.panelDoc.innerHTML);
|
this.cPanel.setPinnedPanel(this.panel, this.panelDoc.innerHTML);
|
||||||
|
|
||||||
|
this.keepAlive = true;
|
||||||
|
|
||||||
this.window.close();
|
this.window.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,13 @@
|
||||||
class emotePanel extends panelObj{
|
class emotePanel extends panelObj{
|
||||||
constructor(client, panelDocument){
|
constructor(client, panelDocument){
|
||||||
super(client, "Emote Palette", "/panel/emote", panelDocument);
|
super(client, "Emote Palette", "/panel/emote", panelDocument);
|
||||||
|
|
||||||
|
this.client.socket.on("personalEmotes", this.renderEmoteLists.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
closer(){
|
||||||
|
this.client.socket.off("personalEmotes", this.renderEmoteLists.bind(this));
|
||||||
|
console.log('emote closer');
|
||||||
}
|
}
|
||||||
|
|
||||||
docSwitch(){
|
docSwitch(){
|
||||||
|
|
@ -19,6 +26,10 @@ class emotePanel extends panelObj{
|
||||||
|
|
||||||
this.searchPrompt = this.panelDocument.querySelector('#emote-panel-search-prompt');
|
this.searchPrompt = this.panelDocument.querySelector('#emote-panel-search-prompt');
|
||||||
|
|
||||||
|
this.personalEmoteLinkPrompt = this.panelDocument.querySelector('#new-emote-link-input');
|
||||||
|
this.personalEmoteNamePrompt = this.panelDocument.querySelector('#new-emote-name-input');
|
||||||
|
this.personalEmoteAddButton = this.panelDocument.querySelector('#new-emote-button');
|
||||||
|
|
||||||
this.setupInput();
|
this.setupInput();
|
||||||
|
|
||||||
this.renderEmoteLists();
|
this.renderEmoteLists();
|
||||||
|
|
@ -46,6 +57,9 @@ class emotePanel extends panelObj{
|
||||||
|
|
||||||
this.searchPrompt.removeEventListener('keyup', this.renderEmoteLists.bind(this));
|
this.searchPrompt.removeEventListener('keyup', this.renderEmoteLists.bind(this));
|
||||||
this.searchPrompt.addEventListener('keyup', this.renderEmoteLists.bind(this));
|
this.searchPrompt.addEventListener('keyup', this.renderEmoteLists.bind(this));
|
||||||
|
|
||||||
|
this.personalEmoteAddButton.removeEventListener("click", this.addPersonalEmote.bind(this));
|
||||||
|
this.personalEmoteAddButton.addEventListener("click", this.addPersonalEmote.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSiteEmotes(event){
|
toggleSiteEmotes(event){
|
||||||
|
|
@ -72,7 +86,7 @@ class emotePanel extends panelObj{
|
||||||
|
|
||||||
useEmote(emote){
|
useEmote(emote){
|
||||||
//If we're using this from the active panel
|
//If we're using this from the active panel
|
||||||
if(client.cPanel.activePanel == this){
|
if(this.client.cPanel.activePanel == this){
|
||||||
//Close it
|
//Close it
|
||||||
this.client.cPanel.hideActivePanel();
|
this.client.cPanel.hideActivePanel();
|
||||||
}
|
}
|
||||||
|
|
@ -81,6 +95,19 @@ class emotePanel extends panelObj{
|
||||||
this.client.chatBox.chatPrompt.value += `[${emote}]`;
|
this.client.chatBox.chatPrompt.value += `[${emote}]`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addPersonalEmote(event){
|
||||||
|
//Collect input
|
||||||
|
const name = this.personalEmoteNamePrompt.value;
|
||||||
|
const link = this.personalEmoteLinkPrompt.value;
|
||||||
|
|
||||||
|
//Empty out prompts
|
||||||
|
this.personalEmoteNamePrompt.value = '';
|
||||||
|
this.personalEmoteLinkPrompt.value = '';
|
||||||
|
|
||||||
|
//Send emote to server
|
||||||
|
this.client.socket.emit("addPersonalEmote", {name, link});
|
||||||
|
}
|
||||||
|
|
||||||
renderEmoteLists(){
|
renderEmoteLists(){
|
||||||
var search = this.searchPrompt.value;
|
var search = this.searchPrompt.value;
|
||||||
|
|
||||||
|
|
@ -102,10 +129,10 @@ class emotePanel extends panelObj{
|
||||||
|
|
||||||
this.renderEmotes(siteEmotes, this.siteEmoteList);
|
this.renderEmotes(siteEmotes, this.siteEmoteList);
|
||||||
this.renderEmotes(chanEmotes, this.chanEmoteList);
|
this.renderEmotes(chanEmotes, this.chanEmoteList);
|
||||||
this.renderEmotes(personalEmotes, this.personalEmoteList);
|
this.renderEmotes(personalEmotes, this.personalEmoteList, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderEmotes(emoteList, container){
|
renderEmotes(emoteList, container, personal = false){
|
||||||
//Clear out the container
|
//Clear out the container
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
|
|
||||||
|
|
@ -165,6 +192,23 @@ class emotePanel extends panelObj{
|
||||||
//Set emote title
|
//Set emote title
|
||||||
emoteTitle.innerHTML = `[${emote.name}]`;
|
emoteTitle.innerHTML = `[${emote.name}]`;
|
||||||
|
|
||||||
|
//if we're rendering personal emotes
|
||||||
|
if(personal){
|
||||||
|
//create span to hold trash icon
|
||||||
|
const trashSpan = document.createElement('span');
|
||||||
|
trashSpan.classList.add('emote-list-trash-icon');
|
||||||
|
|
||||||
|
//Create trash icon
|
||||||
|
const trashIcon = document.createElement('i');
|
||||||
|
trashIcon.classList.add('emote-list-trash-icon', 'bi-trash-fill');
|
||||||
|
|
||||||
|
//Add trash icon to trash span
|
||||||
|
trashSpan.appendChild(trashIcon);
|
||||||
|
|
||||||
|
//append trash span to emote div
|
||||||
|
emoteDiv.appendChild(trashSpan);
|
||||||
|
}
|
||||||
|
|
||||||
//Add the emote media to the emote span
|
//Add the emote media to the emote span
|
||||||
emoteDiv.appendChild(emoteMedia);
|
emoteDiv.appendChild(emoteMedia);
|
||||||
//Add title paragraph node
|
//Add title paragraph node
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue