This commit is contained in:
2019-02-06 00:49:12 +03:00
commit 8dbb1bb605
4796 changed files with 506072 additions and 0 deletions

View File

@@ -0,0 +1,209 @@
<?_code
my $remote = LJ::get_remote();
my $user = $FORM{'user'};
my $u = LJ::load_user($user);
my $userid = $u->{userid};
$body = "";
LJ::set_active_crumb('addfriends');
unless ($remote)
{
$title = $ML{'.error1.title'};
$body = "<?h1 $ML{'.error1.header'} h1?><?p $ML{'.error1.text'} p?>";
return;
}
unless ($user && $userid)
{
$title = $ML{'Error'};
$body = $ML{'.error2.text'};
return;
}
if ($FORM{'mode'} eq "add")
{
unless (LJ::did_post()) {
$title = $ML{'Error'};
$body = "<?h1 $ML{'Error'} h1?><?p <?requirepost?> p?>";
return;
}
unless ($remote->{'userid'} == $FORM{'remid'}) {
$title = $ML{'Error'};
$body = "<?h1 $ML{'Error'} h1?><?p Session info changed. Try again. p?>";
return;
}
my $gmask = 1;
foreach my $bit (1..30) {
next unless $FORM{"bit_$bit"};
$gmask |= (1 << $bit);
}
my $req = {
"user" => $remote->{'user'},
"mode" => "editfriends",
"ver" => $LJ::PROTOCOL_VER,
};
if ($FORM{'action:delete'}) {
$req->{"editfriend_delete_$user"} = 1;
} else {
$req->{"editfriend_add_1_user"} = $user;
$req->{"editfriend_add_1_fg"} = $FORM{'editfriend_add_1_fg'};
$req->{"editfriend_add_1_bg"} = $FORM{'editfriend_add_1_bg'};
$req->{"editfriend_add_1_groupmask"} = $gmask;
}
my %res = ();
LJ::do_request($req, \%res,
{ "noauth" => 1, "userid" => $remote->{'userid'} } );
if ($res{'success'} eq "OK")
{
if ($FORM{'action:delete'}) {
$title = $ML{'.remove.title'};
$body = "<?h1 $ML{'.remove.header'} h1?><?p " .
BML::ml('.remove.text', {'user'=>$user,
'ljuser' => LJ::ljuser($u),
'url'=>"$LJ::SITEROOT/users/$remote->{'user'}/friends"}) .
" p?>";
} else {
$title = $ML{'.add.title'};
$body = "<?h1 $ML{'.add.header'} h1?><?p " .
BML::ml('.add.text', { 'user' => $user,
'ljuser' => LJ::ljuser($u),
'url' => "$LJ::SITEROOT/users/$remote->{'user'}/friends", }) .
" p?>";
}
} else {
$title = $ML{'Error'};
$body = "<?h1 $ML{'Error'} h1?><?p $res{'errmsg'} p?>";
}
return;
}
# check to see if user is already a friend.
# TAG:fr:bml_friends_add:check_is_friend
my $dbr = LJ::get_db_reader();
$sth = $dbr->prepare("SELECT * FROM friends WHERE userid=$remote->{'userid'} AND friendid=$userid");
$sth->execute;
my $fr = $sth->fetchrow_hashref;
if ($fr) {
$title .= $ML{'.error3.title'};
$body .= "<?h1 $ML{'.error3.title'} h1?><?p " .
BML::ml('.error3.text', {'user'=>$user}) . " p?>";
} else {
# was this a syndicated add?
if ($u->{journaltype} eq 'Y') {
$title = $ML{'.confirm.syn.title'};
$body .= "<?h1 " . BML::ml('.confirm.syn.header', { user => $user }) . " h1?>";
} else {
$title .= $ML{'.confirm.title'};
$body .= "<?h1 " . BML::ml(".confirm.header", { 'user' => $user }) . " h1?>";
}
$body .= "<?p " . BML::ml(".confirm.text", { 'user' => $user }) . " p?>";
}
$body .= "<form method='post' action='add.bml'>";
$body .= LJ::html_hidden(mode => 'add',
user => $user,
remid => $remote->{userid});
if ($fr) {
$body .= "<center><input type='submit' value=\"$ML{'.btn.modify'}\">";
$body .= " - <input type='submit' name='action:delete' value=\"$ML{'.btn.remove'}\"></center>";
} else {
$body .= "<center><input type='submit' value=\"" .
BML::ml('.btn.add', {'user'=>$user}) . "\"></center>";
}
## let them pick friend groups
$body .= "<?h1 $ML{'.groups.header'} h1?><?p $ML{'.groups.text'} p?><blockquote>";
my $err;
my $greq = LJ::Protocol::do_request("getfriendgroups", {
'username' => $remote->{'user'},
'ver' => $LJ::PROTOCOL_VER,
}, \$err, { 'noauth' => 1 });
if (@{$greq->{'friendgroups'}}) {
foreach my $g (@{$greq->{'friendgroups'}}) {
my $ck = ($fr && ($fr->{'groupmask'} & (1 << $g->{'id'}))) ?
"checked='1'" : "";
# by default, newly added friends are in default view unless unchecked
$ck = "checked='1'" if (! $fr && $g->{'name'} eq "Default View");
$body .= "<input type='checkbox' value='1' name='bit_$g->{'id'}' $ck> ";
$body .= LJ::ehtml($g->{'name'}) . "<br />\n";
}
} else {
$body .= "<i>$ML{'.groups.nogroup'}</i>";
}
$body .= "</blockquote>";
## let them pick the colors
$body .= "<?h1 $ML{'.colors.header'} h1?><?p " .
BML::ml('.colors.text', {'user'=>$user}) . " p?>";
$ret = "";
$ret .= "<P><CENTER><TABLE CELLPADDING=4><TR><TD><B>$ML{'.colors.fg'}</B></TD><TD><B>$ML{'.colors.bg'}</B></TD></TR>\n";
my @color = ();
LJ::load_codes({ "color" => \@color });
my $sel = $fr || { 'fgcolor' => hex '000000',
'bgcolor' => hex 'FFFFFF', };
$ret .= "<TR>";
$ret .= "<TD><SELECT NAME=\"editfriend_add_1_fg\">";
foreach (@color) {
my $color_int = hex (substr($_->{'code'},1));
my $selected = $color_int eq $sel->{'fgcolor'} ? " SELECTED" : "";
$ret .= "<OPTION VALUE=\"$_->{'code'}\"$selected>$_->{'item'}\n";
}
$ret .= "</SELECT></TD>\n";
$ret .= "<TD><SELECT NAME=\"editfriend_add_1_bg\">";
foreach (@color) {
my $color_int = hex (substr($_->{'code'},1));
my $selected = $color_int eq $sel->{'bgcolor'} ? " SELECTED" : "";
$ret .= "<OPTION VALUE=\"$_->{'code'}\"$selected>$_->{'item'}\n";
}
$ret .= "</SELECT></TD>\n";
$ret .= "</TR>\n";
$ret .= "</TABLE>\n";
### color swatch
my $col = 0;
$ret .= "<P><TABLE border=0 cellspacing=0 cellpadding=0>";
foreach (@color) {
if ($col==0) { $ret .= "<TR>\n"; }
$col++;
my $ecolor = LJ::ehtml($_->{'item'});
$ret .= "<TD bgcolor=$_->{'code'}><IMG SRC=\"/img/dot.gif\" WIDTH=14 HEIGHT=14 TITLE=\"$ecolor\" ALT=\"$ecolor\"></TD>\n";
if ($col==23) { $ret .= "</TR>\n"; $col==0; }
}
if ($col) { $ret .= "</TR>\n"; $col==0; }
$ret .= "</TABLE>\n";
$ret .= "<FONT SIZE=-2 FACE=\"Arial,Helvetica\">$ML{'.colors.hover'}</FONT>";
$ret .= "</CENTER>\n";
$body .= $ret;
$body .= "</form>";
return;
_code?>
<?page
title=><?_code return $title; _code?>
body=><?_code return $body; _code?>
page?><?_c <LJDEP>
link: htdocs/login.bml, htdocs/create.bml, htdocs/friends/edit.bml, htdocs/users
img: htdocs/img/dot.gif
post: htdocs/friends/add.bml
</LJDEP> _c?>

