[livejournal] r20540: LJSUP-9907: Navigation bar on daleyed en...
Committer: sbelyaev
LJSUP-9907: Navigation bar on daleyed entry pagU trunk/cgi-bin/LJ/DelayedEntry.pm U trunk/cgi-bin/LJ/Talk.pm U trunk/htdocs/go.bml
Modified: trunk/cgi-bin/LJ/DelayedEntry.pm
===================================================================
--- trunk/cgi-bin/LJ/DelayedEntry.pm 2011-11-15 11:12:11 UTC (rev 20539)
+++ trunk/cgi-bin/LJ/DelayedEntry.pm 2011-11-15 12:10:16 UTC (rev 20540)
@@ -951,6 +951,60 @@
"ORDER BY is_sticky DESC, revptime $sql_limit");
}
+sub get_first_entry {
+ my ( $journal, $userid ) = @_;
+ __assert($journal, "no journal");
+
+ my $dbcr = LJ::get_cluster_def_reader($journal)
+ or die "get cluster for journal failed";
+
+ my $u;
+ my $sql_poster = '';
+
+ unless ($userid) {
+ $u = LJ::get_remote();
+ } else {
+ $u = LJ::want_user($userid);
+ }
+
+ return 0 unless $u;
+ if (!__delayed_entry_can_see( $journal, $u ) ){
+ $sql_poster = 'AND posterid = ' . $u->userid . " ";
+ }
+
+ my ($id) = $dbcr->selectrow_array("SELECT delayedid " .
+ "FROM delayedlog2 WHERE journalid=? $sql_poster".
+ "ORDER BY is_sticky ASC, revptime DESC LIMIT 1", undef, $journal->userid);
+ return $id || 0;
+}
+
+sub get_last_entry {
+ my ( $journal, $userid ) = @_;
+ __assert($journal, "no journal");
+
+ my $dbcr = LJ::get_cluster_def_reader($journal)
+ or die "get cluster for journal failed";
+
+ my $u;
+ my $sql_poster = '';
+ unless ($userid) {
+ $u = LJ::get_remote();
+ } else {
+ $u = LJ::want_user($userid);
+ }
+
+ return 0 unless $u;
+ if (!__delayed_entry_can_see( $journal, $u ) ){
+ $sql_poster = 'AND posterid = ' . $u->userid . " ";
+ }
+
+ my ($id) = $dbcr->selectrow_array("SELECT delayedid " .
+ "FROM delayedlog2 WHERE journalid=? $sql_poster".
+ "ORDER BY is_sticky DESC, revptime ASC LIMIT 1", undef, $journal->userid);
+ return $id || 0;
+}
+
+
sub get_daycount_query {
my ($class, $journal, $list, $secwhere) = @_;
my $dbcr = LJ::get_cluster_def_reader($journal);
@@ -1148,12 +1202,16 @@
sub get_itemid_near2 {
my ($u, $delayedid, $after_before) = @_;
-
- my ($order, $cmp1, $cmp2, $cmp3, $cmp4);
+
+ my $jid = $u->userid;
+ my $remote = LJ::get_remote();
+ return 0 unless $remote;
+
+ my ($order, $order_sticky, $cmp1, $cmp2, $cmp3, $cmp4);
if ($after_before eq "after") {
- ($order, $cmp1, $cmp2, $cmp3, $cmp4) = ("DESC", "<=", ">", sub {$a->[0] <=> $b->[0]}, sub {$b->[1] <=> $a->[1]} );
+ ($order, $order_sticky, $cmp1, $cmp2, $cmp3, $cmp4) = ("DESC", "ASC", "<=", ">", sub {$a->[0] <=> $b->[0]}, sub {$b->[1] <=> $a->[1]} );
} elsif ($after_before eq "before") {
- ($order, $cmp1, $cmp2, $cmp3, $cmp4) = ("ASC", ">=", "<", sub {$b->[0] <=> $a->[0]}, sub {$a->[1] <=> $b->[1]} );
+ ($order, $order_sticky, $cmp1, $cmp2, $cmp3, $cmp4) = ("ASC", "DESC",">=", "<", sub {$b->[0] <=> $a->[0]}, sub {$a->[1] <=> $b->[1]} );
} else {
return 0;
}
@@ -1163,77 +1221,43 @@
warn "Can't connect to cluster reader. Cluster: " . $u->clusterid;
return 0;
}
-
- my $jid = $u->userid;
- my $field = $u->is_person() ? "revptime" : "rlogtime";
-
- my ($stime) = $dbr->selectrow_array( "SELECT $field FROM delayedlog2 WHERE ".
- "journalid=$jid AND delayedid=$delayedid");
+
+ my ($stime, $is_current_sticky) = $dbr->selectrow_array( "SELECT revptime, is_sticky FROM delayedlog2 WHERE ".
+ "journalid=$jid AND delayedid=$delayedid");
return 0 unless $stime;
- my $secwhere = "AND security='public'";
- my $remote = LJ::get_remote();
-
- if ($remote) {
- if ($remote->userid == $jid) {
- $secwhere = ""; # see everything
- } elsif ($remote->is_person() || $remote->is_identity) {
- my $gmask = LJ::get_groupmask($u, $remote);
- $secwhere = "AND (security='public' OR (security='usemask' AND allowmask & $gmask))"
- if $gmask;
- }
+ my $sql_poster = '';
+ if (!__delayed_entry_can_see( $u, $remote ) ){
+ $sql_poster = 'AND posterid = ' . $remote->userid . " ";
}
- ##
- ## We need a next/prev record in journal before/after a given time
- ## Since several records may have the same time (time is rounded to 1 minute),
- ## we're ordering them by jitemid. So, the SQL we need is
- ## SELECT * FROM log2
- ## WHERE journalid=? AND rlogtime>? AND jitmemid<?
- ## ORDER BY rlogtime, jitemid DESC
- ## LIMIT 1
- ## Alas, MySQL tries to do filesort for the query.
- ## So, we sort by rlogtime only and fetch all (2, 10, 50) records
- ## with the same rlogtime (we skip records if rlogtime is different from the first one).
- ## If rlogtime of all fetched records is the same, increase the LIMIT and retry.
- ## Then we sort them in Perl by jitemid and takes just one.
- ##
- my $result_ref;
- foreach my $limit (2, 10, 50, 100) {
- $result_ref = $dbr->selectall_arrayref( "SELECT delayedid, $field FROM delayedlog2 use index (rlogtime,revptime) ".
- "WHERE journalid=? AND $field $cmp1 ? AND delayedid <> ? ".
- $secwhere. " ".
- "ORDER BY $field $order LIMIT $limit",
- undef, $jid, $stime, $delayedid
- );
-
- my %hash_times = ();
- map {$hash_times{$_->[1]} = 1} @$result_ref;
-
- # If we has one the only 'time' in $limit fetched rows,
- # may be $limit cuts off our record. Increase the limit and repeat.
- if (((scalar keys %hash_times) > 1) || (scalar @$result_ref) < $limit) {
- my @result;
-
- # Remove results with the same time but the jitemid is too high or low
- if ($after_before eq "after") {
- @result = grep { $_->[1] != $stime || $_->[0] > $delayedid } @$result_ref;
- } elsif ($after_before eq "before") {
- @result = grep { $_->[1] != $stime || $_->[0] < $delayedid } @$result_ref;
+ my $sql_item_rule = '';
+ if ($after_before eq "after") {
+ $sql_item_rule = $is_current_sticky ? "(revptime $cmp1 ? AND is_sticky = 1 )" :
+ "(revptime $cmp1 ? OR is_sticky = 1 )";
+ } else {
+ if ($is_current_sticky) {
+ my ($new_stime) = $dbr->selectrow_array("SELECT revptime " .
+ "FROM delayedlog2 WHERE journalid=? $sql_poster AND is_sticky = 0 ".
+ "ORDER BY revptime LIMIT 1", undef, $jid);
+ if ($new_stime < $stime) {
+ $stime = $new_stime;
}
-
- # Sort result by jitemid and get our id from a top.
- @result = sort $cmp3 @result;
-
- # Sort result by revttime
- @result = sort $cmp4 @result;
-
- my $id = $result[0]->[0];
- return 0 unless $id;
- return $id;
+
+ $sql_item_rule = "(revptime $cmp1 ? )";
+ } else {
+ $sql_item_rule = "(revptime $cmp1 ? AND is_sticky = 0 )";
}
+
}
- return 0;
+
+ my $result_ref = $dbr->selectcol_arrayref( "SELECT delayedid FROM delayedlog2 use index (rlogtime,revptime) ".
+ "WHERE journalid=? AND $sql_item_rule AND delayedid <> ? ".
+ $sql_poster. " ".
+ "ORDER BY is_sticky $order_sticky, revptime $order LIMIT 2",
+ undef, $jid, $stime, $delayedid);
+ return 0 unless $result_ref;
+ return $result_ref->[0];
}
sub handle_prefetched_props {
Modified: trunk/cgi-bin/LJ/Talk.pm
===================================================================
--- trunk/cgi-bin/LJ/Talk.pm 2011-11-15 11:12:11 UTC (rev 20539)
+++ trunk/cgi-bin/LJ/Talk.pm 2011-11-15 12:10:16 UTC (rev 20540)
@@ -128,11 +128,12 @@
$entry = LJ::Entry->new($u, ditemid => $itemid);
}
+ my $itemlnk = $entry->is_delayed ? "delayedid=" . $opts->{delayedid} :
+ "itemid=$itemid";
+
# << Previous
- if (!$entry->is_delayed) {
- push @linkele, $mlink->("$LJ::SITEROOT/go.bml?${jargent}itemid=$itemid&dir=prev", "prev_entry");
- $$headref .= "<link href='$LJ::SITEROOT/go.bml?${jargent}itemid=$itemid&dir=prev' rel='Previous' />\n";
- }
+ push @linkele, $mlink->("$LJ::SITEROOT/go.bml?${jargent}$itemlnk&dir=prev", "prev_entry");
+ $$headref .= "<link href='$LJ::SITEROOT/go.bml?${jargent}$itemlnk&dir=prev' rel='Previous' />\n";
# memories
unless ($LJ::DISABLED{'memories'} || $entry->is_delayed) {
@@ -181,11 +182,8 @@
}
## Next
- if (!$entry->is_delayed)
- {
- push @linkele, $mlink->("$LJ::SITEROOT/go.bml?${jargent}itemid=$itemid&dir=next", "next_entry");
- $$headref .= "<link href='$LJ::SITEROOT/go.bml?${jargent}itemid=$itemid&dir=next' rel='Next' />\n";
- }
+ push @linkele, $mlink->("$LJ::SITEROOT/go.bml?${jargent}$itemlnk&dir=next", "next_entry");
+ $$headref .= "<link href='$LJ::SITEROOT/go.bml?${jargent}$itemlnk&dir=next' rel='Next' />\n";
if (@linkele) {
$ret .= BML::fill_template("standout", {
Modified: trunk/htdocs/go.bml
===================================================================
--- trunk/htdocs/go.bml 2011-11-15 11:12:11 UTC (rev 20539)
+++ trunk/htdocs/go.bml 2011-11-15 12:10:16 UTC (rev 20540)
@@ -22,7 +22,8 @@
# prev/next talkread links
my $itemid = $GET{'itemid'}+0;
- if ($GET{'journal'} && $itemid)
+ my $delayedid = $GET{'delayedid'}+0;
+ if ($GET{'journal'} && ($itemid || $delayedid))
{
my $journal = $GET{'journal'};
my $u = LJ::load_user($journal);
@@ -36,19 +37,24 @@
$itemid = int($itemid / 256);
- my $jumpid = 0;
+ my $jumplink;
$title = $ML{'.error.noentrytitle'};
+
+ my $options = { 'itemid' => $itemid,
+ 'delayedid' => $delayedid,
+ 'use_sticky' => 1 };
if ($GET{'dir'} eq "next") {
- $jumpid = LJ::get_itemid_after2($u, $itemid);
+ warn "itemid = " . LJ::get_itemid_after2($u, $itemid);
+ $jumplink = LJ::get_after_item_link($u, $options);
$body = $ML{'.error.noentry.next'};
} elsif ($GET{'dir'} eq "prev") {
- $jumpid = LJ::get_itemid_before2($u, $itemid);
+ $jumplink = LJ::get_before_item_link($u, $options);
$body = $ML{'.error.noentry.prev'};
}
- if ($jumpid) {
- return BML::redirect(LJ::journal_base($u) . "/$jumpid.html");
+ if ($jumplink) {
+ return BML::redirect($jumplink);
}
}
