Autobump system and UI complete. The bulk of this update is now over.

Just a couple of bug fixes and tweaks before release.
This commit is contained in:
rainbownapkin 2022-08-21 21:26:53 +00:00
parent c9fb5b0b0e
commit 85fbe6bb5a
9 changed files with 925 additions and 72 deletions

147
README.md
View file

@ -232,7 +232,7 @@ dev goals for 1.1 pineapple express:
- reset toke cooldown every hour at *:19:30 for 4:20 !tokes ✓ - reset toke cooldown every hour at *:19:30 for 4:20 !tokes ✓
- extend toke until *:20:00 if it ends after *:19:30 but before *:20:00 ✓ - extend toke until *:20:00 if it ends after *:19:30 but before *:20:00 ✓
- autobump - autobump
- Serverside ✓ - Serverside ✓
- Bump Management System ✓ - Bump Management System ✓
- bump object: name, user(person who made bump, optional), lowername, resettoke bool, id, listname, media item ✓ - bump object: name, user(person who made bump, optional), lowername, resettoke bool, id, listname, media item ✓
@ -262,7 +262,7 @@ dev goals for 1.1 pineapple express:
- list selection method ✓ - list selection method ✓
- smashList ✓ - smashList ✓
- randomList ✓ - randomList ✓
- bump selection method: random from last-half, round-robin, full random - bump selection method: random from last-half, round-robin, full random
- round-robin ✓ - round-robin ✓
- full random ✓ - full random ✓
- last-half random ✓ - last-half random ✓
@ -296,52 +296,135 @@ dev goals for 1.1 pineapple express:
- bump selmed ✓ - bump selmed ✓
- list selmed ✓ - list selmed ✓
- min length to bump ✓ - min length to bump ✓
- Add manual only property to bump object(default false). - Add manual only property to bump object(default false).
- add boolean to obj ✓ - add boolean to obj ✓
- add to handleAddBump & its type ✓ - add to handleAddBump & its type ✓
- add to packlist ✓ - add to packlist ✓
- do not autoQueue bumps with manualOnly set to true - do not autoQueue bumps with manualOnly set to true
- round-robin ✓ - round-robin ✓
- full random ✓ - full random ✓
- last-half random ✓ - last-half random ✓
- Change packList to send history as array of arrays ([[lname,id],[lname,id]]) ✓ - Change packList to send history as array of arrays ([[lname,id],[lname,id]]) ✓
- double check perms(all actions should be at least mod+ only) ✓ - double check perms(all actions should be at least mod+ only) ✓
- reset tokebot when tokebump is played ✓ - reset tokebot when tokebump is played ✓
- Clientside - Additions/Changes for Clientside ✓
- send list function ✓
- send deleted list name function ✓
- send hist function ✓
- send config function ✓
- send list to all mods on list save ✓
- send deleted list names to all mods on list deletion ✓
- send config to all mods on config save ✓
- send history to all mods when item added to history ✓
- Save list filename as lowername ✓
- Only load lists with filenames that end in .bump ✓
- renameBump socket binding ✓
- changeCreator socket binding ✓
- renameList socket binding ✓
- Store config/lists on sendBumplists callback ✓
- Clientside ✓
- Update Auto-Bump panel on data receive callback (when open) ✓
- sendBumplists ✓
- sendBumplist ✓
- remove list upon deletion ✓
- sendBumpHist ✓
- sendBumpConf ✓
- decorate bumps in playlist with translucent-green diagnal "BUMP" watermark (similiar to temporary lines) ✓
- General Config ✓
- Agro Level ✓
- Bump Frequency ✓
- Minimum Duration ✓
- Bump Selection Method ✓
- List Selection Method ✓
- Bump/List Management ✓
- Add Bump ✓
- Add List ✓
- Lists ✓
- Create function to display/edit bumps inside of array ✓
- bump title ✓
- rename ✓
- media title ✓
- manual only ✓
- toggle ✓
- rtoke ✓
- toggle ✓
- duration ✓
- user ✓
- rename ✓
- CSS ✓
- Show Bump Controls Boolean ✓
- Queue Next ✓
- Delete Bump ✓
- Create function to display array of bumplists ✓
- Toggle Active ✓
- Move Add Bump ✓
- Delete Bumplist ✓
- Rename Bumplist ✓
- Display Bumplist ✓
- CSS ✓
- Active Lists (expanded) ✓
- All Lists (collapsed) ✓
- Play History (collapsed) ✓
- finishing touches - finishing touches
- Critical Bug Fix: video sometimes unlatches if sync delayed on video start.(Fix pre-latch, if not duration check until sync is past 2s?) - Critical Bug Fixes
- Critical Bug Fix: userlist profile & current connected users tooltips are currently broken ✓ - video sometimes unlatches if sync delayed on video start.(Fix pre-latch, if not duration check until sync is past 2s?)
- Critical Bug Fix: chat does not fill screen in portrait mode (video height being subtracted while video collapsed) - userlist profile & current connected users tooltips are currently broken ✓
- Critical Bug Fix: make serverside commands case insensitive(May have been intentional with cytube, don't give a shit, it's a bug.) - chat does not fill screen in portrait mode (video height being subtracted while video collapsed)
- Critical Bug Fix: serverside commands trigger other commands with same letters (!announce triggers !a. may only be an issue with single letter commands, double check this though.) - make serverside commands case insensitive(May have been intentional with cytube, don't give a shit, it's a bug.)
- Critical Bug Fix: fix playlist errors in fpanel - serverside commands trigger other commands with same letters (!announce triggers !a. may only be an issue with single letter commands, double check this though.)
- Critical Bug Fix: Unescaped characters when preforming youtube search - fix playlist errors in fpanel
- Critical Bug Check/Fix: make sure we use internal flags instead of matching strings for function calls from tokebot/autobump to playlist/chat - Unescaped characters when preforming youtube search
- tokebot - check/fix: make sure we use internal flags instead of matching strings for function calls from tokebot/autobump to playlist/chat
- autobump - tokebot
- Minor Bug Fix: hide "close playlist" button when playlist is in fpanel - autobump
- Minor Bug Fix: fix playlist resizing (both window resize, and when controls expanded) in fpanel - Minor Bug Fixes
- Minor Bug Fix: Execute serverside commands with whitespace before them while also sending them as normal chat to comform to tokebot behavior in (v1)Panama Red - hide "close playlist" button when playlist is in fpanel
- Minor Bug Fix: disable pm send to tokebot - fix fpanel not resizing on video expand/collapse
- Minor Bug Fix: dont open playlist if legacy playlist disabled(on perm change) - fix playlist resizing (both window resize, and video collapse/expand) in fpanel
- Minor Bug Fix: add item to end of block when queueing round robin - Execute serverside commands with whitespace before them while also sending them as normal chat to comform to tokebot behavior in (v1)Panama Red
- Optimization/Refactor: Change join/leave message prefix/postfix to single string with replacable user token instead of two vars - disable pm send to tokebot
- Optimization/Refactor: Keep start time as proprety of media object while in playlist instead of in an array in metadata. - dont open playlist if legacy playlist disabled(on perm change)
- add scrollTo() on fpplaylist open - add item to end of block when queueing round robin
- save temporary vids to channel library - remove tokebot from !clear dropdown in mod panel
- getplaylistlinks outputs in fpanel - don't collapse expanded bumplists when reloading bump panel
- display links - getBumplists when values are undefined at bump panel launch (should only happen on server startup anywho)
- pop mod nmenu - Optimization/Refactor
- css variables in theme for ez customizablity - Change join/leave message prefix/postfix to single string with replacable user token instead of two vars
- start public channels on server start(this makes more sense for fore.st than cytube since we're focused on a handful of site-run channels instead of user-created ones...) - Keep start time as proprety of media object while in playlist instead of in an array in metadata.
- import data from old tokelog - Check and Sanatize input for Tokebot commands
- merge fore.st theme changes to fore.st dusk, consider moving some of them over to cytube.css for easier management - Check and Sanatize input from autobump panel
- Cytube Feature Changes
- save temporary vids to channel library
- enable/disable scroll on video change(if possible)
- Extras
- call scrollTo() on fpplaylist open
- call scrollTo() on move/queue next
- enable/disable either from mod prefs/qs (both enabled by default)
- getplaylistlinks outputs in fpanel
- display links
- pop mod nmenu
- accept invidious links as youtube links
- start public channels on server start(this makes more sense for fore.st than cytube since we're focused on a handful of site-run channels instead of user-created ones...)
- keep user on same page after failed login
- css variables in theme for ez customizablity
- Preformance test on older machines (not everyone has a high end machine)
- import data from old tokelog
- merge fore.st theme changes to fore.st dusk, consider moving some of them over to cytube.css for easier management
- extra shit(probs wait til next update, or hotfix) - extra shit(probs wait til next update, or hotfix)
- check fi urls for "expire/expires/expiring"
- mark media object as expiring
- do not save
- set raw file color back to normal
- add icon to expiring items
- shared tokes across channels - shared tokes across channels
- short chats (acronyms, emoji, single letters/numbers/symbols) pop in over video from left starting at top left, overflow pops in below, instead of in chat box. Chats slide back up into top of vid after 2s. (optional, default on) - short chats (acronyms, emoji, single letters/numbers/symbols) pop in over video from left starting at top left, overflow pops in below, instead of in chat box. Chats slide back up into top of vid after 2s. (optional, default on)
- pop out btn - pop out btn
- toggle 4:20 assist from mod panel/chat command
- close nested menu when parent button is thrown in panelbtn
- close fpanel when messagebuffer or userlist is clicked
- enable/disable in userprefs (default enabled)
- basic profile page (in side panel) - basic profile page (in side panel)
- improved mod chat (dedicated pop out to access mod channel chat from any channel) - improved mod chat (dedicated pop out to access mod channel chat from any channel)
- user themes - user themes

View file

@ -19,6 +19,7 @@ var InfoGetter = require ("../get-info");
var ChannelModule = require("./module"); var ChannelModule = require("./module");
var Media = require("../media"); var Media = require("../media");
var util = require("../utilities"); var util = require("../utilities");
var Server = require("../server");
//type declerations //type declerations
const TYPE_NEWBUMP = { const TYPE_NEWBUMP = {
@ -46,6 +47,17 @@ const TYPE_BFREQ = {
max: "number" max: "number"
} }
const TYPE_RENAME = {
bl: "string",
id: "number",
name: "string"
}
const TYPE_LISTRENAME = {
oldname: "string",
newname: "string"
}
//global vars //global vars
var bumplists = null;//decalare variable but keep it null until lists are loaded var bumplists = null;//decalare variable but keep it null until lists are loaded
var lowerReg = /[\s!"#$%&'()*+,./:;<=>?@[\]^`{|}~]/g;//regex for ripping out specials and whitespace from lowernames var lowerReg = /[\s!"#$%&'()*+,./:;<=>?@[\]^`{|}~]/g;//regex for ripping out specials and whitespace from lowernames
@ -72,8 +84,17 @@ function loadList(bfile){
} }
var data = JSON.parse(rdata); var data = JSON.parse(rdata);
var blist = [];
data.bumps.forEach(function(b){
if(b != null){
var nbump = new bump(b.name, b.user, b.rtoke, b.media, null, b.noauto);
nbump.listname = data.lowername;
nbump.id = b.id;
blist[b.id] = nbump;
}
});
bumplists.set(data.lowername, new bumplist(data.name,data.bumps)); bumplists.set(data.lowername, new bumplist(data.name,blist));
}); });
} }
@ -86,10 +107,7 @@ function loadLists(cb, callp){
bumplists = new Map();//create new map to load lists into, this clears the variable as well as lets the channel know whether or not they have been loaded yet. bumplists = new Map();//create new map to load lists into, this clears the variable as well as lets the channel know whether or not they have been loaded yet.
item.forEach(function(list, i){ item.forEach(function(list, i){
if(list != configFolder.slice(bumpFolder.length, configFolder.length - 1)){ if(list != configFolder.slice(bumpFolder.length, configFolder.length - 1) && list.slice(list.length - 5) === ".bump"){
if((item.length - 2) == i){
}
loadList("bumps/" + list); loadList("bumps/" + list);
} }
}); });
@ -115,7 +133,7 @@ function bump(name, user, rtoke, media, bumplist, noauto){//bump object construc
this.id = null;//this is assigned by the bumplist :P this.id = null;//this is assigned by the bumplist :P
this.media = media; this.media = media;
this.noauto = noauto this.noauto = noauto
if(bumplists != null){ if(bumplist != null){
if(bumplists.get(bumplist.toLowerCase().replace(lowerReg, ""))){//if bumplist exists if(bumplists.get(bumplist.toLowerCase().replace(lowerReg, ""))){//if bumplist exists
bumplists.get(bumplist.toLowerCase().replace(lowerReg, "")).addBump(this);//add this to the bumplist bumplists.get(bumplist.toLowerCase().replace(lowerReg, "")).addBump(this);//add this to the bumplist
} }
@ -129,12 +147,27 @@ function bumplist(name, bumps){//bumplist object constructor
} }
//prototypes //prototypes
bumplist.prototype.saveList = function(){ //bump
bump.prototype.rename = function(name){
this.name = name;
this.lowername = this.name.toLowerCase().replace(lowerReg, "");
}
//bumplist
bumplist.prototype.saveList = function(oldname){
var _this = this; var _this = this;
fs.writeFile("bumps/" + this.name + ".bump", JSON.stringify(this), function(err,data){ //RIPPED FROM TOKEBOT, NOT CHANGED YET fs.writeFile("bumps/" + this.lowername + ".bump", JSON.stringify(this), function(err,data){ //RIPPED FROM TOKEBOT, NOT CHANGED YET
if(err){ if(err){
console.log("[bump] BUMP LIST " + _this.name + " FILE WRITE ERROR: " + err); console.log("[bump] BUMP LIST " + _this.name + " FILE WRITE ERROR: " + err);
} }
Server.getServer().channels.forEach(function(channel){
channel.users.forEach(function(user){
if(user != null && user.account.effectiveRank >= 2){
channel.modules.autobump.sendList(user, _this.lowername, oldname);
}
});
});
}); });
}; };
@ -196,6 +229,54 @@ bumplist.prototype.packList = function(){
return pbl; return pbl;
} }
bumplist.prototype.rename = function(oldname,nname,cb){
var _this = this;
var lnname = nname.toLowerCase().replace(lowerReg, "");
fs.rename("bumps/" + this.lowername + ".bump", "bumps/" + lnname + ".bump", function(err){
if(err){
console.log("[bump] BUMP LIST " + _this.name + " FILE RENAME ERROR: " + err);
}
bumplists.delete(_this.lowername);
_this.name = nname;
_this.lowername = lnname;
_this.bumps.forEach(function(bump){
if(bump != null){
bump.listname = _this.lowername;
}
});
bumplists.set(_this.lowername, _this);//create new bumplist
_this.saveList(oldname);
if(typeof cb === "function"){
cb();
}
});
}
bumplist.prototype.deleteList = function(){
var _this = this;
fs.unlink("bumps/" + this.lowername + ".bump", function (err){
if(err){
console.log("[bump] BUMP LIST " + _this.name + " FILE DELETE ERROR: " + err);
}
Server.getServer().channels.forEach(function(channel){
channel.users.forEach(function(user){
if(user != null && user.account.effectiveRank >= 2){
user.socket.emit("rmBumplist",_this.lowername);
}
});
});
bumplists.delete(_this.lowername);
});
};
//constructor //constructor
function AutobumpModule(_channel){ function AutobumpModule(_channel){
ChannelModule.apply(this, arguments); ChannelModule.apply(this, arguments);
@ -218,7 +299,13 @@ AutobumpModule.prototype.onUserPostJoin = function (user){//on user join
if(user.account.effectiveRank >= 2){ if(user.account.effectiveRank >= 2){
user.socket.typecheckedOn("newBump", TYPE_NEWBUMP, this.handleNewBump.bind(this, user));//handle newBump user.socket.typecheckedOn("newBump", TYPE_NEWBUMP, this.handleNewBump.bind(this, user));//handle newBump
user.socket.typecheckedOn("deleteBump", TYPE_DELBUMP, this.handleDeleteBump.bind(this, user));//handle newBumplist user.socket.typecheckedOn("deleteBump", TYPE_DELBUMP, this.handleDeleteBump.bind(this, user));//handle newBumplist
user.socket.typecheckedOn("renameBump", TYPE_RENAME, this.handleRenameBump.bind(this, user));//handle newBumplist
user.socket.typecheckedOn("changeCreator", TYPE_RENAME, this.handleChangeCreator.bind(this, user));//handle newBumplist
user.socket.typecheckedOn("toggleRtoke", TYPE_DELBUMP, this.handleToggleRtoke.bind(this, user));//toggle rtoke
user.socket.typecheckedOn("toggleNoauto", TYPE_DELBUMP, this.handleToggleNoauto.bind(this, user));//toggle rtoke
user.socket.typecheckedOn("newBumplist", '', this.handleNewBumplist.bind(this, user));//handle newBumplist user.socket.typecheckedOn("newBumplist", '', this.handleNewBumplist.bind(this, user));//handle newBumplist
user.socket.typecheckedOn("delBumplist", '', this.handleDelBumplist.bind(this, user));//handle newBumplist
user.socket.typecheckedOn("renameBumplist", TYPE_LISTRENAME, this.handleRenameBumplist.bind(this, user));//handle newBumplist
user.socket.typecheckedOn("setActive", '', this.handleSetActive.bind(this, user));//handle newBumplist user.socket.typecheckedOn("setActive", '', this.handleSetActive.bind(this, user));//handle newBumplist
user.socket.typecheckedOn("removeActive", '', this.handleRemoveActive.bind(this, user));//handle newBumplist user.socket.typecheckedOn("removeActive", '', this.handleRemoveActive.bind(this, user));//handle newBumplist
user.socket.typecheckedOn("queueBump", TYPE_DELBUMP, this.handleQueueBump.bind(this, user));//TODO:fix perms for this user.socket.typecheckedOn("queueBump", TYPE_DELBUMP, this.handleQueueBump.bind(this, user));//TODO:fix perms for this
@ -227,6 +314,7 @@ AutobumpModule.prototype.onUserPostJoin = function (user){//on user join
user.socket.typecheckedOn("setBumpFreq", TYPE_BFREQ, this.handleSetBumpFreq.bind(this, user));//TODO:fix perms for this user.socket.typecheckedOn("setBumpFreq", TYPE_BFREQ, this.handleSetBumpFreq.bind(this, user));//TODO:fix perms for this
user.socket.typecheckedOn("setMinBump", 0, this.handleSetMinBump.bind(this, user));//TODO:fix perms for this user.socket.typecheckedOn("setMinBump", 0, this.handleSetMinBump.bind(this, user));//TODO:fix perms for this
user.socket.on("getBumplists", this.sendLists.bind(this, user));//send lists user.socket.on("getBumplists", this.sendLists.bind(this, user));//send lists
this.sendLists(user); this.sendLists(user);
} }
}; };
@ -266,16 +354,18 @@ AutobumpModule.prototype.onMediaAdd = function(data, media){
if(this.agro >= 2){//if agro is 2 or above if(this.agro >= 2){//if agro is 2 or above
if(data.pos === "next"){//if someone added something next if(data.pos === "next"){//if someone added something next
if(!media.isBump){//new item isn't bumps if(!media.isBump){//new item isn't bumps
var lastBump = this.findBlockEnd(this.channel.modules.playlist.current.next.next);//get the last bump of the block if(this.channel.modules.playlist.current.next != null){
if(lastBump != null){//if we got a bump in the block var lastBump = this.findBlockEnd(this.channel.modules.playlist.current.next.next);//get the last bump of the block
if(lastBump.media != media && lastBump != this.channel.modules.playlist.current){//make sure we actually have a block and this isn't returning the currently playing item or the item we added if(lastBump != null){//if we got a bump in the block
var moved = {//create move obj if(lastBump.media != media && lastBump != this.channel.modules.playlist.current){//make sure we actually have a block and this isn't returning the currently playing item or the item we added
from: this.channel.modules.playlist.current.next.uid,//set from as the item that was just added var moved = {//create move obj
after: lastBump.uid,//move item after block from: this.channel.modules.playlist.current.next.uid,//set from as the item that was just added
sTimes: [[],[]] after: lastBump.uid,//move item after block
}; sTimes: [[],[]]
};
this.channel.modules.playlist.handleMoveMedia("autobump",moved,true); this.channel.modules.playlist.handleMoveMedia("autobump",moved,true);
}
} }
} }
} }
@ -433,12 +523,13 @@ AutobumpModule.prototype.queueBump = function(listn, bid){//listname, bump ID
var list = bumplists.get(listn.toLowerCase().replace(lowerReg, "")) var list = bumplists.get(listn.toLowerCase().replace(lowerReg, ""))
var bump = null; var bump = null;
var data = null; var data = null;
var _this = this;
if(list != null){//if bumplist exists if(list != null){//if bumplist exists
bump = list.bumps[bid] bump = list.bumps[bid]
var lastin = this.lastPlayed.findIndex(function(cbump){ var lastin = this.lastPlayed.findIndex(function(cbump){
return (cbump.id == bump.id && cbump.listname === bump.listname); return (cbump != null && bump != null && cbump.id == bump.id && cbump.listname === bump.listname);
}); });
if(this.lastPlayed[lastin] != null){ if(this.lastPlayed[lastin] != null){
@ -447,6 +538,10 @@ AutobumpModule.prototype.queueBump = function(listn, bid){//listname, bump ID
this.lastPlayed.push(bump) this.lastPlayed.push(bump)
this.channel.users.forEach(function(user){
_this.sendHist(user);
});
if(bump != null){ if(bump != null){
data = { //create faux data object for _addItem function data = { //create faux data object for _addItem function
@ -524,8 +619,6 @@ AutobumpModule.prototype.loadConfig = function(_this){
var data = JSON.parse(rdata); var data = JSON.parse(rdata);
//console.log(data);
data.active == null ? [] : data.active; data.active == null ? [] : data.active;
if(data.active != null){ if(data.active != null){
data.active.forEach(function(al){ data.active.forEach(function(al){
@ -545,6 +638,7 @@ AutobumpModule.prototype.loadConfig = function(_this){
}; };
AutobumpModule.prototype.saveConfig = function(){ AutobumpModule.prototype.saveConfig = function(){
var _this = this;
var confObj = { var confObj = {
active: [], active: [],
agro: this.agro, agro: this.agro,
@ -564,6 +658,10 @@ AutobumpModule.prototype.saveConfig = function(){
console.log("[Autobump Config] " + err); console.log("[Autobump Config] " + err);
return; return;
} }
_this.channel.users.forEach(function(user){
_this.sendConf(user)
});
}); });
} }
@ -644,7 +742,7 @@ AutobumpModule.prototype.handleRemoveActive = function(user, data){
}else{ }else{
console.log("list not active!") console.log("list not active!")
} }
this.saveConfig();
} }
}; };
@ -665,7 +763,7 @@ AutobumpModule.prototype.sendLists = function(user, data){
sendobj.lists.push(bumplist.packList()); sendobj.lists.push(bumplist.packList());
}); });
this.activeLists.forEach(function(bumplist){ this.activeLists.forEach(function(bumplist, key){
sendobj.active.push(bumplist.lowername); sendobj.active.push(bumplist.lowername);
}); });
@ -678,10 +776,56 @@ AutobumpModule.prototype.sendLists = function(user, data){
} }
}; };
AutobumpModule.prototype.sendList = function(user, data, oname){
if(user != null && user.account.effectiveRank >= 2){
var list = bumplists.get(data.toLowerCase().replace(lowerReg, ""))
if(list != null){
var pack = list.packList();
if(oname != null){
pack.oname = oname;
}
user.socket.emit("sendBumplist", pack);
}
}
};
AutobumpModule.prototype.sendHist = function(user){
if(user != null && user.account.effectiveRank >= 2){
var sendobj = [];
this.lastPlayed.forEach(function(bump){
sendobj.push([bump.listname, bump.id]);
});
user.socket.emit("sendBumphist", sendobj);
}
}
AutobumpModule.prototype.sendConf = function(user){
if(user != null && user.account.effectiveRank >= 2){
var sendobj = {
active: [],
freq: this.bumpFreq,
agro: this.agro,
minBump: this.minBump,
bsort: this.selmed.name,
lsort: this.listsel.name
}
this.activeLists.forEach(function(bumplist, key){
sendobj.active.push(bumplist.lowername);
});
user.socket.emit("sendBumpconf", sendobj);
}
}
AutobumpModule.prototype.handleNewBumplist = function(user, data){//handle newBumplist AutobumpModule.prototype.handleNewBumplist = function(user, data){//handle newBumplist
if(user.account.effectiveRank >= 2){ if(user.account.effectiveRank >= 2){
if(bumplists.get(data.toLowerCase().replace(lowerReg, "")) == null){ if(bumplists.get(data.toLowerCase().replace(lowerReg, "")) == null){
bumplists.set(data.toLowerCase().replace(lowerReg, ""), new bumplist(data));//create new bumplist bumplists.set(data.toLowerCase().replace(lowerReg, ""), new bumplist(data));//create new bumplist
this.sendList(user,data.toLowerCase().replace(lowerReg, ""));
}else{ }else{
user.socket.emit("errorMsg", { user.socket.emit("errorMsg", {
msg: "Bumplist name taken: " + data.toLowerCase().replace(lowerReg, ""), msg: "Bumplist name taken: " + data.toLowerCase().replace(lowerReg, ""),
@ -692,6 +836,51 @@ AutobumpModule.prototype.handleNewBumplist = function(user, data){//handle newBu
} }
}; };
AutobumpModule.prototype.handleRenameBumplist = function(user, data){//handle newBumplist
if(user.account.effectiveRank >= 2){
if(bumplists.get(data.oldname.toLowerCase().replace(lowerReg, "")) != null){
var active = false;
var _this = this;
var list = bumplists.get(data.oldname.toLowerCase().replace(lowerReg, ""));
if(active = this.activeLists.get(data.oldname.toLowerCase().replace(lowerReg, "")) != null)
this.activeLists.delete(data.oldname.toLowerCase().replace(lowerReg, ""));
list.rename(data.oldname, data.newname, function(){
if(active){
_this.activeLists.set(data.newname.toLowerCase().replace(lowerReg, ""), list);
_this.saveConfig();
}
});
}else{
user.socket.emit("errorMsg", {
msg: "Non-Existant Bumplist: " + data.oldname.toLowerCase().replace(lowerReg, ""),
alert: true
});
}
}
}
AutobumpModule.prototype.handleDelBumplist = function(user, data){//handle newBumplist
if(user.account.effectiveRank >= 2){
var active = false;
if(bumplists.get(data.toLowerCase().replace(lowerReg, "")) != null){
if(active = this.activeLists.get(data.toLowerCase().replace(lowerReg, "")) != null)
this.activeLists.delete(data.toLowerCase().replace(lowerReg, ""));
bumplists.get(data.toLowerCase().replace(lowerReg, "")).deleteList();
}else{
user.socket.emit("errorMsg", {
msg: "Non-Existant Bumplist: " + data.toLowerCase().replace(lowerReg, ""),
alert: true
});
return;
}
}
};
//bump management/commands //bump management/commands
AutobumpModule.prototype.handleNewBump = function(user, data){//handle newBump AutobumpModule.prototype.handleNewBump = function(user, data){//handle newBump
if(user.account.effectiveRank >= 2){ if(user.account.effectiveRank >= 2){
@ -712,6 +901,43 @@ AutobumpModule.prototype.handleNewBump = function(user, data){//handle newBump
} }
}; };
AutobumpModule.prototype.handleRenameBump = function(user, data){
if(user.account.effectiveRank >= 2){
if(bumplists.get(data.bl) != null && bumplists.get(data.bl).bumps[data.id] != null){
bumplists.get(data.bl).bumps[data.id].rename(data.name);
bumplists.get(data.bl).saveList();
}
}
}
AutobumpModule.prototype.handleChangeCreator = function(user, data){
if(user.account.effectiveRank >= 2){
if(bumplists.get(data.bl) != null && bumplists.get(data.bl).bumps[data.id] != null){
bumplists.get(data.bl).bumps[data.id].user = (data.name);
bumplists.get(data.bl).saveList();
}
}
}
AutobumpModule.prototype.handleToggleNoauto = function(user, data){
if(user.account.effectiveRank >= 2){
if(bumplists.get(data.bl) != null && bumplists.get(data.bl).bumps[data.id] != null){
bumplists.get(data.bl).bumps[data.id].noauto = !bumplists.get(data.bl).bumps[data.id].noauto;
bumplists.get(data.bl).saveList();
}
}
}
AutobumpModule.prototype.handleToggleRtoke = function(user, data){
if(user.account.effectiveRank >= 2){
if(bumplists.get(data.bl) != null && bumplists.get(data.bl).bumps[data.id] != null){
bumplists.get(data.bl).bumps[data.id].rtoke = !bumplists.get(data.bl).bumps[data.id].rtoke;
bumplists.get(data.bl).saveList();
}
}
}
AutobumpModule.prototype.handleDeleteBump = function(user, data){ AutobumpModule.prototype.handleDeleteBump = function(user, data){
if(user.account.effectiveRank >= 2){ if(user.account.effectiveRank >= 2){
var bl = bumplists.get(data.bl); var bl = bumplists.get(data.bl);
@ -726,7 +952,4 @@ AutobumpModule.prototype.handleDeleteBump = function(user, data){
} }
}; };
module.exports = AutobumpModule; module.exports = AutobumpModule;

View file

@ -35,6 +35,7 @@ Media.prototype = {
duration: this.duration, duration: this.duration,
startTime: this.startTime, startTime: this.startTime,
type: this.type, type: this.type,
isBump: this.isBump,
meta: { meta: {
restricted: this.meta.restricted, restricted: this.meta.restricted,
codec: this.meta.codec, codec: this.meta.codec,

View file

@ -822,7 +822,7 @@ table td {
padding-bottom: 2px; padding-bottom: 2px;
} }
.queue_entry { .queue_entry, .ab-bumparray-bump{
line-height: 22px; line-height: 22px;
padding: 2px; padding: 2px;
font-size: 8pt; font-size: 8pt;
@ -830,10 +830,53 @@ table td {
border-top-width: 0; border-top-width: 0;
} }
.ab-bumparray-span{
display: grid;
grid-template: 2em 2em / 33% 33% auto;
grid-auto-flow: column;
justify-content: space-between;
}
.ab-bumparray-creator{
display: inline;
}
.ab-bumparray-cspan{
float: right;
}
#ab-bumphist-div{
overflow: scroll;
max-height: 25em;
}
.ab-bumplist-lbl, .ab-newlist-form{
display: inline;
}
.ab-newlist-form{
margin-left: 0.5em;
}
.ab-newbump-form{
display: inline;
}
.ab-newbump-cancel{
display: inline;
}
.emotelist-table { .emotelist-table {
margin: auto; margin: auto;
} }
#ab-freq-min, #ab-freq-max{
width: 2em;
}
#ab-dur-min{
width: 4em;
}
.ab-bumplists-ltype, .ab-bumplist-listname{
display: inline;
}
.ab-bumplist-bumps{
max-height: 30em;
overflow: scroll;
}
.ab-bumplist-delete{
float: right;
}
.emote-preview-container { .emote-preview-container {
width: 100px; width: 100px;
height: 100px; height: 100px;
@ -937,6 +980,9 @@ input#logout[type="submit"]:hover {
font-weight: 700; font-weight: 700;
display: inline; display: inline;
} }
#ab-bumparray-reuserfl{
margin: 0px;
}
body.hd #resize-video-larger, body.hd #resize-video-smaller { body.hd #resize-video-larger, body.hd #resize-video-smaller {
display: none; display: none;
} }
@ -944,3 +990,7 @@ body.hd #resize-video-larger, body.hd #resize-video-smaller {
.userlist-ignored { .userlist-ignored {
text-decoration: line-through; text-decoration: line-through;
} }
#bumpi{
background-image: url("../img/bumps.png");
background-size: 2.2em;
}

View file

@ -988,7 +988,7 @@ hr{
font-size:16px font-size:16px
} }
p{ p{
margin:0 0 10px margin:0;
} }
.lead{ .lead{
margin-bottom:20px; margin-bottom:20px;
@ -5396,7 +5396,7 @@ a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{
} }
/* CYTUBE EDIT */ /* CYTUBE EDIT */
body { body {
background-image: url(https://ourfore.st/img/frst.jpg); background-image: url(../../img/frst.jpg);
color: #c8c8c8; color: #c8c8c8;
} }
@ -5471,11 +5471,34 @@ a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
} }
.queue_entry { .ab-bumparray-bump, .queue_entry {
border-color: #949494; border-color: #949494;
background-color: #060606; background-color: #060606;
} }
.navbar-inverse .navbar-text-nofloat { .ab-bumparray-edit{
margin: 0 0.5em 0 0.5em;
}
.ab-bumplist-list{
background-color: #060606;
border-bottom: 1px solid #949494;
margin: 0;
padding-top: 0.5em;
}
.ab-bumplist-bumps{
border-top: 1px solid #949494;
}
.ab-bumplist-setactive-active{
color: #339933;
text-shadow: #339933 0 0 10px;
}
.ab-bumplist-delete{
color: #c00;
}
.ab-bumplist-setactive:hover, .ab-bumplist-setactive-active:hover{
color: #ded;
text-shadow: #339933 0 0 10px;
}
.navbar-inverse .navbar-text-nofloat {
color: #888; color: #888;
} }
.queue_entry.queue_active { .queue_entry.queue_active {

BIN
www/img/bumps.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -743,6 +743,9 @@ Callbacks = {
if(data[i].media.type === "fi"){ if(data[i].media.type === "fi"){
li.attr("id", "filei"); li.attr("id", "filei");
} }
if(data[i].media.isBump){
li.attr("id", "bumpi");
}
li.appendTo(q); li.appendTo(q);
} }
@ -768,10 +771,15 @@ Callbacks = {
li.addClass("queue_active"); li.addClass("queue_active");
activeItem = data.uid; activeItem = data.uid;
} }
if(data.item.media.type === "fi"){ if(data.item.media.type === "fi"){
li.attr("id", "filei"); li.attr("id", "filei");
} }
if(data.item.media.isBump){
li.attr("id", "bumpi");
}
li.hide(); li.hide();
var q = $("#queue"); var q = $("#queue");
li.attr("title", data.item.queueby li.attr("title", data.item.queueby
@ -1203,8 +1211,85 @@ Callbacks = {
}, },
sendBumplists: function (data){ sendBumplists: function (data){
console.log(data); data.lists.forEach(function(list){//tattoo listnames, saves bandwith
} list.bumps.forEach(function(bump){
if(bump != null){
bump.listname = list.lowername;
}
});
});
CHANNEL.bumpdata = data;//the best answer is usually the easy one. Why re-create an object client side when we can just use the one we got handed?
if(CURRENTFPANEL == fpbump){
fpbump.reloadPanel();
}
},
sendBumplist: function (data){
var lfound = null;
CHANNEL.bumpdata.lists.forEach(function(list, i){
if(data.oname == null){
if(lfound == null && data.lowername === list.lowername){
lfound = i;
}
}else{
if(lfound == null && data.oname === list.lowername){
lfound = i;
data.oname = undefined;
}
}
});
data.bumps.forEach(function(bump){
if(bump != null){
bump.listname = data.lowername;
}
});
if(lfound != null){
CHANNEL.bumpdata.lists[lfound] = data;
}else{
CHANNEL.bumpdata.lists.push(data);
}
if(CURRENTFPANEL == fpbump){
fpbump.reloadPanel();
}
},
rmBumplist: function (data){
CHANNEL.bumpdata.lists.forEach(function(list, i){
if(data === list.lowername){
console.log(data);
CHANNEL.bumpdata.lists.splice(i, 1);
}
});
if(CURRENTFPANEL == fpbump){
fpbump.reloadPanel();
}
},
sendBumpconf: function (data){
CHANNEL.bumpdata.active = data.active;
CHANNEL.bumpdata.agro = data.agro;
CHANNEL.bumpdata.bsort = data.bsort;
CHANNEL.bumpdata.freq = data.freq;
CHANNEL.bumpdata.lsort = data.lsort;
CHANNEL.bumpdata.minBump = data.minBump;
if(CURRENTFPANEL == fpbump){
fpbump.reloadPanel();
}
},
sendBumphist: function (data){
CHANNEL.bumpdata.history = data;
if(CURRENTFPANEL == fpbump){
fpbump.reloadPanel();
}
},
} }
var SOCKET_DEBUG = localStorage.getItem('cytube_socket_debug') === 'true'; var SOCKET_DEBUG = localStorage.getItem('cytube_socket_debug') === 'true';

View file

@ -61,7 +61,8 @@ var CHANNEL = {
motd: "", motd: "",
name: CHANNELNAME, name: CHANNELNAME,
usercount: 0, usercount: 0,
emotes: [] emotes: [],
bumpdata: {}
}; };
var PLAYER = false; var PLAYER = false;