View File

@@ -0,0 +1,290 @@
<?page
title=><?_ML .title _ML?>
body<=
<?_code
{
use strict;
use vars qw(%GET %POST);
return LJ::server_down_html() if ($LJ::SERVER_DOWN);
return "<?badinput?>" unless LJ::text_in(\%POST);
LJ::set_active_crumb('editfriends');
# this file used to be edit_do.bml, but edit.bml died, so we moved this
# functionality to edit.bml, but we don't want the translators to have to
# retranslate all of the phrases, so we're still using /edit_do.bml scope
BML::set_language_scope("/friends/edit_do.bml");
my $remote = LJ::get_remote();
return LJ::bad_input($ML{'error.noremote'})
unless $remote;
my $authas = $GET{'authas'} || $remote->{'user'};
my $getextra = $authas ne $remote->{'user'} ? "?authas=$authas" : '';
my $u = LJ::get_authas_user($authas);
return LJ::bad_input("You could not be authenticated as the specified user.")
unless $u;
return BML::redirect("$LJ::SITEROOT/community/members.bml?comm=$u->{'user'}")
if $u->{'journaltype'} eq 'C';
return LJ::bad_input("Cannot modify friends of this journal type.")
unless $u->{'journaltype'} =~ /^[PSI]$/;
my $ret;
# no post, show edit form
unless (LJ::did_post()) {
# user switcher
$ret .= "<form action='edit.bml' method='get'>\n";
$ret .= LJ::make_authas_select($remote,
{ 'authas' => $GET{'authas'},
'type' => ['P', 'S'] });
$ret .= "</form>\n\n";
$ret .= "<form method='post' name='editFriends' action='edit.bml$getextra'>\n";
### who has you defined as a friend?
my %res = ();
LJ::do_request({
"user" => $u->{'user'},
"mode" => "friendof",
"ver" => $LJ::PROTOCOL_VER,
}, \%res, { "noauth" => 1, 'u' => $u });
### who do you have defined as a friend?
my %resf = ();
LJ::do_request({
"user" => $u->{'user'},
"mode" => "getfriends",
"ver" => $LJ::PROTOCOL_VER,
}, \%resf, { "noauth" => 1, 'u' => $u });
# build hash for checking if user is friend
my %isfriend = map { $resf{"friend_${_}_user"}, 1 } 1..$resf{'friend_count'};
### table of friend-ofs
if ($res{'friendof_count'}) {
$ret .= "<?h1 $ML{'.fellowfriends.head'} h1?><?p $ML{'.fellowfriends.text'} p?>\n";
$ret .= "<table style='margin-top: 20px;' align='center'>\n";
$ret .= "<tr bgcolor='<?emcolor?>'><td width='150'><b>$ML{'.user'}</b></td>";
$ret .= "<td width='200'><b>$ML{'.name'}</b></td>";
$ret .= "<td align='center'><b>$ML{'.opt.addtolist'}</b></td></tr>";
my $friendnum = 6; # 1-5 are new friends from the add form
for my $i (1..$res{'friendof_count'}) {
my $fo_user = $res{"friendof_${i}_user"};
$ret .= "<tr align='left'><td>" . LJ::ljuser($fo_user) . "</td>";
$ret .= "<td><label for='editfriend_add_${friendnum}_user'>";
$ret .= LJ::ehtml($res{"friendof_${i}_name"}) . "</label></td><td align='center'>";
my $dis = $isfriend{$fo_user} ? 1 : 0;
$ret .= LJ::html_check({ 'type' => 'check',
'name' => "editfriend_add_${friendnum}_user",
'id' => "editfriend_add_${friendnum}_user",
'value' => $fo_user, 'disabled' => $dis });
$friendnum++;
$ret .= "</td></tr>";
}
$ret .= "</table>";
}
### table of friends
if ($resf{'friend_count'}) {
$ret .= "<?h1 $ML{'.yourfriends.head'} h1?><?p $ML{'.yourfriends.text'} p?>\n";
$ret .= "<p align='center'><table style='margin-top: 20px;' align='center'>";
$ret .= "<tr bgcolor='<?emcolor?>'><td width='150'><b>$ML{'.friend'}</b></td>";
$ret .= "<td width='250'><b>$ML{'.name'}</b></td>";
$ret .= "<td align='center'><b>$ML{'.opt.delete'}</b></td></tr>\n";
foreach my $i (1..$resf{'friend_count'}) {
my $fruser = $resf{"friend_${i}_user"};
$isfriend{$fruser} = 1;
my $bgcolor = $resf{"friend_${i}_bg"} || "#FFFFFF";
my $fgcolor = $resf{"friend_${i}_fg"} || "#000000";
my $status = $resf{"friend_${i}_status"};
my $userlink = LJ::ljuser($fruser);
if ($status eq 'deleted' || $status eq 'purged' || $status eq 'suspended') {
$userlink = "<strike>$userlink</strike>";
}
$ret .= "<tr align='left'><td>$userlink</td>";
$ret .= "<td bgcolor='$bgcolor'><font color='$fgcolor'>";
$ret .= "<label for='editfriend_delete_${fruser}'>";
$ret .= LJ::ehtml($resf{"friend_${i}_name"}) . "</label>";
$ret .= "</font></td><td align='center'>";
$ret .= LJ::html_check({ 'type' => 'check',
'name' => "editfriend_delete_${fruser}",
'id' => "editfriend_delete_${fruser}"});
$ret .= "</td></tr>\n";
}
$ret .= "</table></p>\n\n";
} else {
$ret .= "<?h1 $ML{'.nofriends.head'} h1?><?p $ML{'.nofriends.text'} p?>\n\n";
}
### add friends
$ret .= "<?h1 $ML{'.addfriends.head'} h1?><?p $ML{'.addfriends.text'} p?>\n";
$ret .= "<p align='center'><input type='button' value='" . LJ::ehtml($ML{'.btn.toggle'}) . "' ";
$ret .= "onClick='togglePreview(); return true;'></p>\n";
$ret .= "<table cellpadding='4' align='center'>\n";
$ret .= "<tr><td><b>$ML{'.friend'}</b></td><td><b>$ML{'.foreground'}</b></td><td><b>$ML{'.background'}</b></td></tr>\n";
# load the colors
my @color = ();
LJ::load_codes({ "color" => \@color });
foreach my $i (1..5) {
$ret .= "<tr><td>";
$ret .= LJ::html_text({ 'name' => "editfriend_add_${i}_user",
'size' => '15', 'maxlength' => '15',
'onchange' => "updatePreview(); return true;",
'onfocus' => "setFriend($i);" });
$ret .= "</td><td>";
$ret .= LJ::html_select({ 'name' => "editfriend_add_${i}_fg",
'selected' => '#000000',
'onchange' => "updatePreview(); return true;",
'onfocus' => "setFriend($i);" },
map { lc($_->{'code'}), $_->{'item'} } @color );
$ret .= "</td><td>";
$ret .= LJ::html_select({ 'name' => "editfriend_add_${i}_bg",
'selected' => '#ffffff',
'onchange' => "updatePreview(); return true;",
'onfocus' => "setFriend($i);" },
map { lc($_->{'code'}), $_->{'item'} } @color );
$ret .= "</td></tr>\n";
}
$ret .= "</table>";
### color swatch
my $col = 0;
$ret .= "<table border='0' cellspacing='0' cellpadding='0' align='center'>";
foreach (@color) {
if ($col==0) { $ret .= "<tr>\n"; }
$col++;
my $ecolor = LJ::ehtml($_->{'item'});
$ret .= "<td bgcolor='$_->{'code'}'><img src='/img/dot.gif' width='14' height='14' title='$ecolor' alt='$ecolor' /></td>";
if ($col==23) { $ret .= "</tr>\n"; $col==0; }
}
if ($col) { $ret .= "</tr>\n"; $col==0; }
$ret .= "<tr><td colspan='23' align='center'><font size='-2' face='Arial,Helvetica'>($ML{'.hover'})</font></td></tr>";
$ret .= "</table>";
$ret .= "<p>$ML{'.needmore'}</p>\n";
### ending submit block
$ret .= "<?h1 $ML{'.done.head'} h1?><?p $ML{'.done.text'} p?>\n";
$ret .= "<?standout " . LJ::html_submit($ML{'.btn.save'}) . " standout?>\n";
$ret .= "</form>\n";
return $ret;
}
# if they did a post, then process their changes
if (LJ::did_post()) {
my %request = ();
$request{'mode'} = "editfriends";
$request{'ver'} = $LJ::PROTOCOL_VER;
$request{'user'} = $u->{'user'};
foreach (grep { /^editfriend_/ } keys %POST) {
$request{$_} = $POST{$_};
}
my %response = ();
LJ::do_request(\%request, \%response, { 'noauth' => 1, 'u' => $u });
if ($response{'success'} eq "OK") {
# tell the user all is well
return "<?h1 $ML{'.success.head'} h1?><?p ".BML::ml(".success.text", {'url' => LJ::journal_base($u) . "/friends"})." p?>";
} else {
return "<?h1 $ML{'Error'} h1?><?p $ML{'.error.updating'} <ul><li><b>$response{'errmsg'}</b></ul> p?>\n";
}
}
return $ML{'error.unknownmode'};
}
_code?>
<=body
head<=
<?_code
{
use strict;
BML::set_language_scope("/friends/edit_do.bml");
my %ejs = map { $_, LJ::ejs($ML{".$_"}) } qw(mrcolor viewer textcolor bgcolor btn.close);
return qq{
<script language="JavaScript"><!--
previewOn = 0;
lastFriend = 0;
function setFriend (curfriend)
{
lastFriend = curfriend;
}
function togglePreview()
{
if (previewOn==0 || winPreview.closed) {
winPreview = window.open("", "preview", "toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=0,resizable=0,copyhistory=0,width=400,height=270");
previewOn = 1;
updatePreview();
} else {
winPreview.close();
previewOn = 0;
}
}
function updatePreview () {
if (previewOn == 0 || winPreview.closed) { return; }
frm = document.editFriends;
dropdown = frm["editfriend_add_"+lastFriend+"_fg"]
fg_color = dropdown.options[dropdown.selectedIndex].value;
fg_color_text = dropdown.options[dropdown.selectedIndex].text;
dropdown = frm["editfriend_add_"+lastFriend+"_bg"]
bg_color = dropdown.options[dropdown.selectedIndex].value;
bg_color_text = dropdown.options[dropdown.selectedIndex].text;
user_name = frm["editfriend_add_"+lastFriend+"_user"].value;
if (user_name.length==0) { user_name = "username"; }
d = winPreview.document;
d.open();
d.write("<html><head><title>$ejs{'mrcolor'}</title></head><body bgcolor='#ffffff' text='#000000'>");
d.write("<b><font face='Trebuchet MS, Arial, Helvetica' size='4' color='#000066'><i>$ejs{'viewer'}</i></font></b><hr />");
d.write("<br /><table width='350' align='center' cellpadding='5'><tr valign='middle'>");
d.write("<td width='80%'><b><font face='Arial, Helvetica' size='2'>");
d.write("$ejs{'textcolor'}&nbsp; <font color='#000066'>" + fg_color_text);
d.write("</font></b><br /></td><td width='20%' bgcolor=" + fg_color + ">&nbsp;</td>");
d.write("</tr><tr><td width='80%'><b><font face='Arial, Helvetica' size='2'>");
d.write("$ejs{'bgcolor'}&nbsp; <font color='#000066'>" + bg_color_text + "");
d.write("</font></b><br></td><td width='20%' bgcolor=" + bg_color + ">&nbsp;</td>");
d.write("</tr><tr><td><br /></tr><tr><td colspan='3' bgcolor=" + bg_color + "><font color=" + fg_color + ">");
d.write("<b>" + user_name + "</b></td></tr></table><br />");
d.write("<hr><form><div align='center'><input type='button' value='$ejs{'btn.close'}' onClick='self.close();'></div></form>");
d.write("</body></html>");
d.close();
}
// -->
</script>
}; # end qq{ }
}
_code?>
<=head
page?><?_c <LJDEP>
link: htdocs/create.bml, htdocs/lostinfo.bml
post: htdocs/friends/edit.bml
</LJDEP> _c?>

