[livejournal] r19775: Updated: user interface (for sticky and ...
Committer: sbelyaev
Updated: user interface (for sticky and dalayed entries), added new tables for delayed entries,added delayed entries url support
U branches/delayed_entries/bin/upgrading/update-db-general.pl U branches/delayed_entries/cgi-bin/Apache/LiveJournal.pm U branches/delayed_entries/cgi-bin/LJ/Entry.pm U branches/delayed_entries/cgi-bin/LJ/User.pm U branches/delayed_entries/cgi-bin/LJ/Widget/EntryForm.pm U branches/delayed_entries/cgi-bin/ljlib.pl
Modified: branches/delayed_entries/bin/upgrading/update-db-general.pl
===================================================================
--- branches/delayed_entries/bin/upgrading/update-db-general.pl 2011-08-18 12:44:39 UTC (rev 19774)
+++ branches/delayed_entries/bin/upgrading/update-db-general.pl 2011-08-18 13:01:21 UTC (rev 19775)
@@ -998,6 +998,38 @@
)
EOC
+register_tablecreate("delayedlog2", <<'EOC'); # clustered
+CREATE TABLE delayedlog2 (
+ journalid INT UNSIGNED NOT NULL,
+ delayedid MEDIUMINT UNSIGNED NOT NULL,
+ PRIMARY KEY (journalid, delayedid),
+ posterid INT UNSIGNED NOT NULL,
+ subject CHAR(30),
+ logtime DATETIME,
+ posttime DATETIME,
+ security enum('public','private','usemask') NOT NULL default 'public',
+ allowmask int(10) unsigned NOT NULL default '0',
+ year smallint(6) NOT NULL default '0',
+ month tinyint(4) NOT NULL default '0',
+ day tinyint(4) NOT NULL default '0',
+ rlogtime int(10) unsigned NOT NULL default '0',
+ revptime int(10) unsigned NOT NULL default '0',
+ KEY (journalid, logtime, posttime, year, month, day),
+ KEY `rlogtime` (`journalid`,`rlogtime`),
+ KEY `revptime` (`journalid`,`revptime`)
+)
+EOC
+
+# delayed post Storable object (all props/options)
+register_tablecreate("delayedblob2", <<'EOC'); # clustered
+CREATE TABLE delayedblob2 (
+ journalid INT UNSIGNED NOT NULL,
+ delayedid INT UNSIGNED NOT NULL,
+ PRIMARY KEY (journalid, delayedid),
+ request_stor MEDIUMBLOB
+)
+EOC
+
register_tabledrop("ibill_codes");
register_tabledrop("paycredit");
register_tabledrop("payments");
Modified: branches/delayed_entries/cgi-bin/Apache/LiveJournal.pm
===================================================================
--- branches/delayed_entries/cgi-bin/Apache/LiveJournal.pm 2011-08-18 12:44:39 UTC (rev 19774)
+++ branches/delayed_entries/cgi-bin/Apache/LiveJournal.pm 2011-08-18 13:01:21 UTC (rev 19775)
@@ -788,8 +788,23 @@
$mode = "entry";
}
- }
- elsif ( $uuri =~ m|^/(\d\d\d\d)(?:/(\d\d)(?:/(\d\d))?)?(/?)$| ) {
+ } elsif ($uuri =~ m|^/d(\d+)\.html$|) {
+ my $u = LJ::load_user($user);
+
+ unless ($u) {
+ LJ::Request->pnotes ('error' => 'baduser');
+ LJ::Request->pnotes ('remote' => LJ::get_remote());
+ return LJ::Request::NOT_FOUND;
+ }
+
+ $ljentry = LJ::DelayedEntry->get_entry_by_id($u, $1);
+
+ if ( $GET{'mode'} eq "reply" || $GET{'replyto'} || $GET{'edit'} ) {
+ $mode = "reply";
+ } else {
+ $mode = "entry";
+ }
+ } elsif ( $uuri =~ m|^/(\d\d\d\d)(?:/(\d\d)(?:/(\d\d))?)?(/?)$| ) {
my ($year, $mon, $day, $slash) = ($1, $2, $3, $4);
unless ( $slash ) {
Modified: branches/delayed_entries/cgi-bin/LJ/Entry.pm
===================================================================
--- branches/delayed_entries/cgi-bin/LJ/Entry.pm 2011-08-18 12:44:39 UTC (rev 19774)
+++ branches/delayed_entries/cgi-bin/LJ/Entry.pm 2011-08-18 13:01:21 UTC (rev 19775)
@@ -157,6 +157,17 @@
return $entry;
}
+sub is_delayed {
+ my ($class) = @_;
+ return 0;
+}
+
+sub delayedid {
+ my ($class) = @_;
+ return 0;
+}
+
+
sub new_from_url {
my ($class, $url) = @_;
@@ -277,7 +288,7 @@
sub eventtime_mysql {
my $self = shift;
__PACKAGE__->preload_rows([ $self ]) unless $self->{_loaded_row};
- return $self->{eventtime};
+ return $self->{eventtime};
}
sub logtime_mysql {
@@ -1812,8 +1823,7 @@
sub get_log2_recent_log
{
- my ($u, $cid, $update, $notafter, $events_date, $exclude_sticky) = @_;
- $exclude_sticky = $exclude_sticky || 0; # optional
+ my ($u, $cid, $update, $notafter, $events_date) = @_;
my $jid = LJ::want_userid($u);
$cid ||= $u->{'clusterid'} if ref $u;
@@ -1944,15 +1954,6 @@
"AND rlogtime <= ($LJ::EndOfTime - UNIX_TIMESTAMP()) + $max_age"
);
- if ( $exclude_sticky ) {
- my $uobj = LJ::want_user($u);
- my $sticky = $uobj->get_sticky_entry();
-
- if ($sticky) {
- $sql .= " AND jitemid <> $sticky";
- }
- }
-
my $sth = $db->prepare($sql);
$sth->execute($jid);
my @row = ();
@@ -2000,8 +2001,7 @@
my $ret = [];
my $log = LJ::get_log2_recent_log($opts->{'userid'}, $opts->{'clusterid'},
- $opts->{'update'}, $opts->{'notafter'}, $opts->{events_date},
- $opts->{'exclude_sticky'});
+ $opts->{'update'}, $opts->{'notafter'}, $opts->{events_date},);
## UNUSED: my $left = $opts->{'itemshow'};
my $notafter = $opts->{'notafter'};
Modified: branches/delayed_entries/cgi-bin/LJ/User.pm
===================================================================
--- branches/delayed_entries/cgi-bin/LJ/User.pm 2011-08-18 12:44:39 UTC (rev 19774)
+++ branches/delayed_entries/cgi-bin/LJ/User.pm 2011-08-18 13:01:21 UTC (rev 19775)
@@ -6148,6 +6148,12 @@
return 0;
}
+# return sticky entries existing
+sub has_sticky_entry {
+ my ($self) = @_;
+ return !!$self->prop("sticky_entries");
+}
+
# returns sticky entry jitemid
sub get_sticky_entry {
my ($self) = @_;
@@ -7029,6 +7035,7 @@
# 'O' == pOrtal box id, 'V' == 'vgift', 'E' == ESN subscription id
# 'Q' == Notification Inbox, 'G' == 'SMS messaGe'
# 'D' == 'moDule embed contents', 'W' == 'Wish-list element'
+# 'Y' == delaYed entries
#
# FIXME: both phonepost and vgift are ljcom. need hooks. but then also
# need a separate namespace. perhaps a separate function/table?
@@ -7039,7 +7046,7 @@
##################################################################
# IF YOU UPDATE THIS MAKE SURE YOU ADD INITIALIZATION CODE BELOW #
- return undef unless $dom =~ /^[LTMPSRKCOVEQGDW]$/; #
+ return undef unless $dom =~ /^[LTMPSRKCOVEQGDWY]$/; #
##################################################################
my $dbh = LJ::get_db_writer();
@@ -7157,6 +7164,9 @@
} elsif ($dom eq "W") {
$newmax = $u->selectrow_array("SELECT MAX(wishid) FROM wishlist2 WHERE userid=?",
undef, $uid);
+ } elsif ($dom eq "Y") {
+ $newmax = $u->selectrow_array("SELECT MAX(delayedid) FROM delayedlog2 WHERE journalid=?",
+ undef, $uid);
} else {
die "No user counter initializer defined for area '$dom'.\n";
}
@@ -7768,6 +7778,14 @@
# so they store smaller in memcache
push @days, [ int($y), int($m), int($d), int($c) ];
}
+
+ $sth = LJ::DelayedEntry->get_daycount_query($u, $secwhere);
+ while (my ($y, $m, $d, $c) = $sth->fetchrow_array) {
+ # we force each number from string scalars (from DBI) to int scalars,
+ # so they store smaller in memcache
+ push @days, [ int($y), int($m), int($d), int($c) ];
+ }
+
LJ::MemCache::set($memkey, [time, @days]);
$release_lock->();
return \@days;
Modified: branches/delayed_entries/cgi-bin/LJ/Widget/EntryForm.pm
===================================================================
--- branches/delayed_entries/cgi-bin/LJ/Widget/EntryForm.pm 2011-08-18 12:44:39 UTC (rev 19774)
+++ branches/delayed_entries/cgi-bin/LJ/Widget/EntryForm.pm 2011-08-18 13:01:21 UTC (rev 19775)
@@ -480,17 +480,9 @@
$datetime .= "<noscript>" . LJ::html_hidden("date_diff_nojs", "1") .
"</noscript>";
- my $backdate_check = LJ::html_check({
- 'type' => "check",
- 'id' => "prop_opt_backdated",
- 'name' => "prop_opt_backdated",
- "value" => 1,
- 'selected' => $opts->{'prop_opt_backdated'},
- 'tabindex' => $self->tabindex
- });
+ my $timeZones = option($remote);
+ my $help_icon = LJ::help_icon("24hourshelp");
- my $backdate_help_icon = LJ::help_icon_html("backdate", "", "");
-
$out .= qq{
<p class='pkg'>
<label for='modifydate' class='left'>
@@ -502,15 +494,13 @@
</span>
<a href='javascript:void(0)' onclick='editdate();'
id='currentdate-edit'>$BML::ML{'entryform.date.edit'}</a>
+ $help_icon
</span>
<span id='modifydate'>$datetime
<?de $BML::ML{'entryform.date.24hournote'} de?>
+
<br />
- $backdate_check
- <label for='prop_opt_backdated' class='right'>
- $BML::ML{'entryform.backdated3'}
- </label>
- $backdate_help_icon
+ $timeZones
</span><!-- end #modifydate -->
</p>
<noscript>
@@ -520,19 +510,6 @@
</noscript>
};
- my $sticky = '';
- if ($opts->{jitemid}) {
- my $journalu = LJ::load_user($opts->{'usejournal'}) || $remote;
- my $sticky_entry = $journalu->get_sticky_entry();
- $sticky = 'checked' if ( $sticky_entry eq $opts->{jitemid});
- }
-
- $out .= qq{ <p id='sticky_checkbox'class='pkg'>
- <input type='checkbox' name='type' value='sticky' $sticky>
- $BML::ML{'entryform.sticky.edit'}
- </input>
- </p> };
-
$$onload .= " defaultDate();";
# User Picture
@@ -744,6 +721,36 @@
$out .= "<div id='options' class='pkg'>";
my %blocks = (
+ 'sticky' => sub {
+ my $is_checked = sub {
+ if ($opts->{jitemid}) {
+ my $journalu = LJ::load_user($opts->{'usejournal'}) || $remote;
+ my $sticky_entry = $journalu->get_sticky_entry();
+ if ( $sticky_entry eq $opts->{jitemid} ) {
+ return 'checked'
+ }
+ }
+
+ if ($opts->{delayed_sticky}) {
+ return 'checked'
+ }
+ };
+
+ my $sticky_check = LJ::html_check({
+ 'type' => "check",
+ 'class' => 'sticky_type',
+ 'value' => 'sticky',
+ 'name' => 'type',
+ 'id' => 'sticky_type',
+ 'selected' => $is_checked->(),
+ $opts->{'prop_opt_preformatted'} || $opts->{'event_format'},
+ 'label' => "",
+ });
+
+ return qq{$sticky_check <label for='prop_sticky' class='right options'>
+ $BML::ML{'entryform.sticky.edit'}
+ </label>};
+ },
'tags' => sub {
return if $LJ::DISABLED{'tags'};
@@ -1074,40 +1081,6 @@
},
'spellcheck' => sub {
my $out = '';
-
- # extra submit button so make sure it posts the form when
- # person presses enter key
- my %action_map = (
- 'edit' => 'save',
- 'update' => 'update',
- );
- if (my $action = $action_map{$opts->{'mode'}}) {
- $out .= qq{
- <input type='submit' name='action:$action'
- class='hidden_submit' />
- };
- }
- my $preview_tabindex = $self->tabindex;
- my $preview = qq{
- <input
- type="button"
- value="$BML::ML{'entryform.preview'}"
- onclick="entryPreview(this.form)"
- tabindex="$preview_tabindex"
- />
- };
- $preview =~ s/\s+/ /sg; # JS doesn't like newlines in string
- # literals
-
- unless ($opts->{'disabled_save'}) {
- $out .= $self->wrap_js(qq{
- if (document.getElementById) {
- setTimeout( function() {
- jQuery( '$preview' ).prependTo( '#entryform-spellcheck-wrapper' );
- }, 0 );
- }
- });
- }
if ($LJ::SPELLER && !$opts->{'disabled_save'}) {
$out .= LJ::html_submit(
'action:spellcheck',
@@ -1115,8 +1088,10 @@
{ 'tabindex' => $self->tabindex }
) . " ";
}
-
- return $out;
+
+ return qq{<label for='prop_sticky' class='right options'>
+ $BML::ML{'entryform.spellcheck'}
+ </label> $out};
},
);
@@ -1125,8 +1100,9 @@
[ 'mood', 'comment_settings' ],
[ 'location', 'comment_screening' ],
[ 'music', 'content_flag' ],
+ [ 'spellcheck', 'sticky' ],
'extra',
- [ 'lastfm_logo', 'spellcheck' ],
+ [ 'lastfm_logo' ],
);
unless ($opts->{'disabled_save'}) {
@@ -1278,7 +1254,44 @@
$out .= "<div id='security_container'>\n";
$out .= "<label for='security'>" . BML::ml('entryform.security2') . " </label>\n";
+
+ # preview button
+
+ # extra submit button so make sure it posts the form when
+ # person presses enter key
+ my %action_map = ( 'edit' => 'save',
+ 'update' => 'update', );
+
+ if (my $action = $action_map{$opts->{'mode'}}) {
+ $out .= qq{
+ <input type='submit' name='action:$action'
+ class='hidden_submit' />
+ };
+ }
+
+ my $preview_tabindex = $self->tabindex;
+ my $preview = qq{
+ <input
+ type="button"
+ value="$BML::ML{'entryform.preview'}"
+ onclick="entryPreview(this.form)"
+ tabindex="$preview_tabindex"
+ />
+ };
+ $preview =~ s/\s+/ /sg; # JS doesn't like newlines in string
+ # literals
+
+ unless ($opts->{'disabled_save'}) {
+ $out .= $self->wrap_js(qq{
+ if (document.getElementById) {
+ setTimeout( function() {
+ jQuery( '$preview' ).prependTo('#entryform-update-and-edit' );
+ }, 0 );
+ }
+ });
+ }
+
$out .= $self->render_security_container_block;
if ($opts->{'mode'} eq "update") {
my $onclick = "";
@@ -1297,6 +1310,7 @@
}
my $disabled = $remote && $remote->is_identity && !$self->usejournal;
+ $out .= qq{ <div id="entryform-update-and-edit"> };
$out .= LJ::html_submit(
'action:update',
@@ -1309,11 +1323,12 @@
'disabled' => $disabled,
}
) . " \n";
+ $out .= qq{</div>};
}
if ($opts->{'mode'} eq "edit") {
my $onclick = $LJ::IS_SSL ? '' : 'return true;';
-
+ $out .= qq{ <div id="entryform-update-and-edit"> };
$out .= LJ::html_submit(
'action:save',
BML::ml('entryform.save'),
@@ -1358,8 +1373,10 @@
}
) . "\n";
}
+ $out .= qq{</div>};
}
+
$out .= "</div><!-- end #security_container -->\n\n";
$out .= "</div><!-- end #submitbar -->\n\n";
@@ -1518,4 +1535,51 @@
return $out;
}
+# this one returns a $key => $value list, ordered by keys this way:
+# US goes first, then Canada, then all the rest
+sub timezone_options {
+ my $map = DateTime::TimeZone::links();
+
+ my ( @options, %options );
+
+ push @options, '' => BML::ml('setting.timezone.option.select');
+
+ foreach my $key ( sort keys %$map ) {
+ if ( $key =~ m!^US/! && $key ne 'US/Pacific-New' ) {
+ $options{ $map->{$key} } = $key;
+ push @options, $map->{$key} => $key;
+ }
+ }
+
+ foreach my $key ( sort keys %$map ) {
+ if ( $key =~ m!^Canada/! ) {
+ $options{ $map->{$key} } = $key;
+ push @options, $map->{$key} => $key;
+ }
+ }
+
+ foreach my $key ( DateTime::TimeZone::all_names() ) {
+ next if $options{$key};
+ push @options, $key => $key;
+ }
+
+ return @options;
+}
+
+sub option {
+ my ($u) = @_;
+
+ my $timezone = $u->prop("timezone");
+ my @options = timezone_options;
+
+ my $ret = LJ::html_select({
+ name => "delayed_timezone",
+ selected => $timezone,
+ }, @options);
+
+ $ret .= "<br />";
+
+ return $ret;
+}
+
1;
Modified: branches/delayed_entries/cgi-bin/ljlib.pl
===================================================================
--- branches/delayed_entries/cgi-bin/ljlib.pl 2011-08-18 12:44:39 UTC (rev 19774)
+++ branches/delayed_entries/cgi-bin/ljlib.pl 2011-08-18 13:01:21 UTC (rev 19775)
@@ -104,7 +104,7 @@
"logprop_history",
"comet_history", "pingrel",
"eventrates", "eventratescounters",
- "friending_actions_q",
+ "friending_actions_q", "delayedlog2", "delayedblob2",
);
# keep track of what db locks we have out
@@ -916,7 +916,6 @@
'dateformat' => $opts->{'dateformat'},
'update' => $LJ::EndOfTime - $fr->[1], # reverse back to normal
'events_date' => $events_date,
- 'exclude_sticky' => 1,
});
# stamp each with clusterid if from cluster, so ljviews and other
@@ -1097,7 +1096,7 @@
$remote = LJ::load_userid($remoteid);
}
- my $exclude_sticky = $opts->{exclude_sticky} || 0;
+ my $show_sticky_on_top = $opts->{show_sticky_on_top} || 0;
my $max_hints = $LJ::MAX_SCROLLBACK_LASTN; # temporary
my $sort_key = "revttime";
@@ -1139,18 +1138,18 @@
if ($skip < 0) { $skip = 0; }
if ($skip > $maxskip) { $skip = $maxskip; }
my $itemload = $itemshow + $skip;
-
- #
- # modificate 'usual elements to be shown'
- #
+ my $usual_show = $itemshow;
- # begin point
- $skip = ($skip - 1) if ( $sticky && $skip > 0);
- # elements count
- my $usual_show = $skip > 0 ? $itemshow : $itemshow - 1;
-
+ if ($show_sticky_on_top && $sticky && $skip > 0)
+ {
+ $skip -= 1;
+ } else {
+ $usual_show -= 1 if $sticky;
+ }
+
my $mask = 0;
- if ($remote && ($remote->{'journaltype'} eq "P" || $remote->{'journaltype'} eq "I") && $remoteid != $userid) {
+ if ($remote && ($remote->{'journaltype'} eq "P" ||
+ $remote->{'journaltype'} eq "I") && $remoteid != $userid) {
$mask = LJ::get_groupmask($userid, $remoteid);
}
@@ -1306,9 +1305,9 @@
WHERE journalid=$userid $sql_select $secwhere $jitemidwhere $securitywhere $posterwhere $after_sql $suspend_where
};
- if ($sticky) {
+ if ( $sticky && $show_sticky_on_top ) {
# build request to receive sticky entries
- if (!$skip && !$exclude_sticky) {
+ if (!$skip) {
$sticky_sql = "$sql AND jitemid = $sticky ";
$sticky_sql .= "ORDER BY journalid, $sort_key ";
}
@@ -1319,7 +1318,7 @@
$sql .= qq{
ORDER BY journalid, $sort_key
- $sql_limit};
+ $sql_limit };
unless ($logdb) {
$$err = "nodb" if ref $err eq "SCALAR";
@@ -1356,7 +1355,7 @@
}
};
- $absorb_data->($sticky_sql) if ( $sticky && !$skip && !$exclude_sticky );
+ $absorb_data->($sticky_sql) if ( $sticky && !$skip && $show_sticky_on_top);
$absorb_data->($sql);
$flush->();