View file

@ -276,9 +276,7 @@ fpset.ocall = function(){
$("<form>").append( $("<form>").append(
$("<label>").prop("for","qs-sync-threshold").html("Sync Threshold(seconds): "), $("<label>").prop("for","qs-sync-threshold").html("Sync Threshold(seconds): "),
$("<input>").prop("id","qs-sync-threshold").prop("type","text").addClass("qs-form"), $("<input>").prop("id","qs-sync-threshold").prop("type","text").addClass("qs-form").change(function() {
$("<button/>").addClass("btn btn-primary btn-ln").text("Save").prop("type","button").prop("id","qs-sync-threshold-save").click(function() {
USEROPTS.sync_accuracy = parseFloat($("#qs-sync-threshold").val()) || 2; USEROPTS.sync_accuracy = parseFloat($("#qs-sync-threshold").val()) || 2;
processOpts(); processOpts();
}), }),
@ -349,7 +347,7 @@ fpset.ocall = function(){
}), }),
), ),
]) ])
fpset.loadSettings(); this.loadSettings();
} }
fpset.loadSettings = function(){ fpset.loadSettings = function(){
@ -370,7 +368,6 @@ fpset.loadSettings = function(){
$("#qs-timestamp-second").parent().toggle(USEROPTS.show_timestamps); $("#qs-timestamp-second").parent().toggle(USEROPTS.show_timestamps);
$("#qs-timestamp-second").prop("checked", USEROPTS.show_seconds); $("#qs-timestamp-second").prop("checked", USEROPTS.show_seconds);
$("#qs-toke-pm").prop("checked", USEROPTS.toke_pm); $("#qs-toke-pm").prop("checked", USEROPTS.toke_pm);
} }
@ -599,7 +596,397 @@ fpbump.elm = [//fpmod element array
fpbump.ocall = function(){ fpbump.ocall = function(){
modNested.popMenu(); modNested.popMenu();
var ladd = $("<form>").addClass("ab-newlist-form").append(
$("<input>").prop("id","ab-newlist-name").prop("type","text").addClass("qs-form").attr("placeholder", "New Bumplist Title").change(function(){$("#ab-newlist-newbtn").click();}),
//$("<button/>").addClass("btn btn-primary btn-ln").text("Add List").prop("type","button").click(function(){
$("<span>").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-plus-sign pointer").attr("title","Create Bumplist").attr("id","ab-newlist-newbtn").click(function(){
var nlname = $("#ab-newlist-name").val()
if(nlname != null && nlname !== ""){
socket.emit("newBumplist",nlname);
$("#ab-newlist-name").val("");
$(this).parent().after(laddbtn.clone(true));
$(".ab-newlist-form").remove();
}
}),
$("<span>").addClass("qsbtn glyphicon glyphicon-ban-circle pointer").attr("title","Cancel").click(function(){
$(this).parent().after(laddbtn.clone(true));
$(".ab-newlist-form").remove();
}),
);
var laddbtn = $("<span>").prop("id","ab-newlist-btn").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-plus-sign pointer").attr("title","Create Bumplist").click(function(){
$(this).replaceWith(ladd.clone(true));
});
var alists = [];
CHANNEL.bumpdata.active.forEach(function(bname){
CHANNEL.bumpdata.lists.forEach(function(list){
if(list.lowername === bname)
alists.push(list);
});
});
$("#fpcontdiv").append(
$("<h4>").html("General Config"),
$("<form>").append(
$("<label>").prop("for","ab-agro").html("Agression Level: "),
$("<select>").prop("id","ab-agro").prop("type","text").addClass("qs-form").change(function() {
socket.emit("setAgro", parseInt($("#ab-agro").val()));
}).append(
$("<option>").val(0).html("0"),
$("<option>").val(1).html("1"),
$("<option>").val(2).html("2"),
$("<option>").val(3).html("3")
),
),
$("<form>").append(
$("<label>").prop("for","ab-freq-min").html("Bump Frequency: "),
$("<input>").prop("id","ab-freq-min").prop("type","text").addClass("qs-form").change(function() {
socket.emit("setBumpFreq", {min: parseInt($("#ab-freq-min").val()), max: parseInt($("#ab-freq-max").val())});
}),
$("<input>").prop("id","ab-freq-max").prop("type","text").addClass("qs-form").change(function() {
socket.emit("setBumpFreq", {min: parseInt($("#ab-freq-min").val()), max: parseInt($("#ab-freq-max").val())});
}),
),
$("<form>").append(
$("<label>").prop("for","ab-dur-min").html("Duration Minimum (seconds): "),
$("<input>").prop("id","ab-dur-min").prop("type","text").addClass("qs-form").change(function() {
socket.emit("setMinBump", parseInt($("#ab-dur-min").val()));
})
),
$("<form>").append(
$("<label>").prop("for","ab-bsel").html("Bump Selection Method: "),
$("<select>").prop("id","ab-bsel").prop("type","text").addClass("qs-form").change(function() {
socket.emit("setSelect", {bump: parseInt($("#ab-bsel").val()), list: parseInt($("#ab-lsel").val())});
}).append(
$("<option>").val(0).html("Last Half Random"),
$("<option>").val(1).html("Queue Random"),
$("<option>").val(2).html("Round Robin")
),
),
$("<form>").append(
$("<label>").prop("for","ab-lsel").html("List Selection Method: "),
$("<select>").prop("id","ab-lsel").prop("type","text").addClass("qs-form").change(function() {
socket.emit("setSelect", {bump: parseInt($("#ab-bsel").val()), list: parseInt($("#ab-lsel").val())});
}).append(
$("<option>").val(0).html("Random List"),
$("<option>").val(1).html("Smash List"),
),
),
/*$("<form>").append(
$("<label>").prop("for","qs-theme").html("Bump Selection: "),
$("<select>").prop("id","qs-theme").addClass("qs-form").change(function() {
USEROPTS.theme = $("#qs-theme").val();
processOpts();
}),
),*/
$("<h4>").html("Bump Lists").addClass("ab-bumplist-lbl"),
laddbtn.clone(true),
$("<br>"),
$("<span>").prop("id","ab-activebumplists-exp").addClass("qsbtn glyphicon glyphicon-chevron-down pointer").click(function(){
if($(".ab-activebumplists-div").is(":visible")){
$(".ab-activebumplists-div").hide("blind"),
$(this).attr("style", "rotate: 270deg;");
}else{
$(".ab-activebumplists-div").show("blind"),
$(this).attr("style", "rotate: 0;");
}
}),
$("<h5>").addClass("ab-activebumplists-lbl ab-bumplists-ltype").html("Active Lists (" + CHANNEL.bumpdata.active.length + ")").click(function(){$("#ab-activebumplists-exp").click()}),
$("<div>").addClass("ab-activebumplists-div").append(
this.showLists(alists),
),
$("<br>"),
$("<span>").prop("id","ab-allbumplists-exp").addClass("qsbtn glyphicon glyphicon-chevron-down pointer").click(function(){
if($(".ab-allbumplists-div").is(":visible")){
$(".ab-allbumplists-div").hide("blind"),
$(this).attr("style", "rotate: 270deg;");
}else{
$(".ab-allbumplists-div").show("blind"),
$(this).attr("style", "rotate: 0;");
}
}),
$("<h5>").addClass("ab-allbumplists-lbl ab-bumplists-ltype").html("All Lists (" + CHANNEL.bumpdata.lists.length + ")").click(function(){$("#ab-allbumplists-exp").click()}),
$("<br>"),
$("<div>").addClass("ab-allbumplists-div").append(
this.showLists(),
),
$("<span>").prop("id","ab-bumphist-exp").addClass("qsbtn glyphicon glyphicon-chevron-down pointer").click(function(){
if($("#ab-bumphist-div").is(":visible")){
$("#ab-bumphist-div").hide("blind"),
$(this).attr("style", "rotate: 270deg;");
}else{
$("#ab-bumphist-div").show("blind"),
$(this).attr("style", "rotate: 0;");
}
}),
$("<h5>").html("Bump History (" + this.getHist().length + ")").attr("style", "display: inline").addClass("ab-bumphist-lbl").click(function(){$("#ab-bumphist-exp").click()}),
$("<div>").prop("id", "ab-bumphist-div").append(this.showBumps(this.getHist())),
);
this.loadSettings();
} }
fpbump.loadSettings = function(){
$("#ab-agro")[0].value = CHANNEL.bumpdata.agro;
$("#ab-freq-min").val(CHANNEL.bumpdata.freq[0]);
$("#ab-freq-max").val(CHANNEL.bumpdata.freq[1]);
$("#ab-dur-min").val(CHANNEL.bumpdata.minBump);
if(CHANNEL.bumpdata.bsort === "queueRandom"){
$("#ab-bsel")[0].value = 1;
}else if(CHANNEL.bumpdata.bsort === "roundRobin"){
$("#ab-bsel")[0].value = 2;
}else{
$("#ab-bsel")[0].value = 0;
}
$("#ab-lsel")[0].value = CHANNEL.bumpdata.lsort === "smashList" ? 1 : 0;
CHANNEL.bumpdata.lists.forEach(function(blist){
$("#ab-newbump-list").append($("<option>").val(blist.lowername).html(blist.name));
});
}
fpbump.reloadPanel = function(){
this.loadSettings();
var alists = [];
CHANNEL.bumpdata.active.forEach(function(bname){
CHANNEL.bumpdata.lists.forEach(function(list){
if(list.lowername === bname)
alists.push(list);
});
});
$(".ab-activebumplists-lbl").html("Active Lists (" + CHANNEL.bumpdata.active.length + ")");
$(".ab-allbumplists-lbl").html("All Lists (" + CHANNEL.bumpdata.lists.length + ")");
$(".ab-bumphist-lbl").html("Bump History (" + this.getHist().length + ")");
$(".ab-activebumplists-div").html(this.showLists(alists));
$(".ab-allbumplists-div").html(this.showLists());
$("#ab-bumphist-div").html(this.showBumps(this.getHist()));
}
fpbump.getHist = function(){
var fHist = [];
CHANNEL.bumpdata.history.forEach(function(bdata){
CHANNEL.bumpdata.lists.forEach(function(list){
if(list.lowername === bdata[0]){
fHist.push(list.bumps[bdata[1]]);
}
});
});
return fHist;
}
fpbump.showLists = function(lists){
var lDivs = [];
var _this = this;
if(lists == null){
lists = CHANNEL.bumpdata.lists;
}
function badd(list, ob){
return [$("<br>"),
$("<form>").addClass("ab-newbump-form").append(
$("<input>").prop("id","ab-newbump-url").prop("type","text").addClass("qs-form").attr("placeholder","URL"),
$("<input>").prop("id","ab-newbump-title").prop("type","text").addClass("qs-form").attr("placeholder","Title"),
$("<input>").prop("id","ab-newbump-user").prop("type","text").addClass("qs-form").attr("placeholder","Bump Creator"),
$("<br>"),
$("<label>").prop("for","ab-newbump-rtoke").html("Toke Bump: "),
$("<input>").prop("id","ab-newbump-rtoke").prop("type","checkbox").addClass("qs-form"),
$("<label>").prop("for","ab-newbump-noauto").html("Manual Only: "),
$("<input>").prop("id","ab-newbump-noauto").prop("type","checkbox").addClass("qs-form"),
$("<span>").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-plus-sign pointer").attr("title","Add Bump").attr("id","ab-newlist-newbtn").click(function(){
if($("#ab-newbump-url").val() !== ""){
var mdata = parseMediaLink($("#ab-newbump-url").val());
var bumpObj = {
id: mdata.id,
type: mdata.type,
name: $("#ab-newbump-title").val(),
user: $("#ab-newbump-user").val(),
rtoke: $("#ab-newbump-rtoke").prop("checked"),
bumplist: list,
noauto: $("#ab-newbump-noauto").prop("checked")
}
socket.emit("newBump", bumpObj);
$("#ab-newbump-url").val("");
$("#ab-newbump-title").val("");
$("#ab-newbump-user").val("");
$("#ab-newbump-cancel").click();
}
}),
).clone(true),
$("<span>").prop("id","ab-newbump-cancel").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-ban-circle pointer").click(function(){
$(this).prev().prev().remove();//gotta take out that br...
$(this).prev().remove();
$(this).replaceWith(ob);
})];
}
lists.forEach(function(list){
var blist = $("<div>").addClass("ab-bumplist-bumps").append(_this.showBumps(list.bumps, true));
var active = false;
CHANNEL.bumpdata.active.forEach(function(lname){
if(!active)
active = list.lowername === lname;
});
lDivs.push(
$("<div>").addClass("ab-bumplist-list").attr("id", "ab-bumplist-" + list.lowername).append(
$("<span>").addClass("ab-bumplist-setactive" + (active ? "-active " : " ") + "qsbtn glyphicon glyphicon-ok pointer").attr("title",(active ? "Set List Inactive" : "Set List Active")).click(function(){
socket.emit((active ? "remove" : "set") + "Active", list.lowername);
}),
$("<span>").prop("id","ab-bumplist-bumps-exp").addClass("qsbtn glyphicon glyphicon-chevron-down pointer").attr("style","rotate: 270deg").click(function(){
if(blist.is(":visible")){
blist.hide("blind"),
$(this).attr("style", "rotate: 270deg;");
}else{
blist.show("blind"),
$(this).attr("style", "rotate: 0;");
}
}),
$("<h6>").html(list.name + " (" + list.bumps.length + ")").addClass("ab-bumplist-listname").click(function(){$(this).prev().click()}),
$("<span>").prop("id","ab-bumplist-rename").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-pencil pointer").click(function(){
var link = $(this).prev().clone(true);
var ebtn = $(this).clone(true);
$(this).prev().replaceWith($("<form>").append(
$("<input>").prop("type","text").attr("id", "ab-bumparray-reuserf").addClass("qs-form").attr("placeholder", list.name).keydown(function(ev) {
// Enter/return
if(ev.keyCode == 13) {
socket.emit("renameBumplist", {oldname: list.lowername, newname: this.value});
$(this).parent().next().replaceWith(ebtn);
$(this).parent().replaceWith(link);
}
})
).attr("style", "display: inline"));
$(this).replaceWith(
$("<span>").prop("id","ab-bumparray-reuser").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-ban-circle pointer").click(function(){
$(this).prev().replaceWith(link);
$(this).replaceWith(ebtn);
})
);
}),
$("<span>").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-plus-sign pointer").attr("title","Add Bump").attr("id","ab-newlist-newbtn").click(function(){
var abtn = $(this).clone(true);
$(this).replaceWith(badd(list.lowername, abtn));
}),
$("<span>").addClass("ab-bumplist-delete qsbtn glyphicon pointer glyphicon-trash").attr("title","Delete List").click(function(){
if(window.confirm("Fuck me, you sure you wanna do that? You're about to nuke " + list.name + " off the face of the planet.")){
socket.emit("delBumplist",list.lowername);
}
}),
blist.hide(),
),
);
});
return lDivs;
}
fpbump.showBumps = function(bumps, controls){
var bDivs = [];
var bSpan = []
bumps.forEach(function(bump){
if(bump != null){
var bCreator = $("<span>").append(
$("<p>Creator: " + (bump.user == null ? "N/A" : bump.user) + "</p>").addClass("ab-bumparray-creator"),
(controls ? $("<span>").prop("id","ab-bumparray-reuser").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-pencil pointer").click(function(){
var link = $(this).prev().clone(true);
var ebtn = $(this).clone(true);
$(this).prev().replaceWith($("<form>").append(
$("<label>").prop("for", "ab-bumparray-reuserf").attr("id", "ab-bumparray-reuserfl").html("Creator: "),//alphanum sort label
$("<input>").prop("type","text").attr("id", "ab-bumparray-reuserf").addClass("qs-form").attr("placeholder", (bump.user == null ? "N/A" : bump.user)).keydown(function(ev) {
// Enter/return
if(ev.keyCode == 13) {
socket.emit("changeCreator", {bl: bump.listname, id: bump.id, name: this.value});
$(this).parent().next().replaceWith(ebtn);
$(this).parent().replaceWith(link);
}
})
).attr("style", "display: inline"));
$(this).replaceWith(
$("<span>").prop("id","ab-bumparray-reuser").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-ban-circle pointer").click(function(){
$(this).prev().replaceWith(link);
$(this).replaceWith(ebtn);
})
);
}):undefined),
);
var bSpan = $("<span>").addClass("ab-bumparray-span").append(
$("<span>").append(
$('<a href="' + formatURL(bump.media) + '">' + bump.name + "</a>"),
(controls ? $("<span>").prop("id","ab-bumparray-rename").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-pencil pointer").click(function(){
var link = $(this).prev().clone(true);
var ebtn = $(this).clone(true);
$(this).prev().replaceWith($("<form>").append(
$("<input>").prop("type","text").addClass("qs-form").attr("placeholder", bump.name).keydown(function(ev) {
// Enter/return
if(ev.keyCode == 13) {
socket.emit("renameBump", {bl: bump.listname, id: bump.id, name: this.value});
$(this).parent().next().replaceWith(ebtn);
$(this).parent().replaceWith(link);
}
})
).attr("style", "display: inline"));
$(this).replaceWith(
$("<span>").prop("id","ab-bumparray-rename").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-ban-circle pointer").click(function(){
$(this).prev().replaceWith(link);
$(this).replaceWith(ebtn);
})
);
}):undefined),
),
$("<p>" + bump.media.title + "</p>"),
(controls ? [
$('<p>Manual Only: <a class="pointer">' + (bump.noauto ? "Y" : "N") + "</a></p>").click(function(){socket.emit("toggleNoauto", {bl: bump.listname, id: bump.id})}),
$('<p>Toke Bump: <a class="pointer">' + (bump.rtoke ? "Y" : "N") + "</a></p>").click(function(){socket.emit("toggleRtoke", {bl: bump.listname, id: bump.id})}),
] : [
$("<p>Manual Only: " + (bump.noauto ? "Y" : "N") + "</p>"),
$("<p>Toke Bump: " + (bump.rtoke ? "Y" : "N") + "</p>"),
]),
$("<p>Dur: " + bump.media.duration + "</p>"),
);
var bDiv = $("<div>").addClass("ab-bumparray-bump").attr("id", "ab-bumparray-" + bump.listname + "-" + bump.id).append(bSpan);
if(controls){
bDiv.append(
$("<span>").append(
$("<button/>").addClass("btn btn-xs btn-default abbtn-next").html("<span class='glyphicon glyphicon-share-alt'></span>Queue Next").click(function() {
socket.emit("queueBump",{bl: bump.listname, id: bump.id});
}),
$("<button/>").addClass("btn btn-xs btn-default abbtn-next").html("<span class='glyphicon glyphicon-trash'></span>Delete").click(function() {
socket.emit("deleteBump",{bl: bump.listname, id: bump.id});
})
),
$("<span>").addClass("ab-bumparray-cspan").append(
bCreator,
)
);
}else{
bDiv.append(bCreator);
}
bDivs.push(bDiv);
}
});
return bDivs;
}
//---Tokebot--- //---Tokebot---
var fptoke = new fpmenu("Tokebot");//create new panel fpmod var fptoke = new fpmenu("Tokebot");//create new panel fpmod