View File

@@ -0,0 +1,425 @@
<?_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?>

View File

@@ -0,0 +1,74 @@
<?_code
$title = $ML{'.title'};
$body = "";
LJ::set_active_crumb('friendsfilter');
if ($FORM{'mode'} eq "view")
{
my $user = lc($FORM{'user'});
my $filter = 0;
foreach my $k (keys %FORM) {
next unless ($k =~ /^bit_(\d+)$/);
my $bit = $1;
next if ($bit < 1 || $bit > 30);
$filter |= (1 << $bit);
}
my $extra = "?filter=$filter";
return BML::redirect("$LJ::SITEROOT/users/$user/friends${extra}");
}
my $remote = LJ::get_remote();
unless ($remote) { $body .= "<?needlogin?>"; return; }
my %res;
# FIXME: make this use LJ::Protocol::do_request
LJ::do_request({ 'mode' => 'getfriendgroups',
'ver' => $LJ::PROTOCOL_VER,
'user' => $remote->{'user'}, },
\%res, { 'noauth' => 1, 'userid' => $remote->{'userid'} });
unless ($res{'frgrp_maxnum'}) {
$body = "<?h1 $ML{'.error.nogroups.header'} h1?><?p $ML{'.error.nogroups'} p?>";
return;
}
my %group;
foreach $k (keys %res) {
if ($k =~ /^frgrp_(\d+)_name/) {
$group{$1}->{'name'} = $res{$k};
}
elsif ($k =~ /^frgrp_(\d+)_sortorder/) {
$group{$1}->{'sortorder'} = $res{$k};
}
}
$body .= "<?h1 $ML{'.select.header'} h1?><?p $ML{'.select'} p?>";
$body .= "<form method='post' style='display: inline' action='filter.bml'>\n";
$body .= LJ::html_hidden("user", $remote->{'user'},
"mode", "view");
$body .= "<div style='margin-left: 30px'>";
foreach my $g (sort { $group{$a}->{'sortorder'} <=> $group{$b}->{'sortorder'} } keys %group)
{
my $url = "$LJ::SITEROOT/users/$remote->{'user'}/friends/" . LJ::eurl($group{$g}->{'name'});
$body .= "<input type='checkbox' value='1' name=\"bit_$g\" /> <a href=\"$url\">" . LJ::ehtml($group{$g}->{'name'}) . "</a><br />\n";
}
$body .= "<input type='submit' value=\"$ML{'.submit'}\"> <input type='reset' value=\"$ML{'.reset'}\"></div>";
$body .= "<?p " . BML::ml('.editgroups', { 'link' => "<a href='editgroups.bml'>$ML{'/friends/editgroups.bml.title'}</a>" }) . " p?>";
$body .= "</form>";
return;
_code?><?page
title=><?_code return $title; _code?>
body=><?_code return $body; _code?>
page?><?_c <LJDEP>
link: htdocs/users, htdocs/friends/editgroups.bml
post: htdocs/friends/filter.bml
</LJDEP> _c?>

