ljr/livejournal/htdocs/friends/editgroups.bml

426 lines
13 KiB
Plaintext
Executable File

<?_code
{
use strict;
use vars qw(%GET %POST $title $body);
LJ::set_active_crumb('editfriendgrps');
$title = $ML{'.title'};
$body = "";
my $err = sub {
$title = "Error";
$body = LJ::bad_input(@_);
return;
};
# these are only used by the client-side for JS to play with.
# we delete them because they may contain embedded NULLs, which
# text_in won't like.
delete $POST{'list_in'};
delete $POST{'list_out'};
unless (LJ::text_in(\%POST)) {
$body = "<?badinput?>";
return;
}
my $remote = LJ::get_remote();
return $err->($ML{'error.noremote'})
unless $remote;
my $authas = $GET{'authas'} || $remote->{'user'};
my $u = LJ::get_authas_user($authas);
return $err->($ML{'error.invalidauth'})
unless $u;
# extra arguments for get requests
my $getextra = $authas ne $remote->{'user'} ? "?authas=$authas" : '';
if ($POST{'mode'} eq "save") {
my %res;
$POST{'mode'} = "editfriendgroups";
$POST{'user'} = $u->{'user'};
$POST{'ver'} = $LJ::PROTOCOL_VER;
LJ::do_request(\%POST, \%res, {
'u' => $u,
'noauth' => 1,
});
if ($res{'success'} eq "OK") {
$body .= "<?h1 $ML{'.saved.header'} h1?><?p $ML{'.saved.text'} p?>";
} else {
$body .= "<?h1 $ML{'Error'} h1?><?p $ML{'.error.text'} p?><?p $res{'errmsg'} p?>";
}
return;
}
my %res;
LJ::do_request({ 'mode' => 'getfriends',
'user' => $u->{'user'},
'ver' => $LJ::PROTOCOL_VER,
'includegroups' => 1 },
\%res, { 'u' => $u,
'noauth' => 1, });
my @num_used;
my @num_free;
# authas switcher form
$body .= "<form method='get' action='editgroups.bml'>\n";
$body .= LJ::make_authas_select($remote, { 'authas' => $GET{'authas'} }) . "\n";
$body .= "</form>\n\n";
$body .= "<?h1 $ML{'.title'} h1?><?p $ML{'.text'} p?><?p $ML{'.text.sec'} p?><p>";
$body .= "<form method='post' name='fg' action='editgroups.bml$getextra'>";
$body .= "<input type='hidden' name='mode' value='save' />";
for (my $i=1; $i<=30; $i++) {
my $sort = 255;
my $name = "";
my $public = 0;
if ($res{"frgrp_${i}_name"}) {
$sort = $res{"frgrp_${i}_sortorder"}+0;
$name = LJ::ehtml($res{"frgrp_${i}_name"});
$public = $res{"frgrp_${i}_public"}+0;
push @num_used, $i;
} else {
push @num_free, $i;
}
$body .= "<input type='hidden' name='efg_set_${i}_name' value='$name' />";
$body .= "<input type='hidden' name='efg_set_${i}_sort' value='$sort' />";
$body .= "<input type='hidden' name='efg_delete_${i}' value='0' />";
$body .= "<input type='hidden' name='efg_set_${i}_public' value='$public' />";
}
for (my $i=1; $i<=$res{'friend_count'}; $i++) {
my $user = $res{"friend_${i}_user"};
my $mask = $res{"friend_${i}_groupmask"} || 1;
$body .= "<input type='hidden' name='editfriend_groupmask_$user' value='$mask' />";
}
# escape strings for JavaScript
my %T = qw(public .group.public
rename .prompt.rename
newname .prompt.newname
delete .confirm.delete
max30 .error.max30
);
foreach (keys %T) { $T{$_} = LJ::ejs($ML{$T{$_}}); }
$body .= <<"END_JS";
<SCRIPT LANGUAGE="JavaScript"><!--
var selectedGroup = 0;
function eraseList (list)
{
while (list.length) {
list.options[0] = null;
}
}
function groupClicked ()
{
var selIndex;
var form = document.fg;
var grouplist = form.list_groups;
var inlist = form.list_in;
var outlist = form.list_out;
// figure out what they clicked, and bring their focus up to first free blank
selIndex = grouplist.selectedIndex;
if (selIndex == -1) { return; }
var groupname = grouplist.options[selIndex].text;
var newSelGroup = grouplist.options[selIndex].value;
if (newSelGroup == selectedGroup) { return; }
selectedGroup = newSelGroup;
// clears the other "not in" and "in" boxes
eraseList(inlist);
eraseList(outlist);
// iterate over all friends, putting them in one group or the other
var i;
for (i=0; i<form.elements.length; i++) {
var name = form.elements[i].name;
var mask = form.elements[i].value;
if (name.substring(0, 21) == "editfriend_groupmask_") {
var user = name.substring(21, name.length);
var list = mask & (1 << selectedGroup) ? inlist : outlist;
var optionName = new Option(user, user, false, false)
list.options[list.length] = optionName;
}
}
}
function moveItems (from, to, bitstatus)
{
var selindex;
while ((selindex=from.selectedIndex) != -1)
{
var i;
var item = new Option(from.options[selindex].text,
from.options[selindex].value,
false, true);
from.options[selindex] = null;
//to.options[to.options.length] = item;
// find spot to put new item
for (i=0; i<to.options.length && to.options[i].text < item.text; i++) { }
var newindex = i;
// move everything else down
for (i=to.options.length; i>newindex; i--) {
to.options[i] = new Option(to.options[i-1].text,
to.options[i-1].value,
false,
to.options[i-1].selected);
}
to.options[newindex] = item;
// turn the groupmask bit on or off
var user = item.value;
var element = document.fg["editfriend_groupmask_"+user];
var mask = element.value;
if (bitstatus) {
mask |= (1 << selectedGroup);
} else {
mask &= ~(1 << selectedGroup);
}
element.value = mask;
}
}
function moveIn ()
{
if (! selectedGroup) { return; }
var form = document.fg;
var inlist = form.list_in;
var outlist = form.list_out;
moveItems(document.fg.list_out, document.fg.list_in, true);
}
function moveOut ()
{
if (! selectedGroup) { return; }
moveItems(document.fg.list_in, document.fg.list_out, false);
}
function moveGroup (dir)
{
var list = document.fg.list_groups;
var selindex = list.selectedIndex;
if (selindex==-1) { return; }
var toindex = selindex+dir;
if (toindex < 0 || toindex >= list.options.length) { return; }
var selopt = new Option(list.options[selindex].text,
list.options[selindex].value,
false,
list.options[selindex].selected);
var toopt = new Option(list.options[toindex].text,
list.options[toindex].value,
false,
list.options[toindex].selected);
list.options[toindex] = selopt;
list.options[selindex] = toopt;
// stupid mozilla necessity:
list.selectedIndex = toindex;
setSortOrders();
}
function setSortOrders ()
{
var list = document.fg.list_groups;
// set all their sort orders now
var i;
for (i=0; i<list.options.length; i++) {
var item = list.options[i];
var key = "efg_set_"+item.value+"_sort";
document.fg[key].value = (i+1)*5;
}
}
function realName (name)
{
var rname = name;
var index = name.lastIndexOf(" $T{'public'}");
if (index != -1) {
rname = name.substr(0, index);
}
return rname;
}
function renameGroup ()
{
var list = document.fg.list_groups;
var selindex = list.selectedIndex;
if (selindex==-1) { return; }
var item = list.options[selindex];
var newtext = realName(item.text);
newtext = prompt("$T{'rename'}", newtext);
if (newtext==null || newtext == "") { return; }
var gnum = item.value;
document.fg["efg_set_"+gnum+"_name"].value = newtext;
if (document.fg["efg_set_"+gnum+"_public"].value == 1) {
newtext = newtext + " $T{'public'}";
}
item.text = newtext;
}
function deleteGroup ()
{
var list = document.fg.list_groups;
var selindex = list.selectedIndex;
if (selindex==-1) { return; }
var item = list.options[selindex];
var conf = confirm("$T{'delete'}");
if (!conf) { return; }
// mark it to be deleted later
var gnum = item.value;
document.fg["efg_delete_"+gnum].value = "1";
document.fg["efg_set_"+gnum+"_name"].value = "";
// as per the protocol documentation, unset bit on all friends
var i;
var form = document.fg;
for (i=0; i<form.elements.length; i++) {
var name = form.elements[i].name;
if (name.substring(0, 21) == "editfriend_groupmask_") {
var user = name.substring(21, name.length);
var mask = form.elements[i].value;
mask &= ~(1 << gnum);
form.elements[i].value = mask;
}
}
// clean up the UI
list.options[selindex] = null;
eraseList(document.fg.list_in);
eraseList(document.fg.list_out);
}
function makePublic ()
{
var list = document.fg.list_groups;
var selindex = list.selectedIndex;
if (selindex==-1) { return; }
var item = list.options[selindex];
var name = realName(item.text);
item.text = name + " $T{'public'}";
var gnum = item.value;
document.fg["efg_set_"+gnum+"_public"].value = "1";
}
function makePrivate ()
{
var list = document.fg.list_groups;
var selindex = list.selectedIndex;
if (selindex==-1) { return; }
var item = list.options[selindex];
var name = realName(item.text);
item.text = name;
var gnum = item.value;
document.fg["efg_set_"+gnum+"_public"].value = "0";
}
function newGroup ()
{
var form = document.fg;
var i;
var foundg = false;
for (i=1; i<=30; i++) {
if (form["efg_delete_"+i].value==1) { continue; }
if (form["efg_set_"+i+"_name"].value!="") { continue; }
foundg = true;
break;
}
if (! foundg) {
alert("$T{'max30'}");
return;
}
var gnum = i;
var groupname = prompt("$T{'newname'}", "");
if (groupname==null || groupname=="") { return; }
form["efg_set_"+gnum+"_name"].value = groupname;
var item = new Option(groupname, gnum, false, true);
var list = form.list_groups;
list.options[list.options.length] = item;
list.options.selectedIndex = list.options.length-1;
setSortOrders();
groupClicked();
}
// --></SCRIPT>
END_JS
$body .= "<table cellspacing='5'><tr valign='bottom'>";
$body .= "<td nowrap='1' colspan='2'><strong>$ML{'.yourgroups'}</strong></td>";
$body .= "<td nowrap='1' colspan='2'><strong>$ML{'.ingroup.not'}</strong></td>";
$body .= "<td nowrap='1'><strong>$ML{'.ingroup'}</strong></td></tr>";
$body .= "<tr valign='top'>";
$body .= "<td><select name='list_groups' style='width: 150px;' size='15' onchange='groupClicked();'>";
foreach my $num (sort { $res{"frgrp_${a}_sortorder"} <=>
$res{"frgrp_${b}_sortorder"} } @num_used) {
my $listname = $res{"frgrp_${num}_name"};
$listname .= " $ML{'.group.public'}" if $res{"frgrp_${num}_public"};
$body .= "<option value='$num'>" . LJ::ehtml($listname);
}
$body .= "</select></td>";
$body .= "<td valign='middle'>";
$body .= "<input type='button' value='$ML{'.btn.mv.up'}' onClick='moveGroup(-1);' /><br /><br />";
$body .= "<input type='button' value='$ML{'.btn.mv.down'}' onClick='moveGroup(1);' /></td>";
$body .= "<td><select name='list_out' multiple='1' size='15'>";
$body .= "<option value=''>---------------</option></select></td>";
$body .= "<td valign='middle'>";
$body .= "<input type='button' onClick='moveIn();' value='&gt;&gt;' /><br /><br />";
$body .= "<input type='button' onClick='moveOut();' value='&lt;&lt;' /></td>";
$body .= "<td><select name='list_in' multiple='1' size='15'>";
$body .= "<option value=''>---------------</option></select></td>";
$body .= "</tr><tr><td colspan='2'>";
$body .= "<nobr>";
$body .= "<input type='button' value='$ML{'.btn.ge.new'}' onClick='newGroup();' /> ";
$body .= "<input type='button' value='$ML{'.btn.ge.del'}' onClick='deleteGroup();' /> ";
$body .= "<input type='button' value='$ML{'.btn.ge.ren'}' onClick='renameGroup();' />";
$body .= "</nobr><br /><nobr>";
$body .= "<input type='button' value='$ML{'.btn.gs.public'}' onClick='makePublic();' /> ";
$body .= "<input type='button' value='$ML{'.btn.gs.private'}' onClick='makePrivate();' />";
$body .= "</nobr></td><td></td><td></td><td></td>";
$body .= "</tr></table>";
$body .= "<?h1 $ML{'.done.header'} h1?><?p $ML{'.done.text'} p?>";
$body .= "<?p <input type='submit' value='$ML{'.done.btn'}' /> p?>";
$body .= "</form>";
return;
}
_code?><?page
title=><?_code return $title; _code?>
body=><?_code return $body; _code?>
page?><?_c <LJDEP>
link: htdocs/login.bml
post: htdocs/friends/editgroups.bml
</LJDEP> _c?>