mourningdove/htdocs/js/userpicselect.js

469 lines
13 KiB
JavaScript
Raw Permalink Normal View History

2026-05-24 01:03:05 +00:00
UserpicSelect = new Class (LJ_IPPU, {
init: function () {
if ( UserpicSelect.superClass.init )
UserpicSelect.superClass.init.apply(this, ["Choose Icon"]);
this.setDimensions("560px", "441px");
this.selectedPicid = null;
this.displayPics = null;
this.dataLoaded = false;
this.imgScale = 1;
this.picSelectedCallback = null;
var template = new Template( UserpicSelect.top );
var templates = { body: template };
this.setContent(template.exec( new Template.Context( {}, templates ) ));
this.setHiddenCallback(this.hidden.bind(this));
},
show: function() {
UserpicSelect.superClass.show.apply(this, []);
if (!this.dataLoaded) {
this.setStatus("Loading...");
this.loadPics();
this.dataLoaded = true;
} else {
this.redraw();
}
},
// hide the hourglass when window is closed
hidden: function () {
if (this.hourglass)
this.hourglass.hide();
},
// set a callback to be called when the "select" button is clicked
setPicSelectedCallback: function (callback) {
this.picSelectedCallback = callback;
},
// called when the "select" button is clicked
closeButtonClicked: function (evt) {
if (this.picSelectedCallback) {
var selectedKws = [];
if (this.selectedPicid) {
var kws = this.pics.pics[this.selectedPicid+""].keywords;
if (kws && kws.length) selectedKws = kws;
}
this.picSelectedCallback(this.selectedPicid, selectedKws);
}
this.hide();
},
setStatus: function(status) {
this.setField({'status': status});
},
setField: function(vars) {
var template = new Template( UserpicSelect.dynamic );
var userpics_template = new Template( UserpicSelect.userpics );
var templates = {
body: template,
userpics: userpics_template
};
if (!vars.pics)
vars.pics = this.pics || {};
if (!vars.status)
vars.status = "";
vars.imgScale = this.imgScale;
$("ups_dynamic").innerHTML = (template.exec( new Template.Context( vars, templates ) ));
if (!vars.pics.ids)
return;
// we redrew the window so reselect the current selection, if any
if (this.selectedPicid)
this.selectPic(this.selectedPicid);
var ST = new SelectableTable();
ST.init({
"table": $("ups_userpics_t"),
"selectedClass": "ups_selected_cell",
"selectableClass": "ups_cell",
"multiple": false,
"selectableItem": "cell"
});
var self = this;
ST.addWatcher(function (data) {
var selectedCell = data[0];
if (!selectedCell) {
// clear selection
self.selectPic(null);
} else {
// find picid and select it
var parentCell = DOM.getFirstAncestorByClassName(selectedCell, "ups_cell", true);
if (!parentCell) return;
var picid = parentCell.getAttribute("lj_ups:picid");
if (!picid) return;
self.selectPic(picid);
}
});
DOM.addEventListener($("ups_closebutton"), "click", this.closeButtonClicked.bindEventListener(this));
// set up image scaling buttons
var scalingSizes = [3,2,1];
var baseSize = 25;
var scalingBtns = $("ups_scaling_buttons");
this.scalingBtns = [];
if (scalingBtns) {
scalingSizes.forEach(function (scaleSize) {
var scaleBtn = document.createElement("img");
scaleBtn.style.width = scaleBtn.width = scaleBtn.style.height = scaleBtn.height = baseSize - scaleSize * 5;
scaleBtn.src = Site.imgprefix + "/imgscale.png";
DOM.addClassName(scaleBtn, "ups_scalebtn");
self.scalingBtns.push(scaleBtn);
DOM.addEventListener(scaleBtn, "click", function (evt) {
Event.stop(evt);
self.imgScale = scaleSize;
self.scalingBtns.forEach(function (otherBtn) {
DOM.removeClassName(otherBtn, "ups_scalebtn_selected");
});
DOM.addClassName(scaleBtn, "ups_scalebtn_selected");
self.redraw();
});
scalingBtns.appendChild(scaleBtn);
if (self.imgScale == scaleSize)
DOM.addClassName(scaleBtn, "ups_scalebtn_selected");
});
}
},
kwmenuChange: function(evt) {
this.selectPic($("ups_kwmenu").value);
},
selectPic: function(picid) {
if (this.selectedPicid) {
DOM.removeClassName($("ups_upicimg" + this.selectedPicid), "ups_selected");
DOM.removeClassName($("ups_cell" + this.selectedPicid), "ups_selected_cell");
}
this.selectedPicid = picid;
if (picid) {
// find the current pic and cell
var picimg = $("ups_upicimg" + picid);
var cell = $("ups_cell" + picid);
if (!picimg || !cell)
return;
// hilight the userpic
DOM.addClassName(picimg, "ups_selected");
// hilight the cell
DOM.addClassName(cell, "ups_selected_cell");
// enable the select button
$("ups_closebutton").disabled = false;
// select the current selectedPicid in the dropdown
this.setDropdown();
} else {
$("ups_closebutton").disabled = true;
}
},
// filter by keyword/comment
filterPics: function(evt) {
var searchbox = $("ups_search");
if (!searchbox)
return;
var filter = searchbox.value.toLocaleUpperCase();
var pics = this.pics;
if (!filter) {
this.setPics(pics);
return;
}
// if there is a filter and there is selected text in the field assume that it's
// inputcomplete text and ignore the rest of the selection.
if (searchbox.selectionStart && searchbox.selectionStart > 0)
filter = searchbox.value.substr(0, searchbox.selectionStart).toLocaleUpperCase();
var newpics = {
"pics": [],
"ids": []
};
for (var i=0; i<pics.ids.length; i++) {
var picid = pics.ids[i];
var pic = pics.pics[picid];
if (!pic)
continue;
for (var j=0; j < pic.keywords.length; j++) {
var kw = pic.keywords[j];
var piccomment = "";
if (pic.comment)
piccomment = pic.comment.toLocaleUpperCase();
var picalt = "";
if (pic.alt)
picalt = pic.alt.toLocaleUpperCase();
if(kw.toLocaleUpperCase().indexOf(filter) != -1 || // matches a keyword
(piccomment && piccomment.indexOf(filter) != -1) || // matches comment
(pic.keywords.join(", ").toLocaleUpperCase().indexOf(filter) != -1) || // matches comma-seperated list of keywords
(picalt && picalt.indexOf(filter) != -1)) { // matches description
newpics.pics[picid] = pic;
newpics.ids.push(picid);
break;
}
}
}
if (this.pics != newpics)
this.setPics(newpics);
// if we've filtered down to one pic and we don't currently have a selected pic, select it
if (newpics.ids.length == 1 && !this.selectedPicid)
this.selectPic(newpics.ids[0]);
},
setDropdown: function(pics) {
var menu = $("ups_kwmenu");
for (var i=0; i < menu.length; i++)
menu.remove(i);
menu.length = 0;
if (!pics)
pics = this.pics;
if (!pics || !pics.ids)
return;
for (var i=0; i < pics.ids.length; i++) {
var picid = pics.ids[i];
var pic = pics.pics[picid];
if (!pic)
continue;
var sel = false;
var self = this;
pic.keywords.forEach(function (kw) {
// add to dropdown
var picopt = document.createElement("option");
picopt.text = kw;
picopt.value = picid;
if (! sel) {
picopt.selected = self.selectedPicid ? self.selectedPicid == picid : false;
sel = picopt.selected;
}
Try.these(
function () { menu.add(picopt, 0); }, // everything else
function () { menu.add(picopt, null); } // IE
);
});
}
},
picsReceived: function(picinfo) {
if (picinfo && picinfo.alert) { // got an error
this.handleError(picinfo.alert);
return;
}
if (!picinfo || !picinfo.ids || !picinfo.pics || !picinfo.ids.length)
return;
var piccount = picinfo.ids.length;
// force convert integers to strings
for (var i=0; i < piccount; i++) {
var picid = picinfo.ids[i];
var pic = picinfo.pics[picid];
if (!pic)
continue;
if (pic.comment)
pic.comment += "";
for (var j=0; j < pic.keywords.length; j++)
pic.keywords[j] += "";
}
// set default scaling size based on how many pics there are
if (piccount < 30) {
this.imgScale = 1;
} else if (piccount < 60) {
this.imgScale = 2;
} else {
this.imgScale = 3;
}
this.pics = picinfo;
this.setPics(picinfo);
this.redraw();
if (this.hourglass)
this.hourglass.hide();
},
redraw: function () {
this.setStatus();
if (!this.pics)
return;
this.setPics(this.pics);
if (this.hourglass)
this.hourglass.hide();
var keywords = [], comments = [];
for (var i=0; i < this.pics.ids.length; i++) {
var picid = this.pics.ids[i];
var pic = this.pics.pics[picid];
for (var j=0; j < pic.keywords.length; j++)
keywords.push(pic.keywords[j]);
comments.push(pic.comment);
}
var searchbox = $("ups_search");
var compdata = new InputCompleteData(keywords.concat(comments));
var whut = new InputComplete(searchbox, compdata);
DOM.addEventListener(searchbox, "keydown", this.filterPics.bind(this));
DOM.addEventListener(searchbox, "keyup", this.filterPics.bind(this));
DOM.addEventListener(searchbox, "focus", this.filterPics.bind(this));
try {
searchbox.focus();
} catch(e) {}
DOM.addEventListener($("ups_kwmenu"), "change", this.kwmenuChange.bindEventListener(this));
},
setPics: function(pics) {
if (this.displayPics == pics)
return;
this.displayPics = pics;
this.setField({'pics': pics});
this.setDropdown(pics);
},
handleError: function(err) {
log("Error: " + err);
this.hourglass.hide();
},
loadPics: function() {
this.hourglass = new Hourglass($("ups_userpics"));
var reqOpts = {};
reqOpts.url = Site.currentJournal ? "/" + Site.currentJournal + "/__rpc_userpicselect" : "/__rpc_userpicselect";
reqOpts.onData = this.picsReceived.bind(this);
reqOpts.onError = this.handleError.bind(this);
HTTPReq.getJSON(reqOpts);
}
});
// Templates
UserpicSelect.top = "\
<div class='ups_search'>\
<span class='ups_searchbox'>\
Search: <input type='text' id='ups_search'>\
Select: <select id='ups_kwmenu'><option value=''></option></select>\
</span>\
</div>\
<div id='ups_dynamic'></div>";
UserpicSelect.dynamic = "\
[# if (status) { #] <div class='ups_status'>[#| status #]</div> [# } #]\
<div class='ups_userpics' id='ups_userpics'>\
[#= context.include( 'userpics' ) #]\
&nbsp;\
</div>\
<div class='ups_closebuttonarea'>\
<input type='button' id='ups_closebutton' value='Select' disabled='true' />\
<span id='ups_scaling_buttons'>\
</span>\
</div>";
UserpicSelect.userpics = "\
[# if(pics && pics.ids) { #] \
<table summary='' class='ups_table' cellpadding='0' cellspacing='0' id='ups_userpics_t'> [# \
var rownum = 0; \
for (var i=0; i<pics.ids.length; i++) { \
var picid = pics.ids[i]; \
var pic = pics.pics[picid]; \
\
if (!pic) \
continue; \
\
var pickws = pic.keywords; \
if (i%2 == 0) { #] \
<tr class='ups_row ups_row[#= rownum++ % 2 + 1 #]'> [# } #] \
\
<td class='ups_cell' \
lj_ups:picid='[#= picid #]' id='ups_cell[#= picid #]'> \
<div class='ups_container'> \
<img src='[#= pic.url #]' width='[#= finiteInt(pic.width/imgScale) #]' \
alt='[#= pic.alt #]' \
height='[#= finiteInt(pic.height/imgScale) #]' id='ups_upicimg[#= picid #]' class='ups_upic' /> \
</div> \
\
<b>[#| pickws.join(', ') #]</b> \
[# if(pic.comment) { #]<br/>[#= pic.comment #][# } #] \
<div class='ljclear'>&nbsp;</div>\
</td> \
\
[# if (i%2 == 1 || i == pics.ids.length - 1) { #] </tr> [# } \
} #] \
</table> \
[# } #] \
";
// Copied here from entry.js
function insertViewThumbs() {
var lj_userpicselect = $('lj_userpicselect');
lj_userpicselect.innerHTML = 'View Thumbnails';
}