View File

@@ -0,0 +1,27 @@
<?_info
nocache=>1
_info?><?_code
if (BML::get_path_info() =~ m!^/(\w+)\.dot(\.txt)?$!) {
BML::set_content_type("text/plain");
return "# dot file for $1:\n" . LJ::make_graphviz_dot_file($1);
}
my $u = LJ::load_user($FORM{'user'});
unless ($u) {
return "<?h1 Unknown user h1?><?p No user with that username. Sorry. p?>";
}
my $user = $u->{'user'};
my $ret = "";
$ret .= "User: <B>$user</B> (<A HREF=\"/userinfo.bml?user=$user\">user info</A>)<BR><I>If image doesn't load, press reload.</I><P>";
$ret .= "<A HREF=http://www.research.att.com/~north/cgi-bin/webdot.cgi/";
$ret .= "$LJ::SITEROOT/friends/graph.bml/$user.dot.map>";
$ret .= "<IMG SRC=http://www.research.att.com/~north/cgi-bin/webdot.cgi/";
$ret .= "$LJ::SITEROOT/friends/graph.bml/$user.dot.gif ismap border=0>";
$ret .= "</A>\n";
return $ret;
_code?>

View File

@@ -0,0 +1,34 @@
<?page
title=><?_ml .title _ml?>
body<=
<?_code
LJ::set_active_crumb('friends');
_code?>
<?p <?_ml .about _ml?> p?>
<?h1 <?_ml .tools _ml?> h1?>
<dl>
<dt><a href="edit.bml"><?_ml /friends/edit.bml.title _ml?></a></dt>
<dd><?_ml .edit.about _ml?></dd>
</dl>
<?p <?_ml .groups _ml?> p?>
<dl>
<dt><a href="editgroups.bml"><?_ml /friends/editgroups.bml.title _ml?></a></dt>
<dd><?_ml .editgroups.about _ml?></dd>
</dl>
<?p <?_ml .filter _ml?> p?>
<dl>
<dt><a href="filter.bml"><?_ml /friends/filter.bml.title _ml?></a></dt>
<dd><?_ml .filter.about _ml?></dd>
</dl>
<?h1 <?_ml .security.header _ml?> h1?>
<?p <?_ml .security _ml?> p?>
<ul>
<li><?_ml .security.only _ml?></li>
<li><?_ml .security.custom _ml?></li>
</ul>
<=body
page?><?_c <LJDEP>
link: htdocs/friends/edit.bml, htdocs/friends/editgroups.bml
link: htdocs/friends/filter.bml, htdocs/download/index.bml
</LJDEP> _c?>