/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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/>.*/
//NPM Imports
const {mongoose} = require('mongoose');
//Local Imports
const defaultEmote = require("../../defaultEmotes.json");
const server = require('../server');
/**
* "Enum" for emote type property
*/
const typeEnum = ["image", "video"];
/**
* DB Schema for documents represnting site-wide emotes
*/
const emoteSchema = new mongoose.Schema({
name:{
type: mongoose.SchemaTypes.String,
required: true,
maxLength: 14,
},
link:{
type: mongoose.SchemaTypes.String,
required: true
},
type:{
type: mongoose.SchemaTypes.String,
required: true,
enum: typeEnum,
default: typeEnum[0]
}
});
/**
* Post-Save function, ensures all new emotes are broadcastes to actively connected clients
*/
emoteSchema.post('save', async function (next){
//broadcast updated emotes
server.channelManager.broadcastSiteEmotes();
});
/**
* Post-Delete function, ensures all deleted emotes are removed from actively connected clients
*/
emoteSchema.post('deleteOne', {document: true}, async function (next){
//broadcast updated emotes
server.channelManager.broadcastSiteEmotes();
});
//statics
/**
* Loads un-loaded emotes from defaultEmotes.json
*/
emoteSchema.statics.loadDefaults = async function(){
//Make sure registerEmote function is happy
const _this = this;
//Ensure default comes first (.bind(this) doesn't seem to work here...)
await registerEmote(defaultEmote.default);
//For each entry in the defaultEmote.json file
defaultEmote.array.forEach(registerEmote);
async function registerEmote(emote){
try{
//Look for emote matching the one from our file
const foundEmote = await _this.findOne({name: emote.name});
//if the emote doesn't exist
if(!foundEmote){
const emoteDB = await _this.create(emote);
console.log(`Loading default emote [${emote.name}] into DB from defaultEmote.json`);
}
}catch(err){
if(emote != null){
console.log(`Error loading emote [${emote.name}]:`);
}else{
console.log("Error, null emote:");
}
}
}
}
/**
* Generates a network-friendly browser-digestable list of emotes
* @returns {Object} - network-friendly browser-digestable list of emotes
*/
emoteSchema.statics.getEmotes = async function(){
//Create an empty array to hold our emote list
const emoteList = [];
//Pull emotes from database
const emoteDB = await this.find({});
emoteDB.forEach((emote) => {
emoteList.push({
name: emote.name,
link: emote.link,
type: emote.type
});
});
return emoteList;
}
emoteSchema.statics.typeEnum = typeEnum;
module.exports = mongoose.model("emote", emoteSchema);