Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Bug2152 prime #312

Closed
wants to merge 5 commits into from

4 participants

@louiseadennis
Collaborator

A rebased version of Bug2152. Ready for (as yet unmade) changes requested from code review.

@zorkian
Owner

Hiya; this still has a commit on it we aren't looking for.

I think this is because your develop branch is not up to date, so when you rebased on top of Dreamwidth's develop, it included the commit from 90d.

I would suggest:

$ git checkout develop
$ git pull --ff-only dreamwidth develop:develop
$ git push origin develop
$ git checkout Bug2152_prime
$ git rebase develop
$ git push origin Bug2152_prime

Then come back to this pull request and see if anything has changed? And of course, if anything errors out in those steps, please stop and let me/Afuna know what it says?

@louiseadennis
Collaborator

My local develop branch was up-to-date, but my branch on github was behind. I ran through the above sequence and all was fine (give or take a few Already-up-to-date message) until the final step where it failed with

dh-purplecat@newhack:~/dw$ git push origin Bug2152_prime
Password for 'https://annariel@github.com':
To https://annariel@github.com/annariel/dw-free.git
! [rejected] Bug2152_prime -> Bug2152_prime (non-fast-forward)
error: failed to push some refs to 'https://annariel@github.com/annariel/dw-free.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

@afuna
Collaborator

So in this case, your develop branch on github has an extra commit https://github.com/annariel/dw-free/commits/Bug2152_prime -- the second one there says that it was commited by purplecat

Normally if there are extra commits on the branch that you're pushing to, you want to first pull them in. But in this case, you want to get rid of them -- so do:

git push -f 

and that will force the github branch to be like your local branch.

@louiseadennis
Collaborator

Thank goodness, that finally seems to have worked. I'll start working on the code review now!

@afuna afuna commented on the diff
cgi-bin/DW/Setting/StickyEntry.pm
((14 lines not shown))
+ foreach my $i ( 1... $u->count_max_stickies ) {
+ my $url = "http://$username.dreamwidth.org/$stickies[$i - 1].html" if $stickies[$i - 1];
+ my $textentry = $errs ? $class->get_arg( $args, "stickyid${i}" ) : $url;
+
+ $ret .= "<label for='${key}stickyid${i}'>" . $class->ml( 'setting.stickyentryi.label' ) . " $i </label>";
+ $ret .= LJ::html_text({
+ name => "${key}stickyid${i}",
+ id => "${key}stickyid${i}",
+ class => "text",
+ value => "$textentry",
+ size => 50,
+ maxlength => 100,
@afuna Collaborator
afuna added a note

I think that works a lot better now! In addition, I'd like to suggest that, if there's no value, a "placeholder" attribute be put into place, as a hint to anyone putting in their first sticky entries (though hopefuly they'll just do it via the entry page!)

@louiseadennis Collaborator

I've added (Entry Number) in place of the ditemid in the first "blank" entry. Commit: louiseadennis@2f99b05

@afuna Collaborator
afuna added a note

Ah I just realized that I mentioned this before, but was likely unclear :)

Try putting a:

placeholder => "http://.../1234.html"

in the same place the name/id/value, etc got set

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
purplecat added some commits
purplecat Bug 2152 - Multiple stickies bugs.dwscoalition.org/show_bug.cgi?id=2152
Allowing multiple stickies to be set both in the post forms, via a sticky module and in the Display tab under Manage account.
Allows for different sticky allocations depending upon account type and attempts to handle switching between account types elegantly.
145cc3e
purplecat (Bug 2152) Made changes to User.pm following on from code review disc…
…ussion.

(github.com/dreamwidth/dw-free/pull/276/files#r3386924)
6c95934
purplecat (Bug 2152) Made changes to Entry.pm following on from code review dis…
…cussion.

This involved alterations to module-sticky.tt, most notably to change the value of "sticky_select" form elements
so that their results could be cast into an integer describing the desired position of the sticky (O indicating the
entry is not a sticky).  This made the use of the form element more intuitive in Entry.pm.  Previously sticky
position had to be determined by comparing the ditemid of an edited entry with that of sticky entries, not it
can be determined from the form variable.  Variables in Entry.pm were re-named accordingly where appropriate.
8145b48
purplecat (Bug 2152) Making changes to StickyEntry.pm requested during code rev…
…iew.

This includes a change to the way is_sticky in User.pm handles its inputs.

This commit also includes a bug fix to Entry.pm
d4bf53a
purplecat (Bug 2152) Final changes requested by code review.
This has involved considerable extension and reworking of the entry from interface
for the stickies to handle the various combinations of journals and posters that
are possible from that form.
2f99b05
@louiseadennis louiseadennis referenced this pull request
Closed

Bug2152 #276

@louiseadennis
Collaborator

This should be ready for a new code review now.

@zorkian zorkian added this to the Pull Requests milestone
@afuna afuna commented on the diff
views/entry/module-sticky.tt
((23 lines not shown))
+ id = "issticky"
+ checked = 1
+ value=1
+ );
+ ELSE;
+ form.checkbox( label = label_yes
+ name = "issticky"
+ id = "issticky"
+
+ value=1
+ );
+ END;
+ %]
+ </div>
+ <div id='sticky_positions'>
+ [%# first_unused_sticky = 0 if there are no free sticky options
@afuna Collaborator
afuna added a note

Hmmm, what if instead of a list of radioboxes which looks ilke so:

Sticky Position: () Sticky 1
                    Currently: 1618 (No Subject)
                 () Sticky 2

Use textboxes and emphasize the subject instead:

[ ] Make Sticky Entry
(expanded section)
[ 1 ] this entry
[ 2 ] (No Subject) - 1618
[ 3 ] Some entry with a subject

With the assumption / default being that we want to make this entry be the topmost sticky entry, and an option to reorder.

Actually, for simplicity's sake, how do you feel about just having:

[ ] Sticky to top of journal/community

And if that's checked, then expand to show a link to the accounts page to reorder, with some indication that this will become the topmost. That might balance the desire to keep the flow simple with the ability to have some flexibility.

With an assumption made that we want this entry to be the top most sticky entry

@afuna Collaborator
afuna added a note

Status message: Sticky #1 - reorder

Where reorder is a link?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/DW/Controller/Entry.pm
@@ -231,6 +237,7 @@ sub new_handler {
trust_datetime_value => $trust_datetime_value,
crosspost => \%crosspost,
+ sticky_pos => int( $sticky_pos ),
@afuna Collaborator
afuna added a note

Small detail: I'd prefer to have the conversion to int happen where we set the variable, because then that way we know that if we need to use $sticky_pos anywhere else in the future, that'll be consistent/safe.

I like that presence of the checking though -- just in case :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/DW/Controller/Entry.pm
@@ -328,10 +338,15 @@ sub _init {
}
}
-
- @journallist = ( $u, $u->posting_access_list )
- unless $usejournal;
-
+ unless ( $usejournal ) {
+ my @postables = $u->posting_access_list;
@afuna Collaborator
afuna added a note

Ahhh I see what you're doing here! For clarity, I'd suggest moving the my @postables line to above the for loop (or even just use that in the for loop directly); but logic looks good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/DW/Controller/Entry.pm
((7 lines not shown))
+ my $max_stickies = $journalu->count_max_stickies;
+ my $entry_is_sticky = 0;
+ for my $i ( 0... $max_stickies-1 ) {
+ my $sticky = $journalu->get_sticky_entry( $i );
+ if ( $sticky ) {
+ my $subject = $sticky->subject_html;
+ my $sticky_name = $subject ? $subject : "No Subject";
+ $checked = 1 if ( $i + 1 == $sticky_pos );
+ $entry_is_sticky = $checked if $checked;
+ push @stickylist, { name => $sticky_name, ditemid => $sticky->ditemid, position => $i + 1, issticky => 1, checked => $checked };
+ $checked = 0;
+ # If all allowed sticky positions are taken then the first unused sticky is 0
+ # i.e., there isn't one.
+ $first_unused_sticky = $i == $max_stickies - 1 ? 0 : $i + 2;
+ } else {
+ push @stickylist, { name => "", ditemid => 0, position => $i + 1, issticky => 0, checked => 0 }
@afuna Collaborator
afuna added a note

ponder I think that an empty sticky name ends up being confusing unless you understand that the sticky is meant to refer to this entry -- so maybe we can say current entry, or similar -- but see my comment on the frontend template below, this may be moot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/DW/Controller/Entry.pm
@@ -412,6 +449,10 @@ sub _init {
moodtheme => \%moodtheme,
moods => \@moodlist,
+ stickies => \@stickylist,
+ first_unused_sticky => $first_unused_sticky,
@afuna Collaborator
afuna added a note

Hrrrm. I think that $first_unused_sticky, it makes most sense to have us assume that they want this latest sticky to go on top, instead of in the first blank.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/DW/Controller/Entry.pm
@@ -1069,8 +1131,19 @@ sub _do_edit {
my $juser = $journal->user;
my $entry_url = $res->{url};
my $edit_url = "$LJ::SITEROOT/entry/$juser/$ditemid/edit";
+ my $u = $auth->{poster};
+ my $ju = $auth->{journal} || $auth->{poster};
@afuna Collaborator
afuna added a note

Created $u and $ju but never used?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/DW/Controller/Entry.pm
@@ -1069,8 +1131,19 @@ sub _do_edit {
my $juser = $journal->user;
my $entry_url = $res->{url};
my $edit_url = "$LJ::SITEROOT/entry/$juser/$ditemid/edit";
+ my $u = $auth->{poster};
+ my $ju = $auth->{journal} || $auth->{poster};
+ my $sticky_pos = $form_req->{props}->{sticky_select};
+
+ if ( $sticky_pos == 0 && $journal->is_sticky_entry( $ditemid ) ) {
@afuna Collaborator
afuna added a note

Ponder ponder. Okay this if statement is slightly convoluted. How about:

if ( $sticky_pos ) {
    $journal->make_sticky_entry(....)
} else {
    $journal->remove_sticky_entry($ditemid) if $journal->is_sticky_entry(...)
}

Which basically just reverses it and gets rid of one negative condition which is always a bit harder to parse.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/DW/Setting/StickyEntry.pm
((14 lines not shown))
+ foreach my $i ( 1... $u->count_max_stickies ) {
+ my $url = "";
+ if ( $stickies[$i - 1] ) {
+ $url = "http://$username.dreamwidth.org/$stickies[$i - 1].html";
+ } else {
+ $url = "http://$username.dreamwidth.org/(Entry Number).html" if ( $i == 1 || $stickies [$i - 2] );
@afuna Collaborator
afuna added a note

Ooooh I like this... but I suggest that in this case, you use this as a placeholder HTML attribute, so that when someone clicks on the textbox, the example disappears without them having to select and delete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/DW/Setting/StickyEntry.pm
((43 lines not shown))
return $ret;
}
sub save {
my ( $class, $u, $args ) = @_;
- my $sticky = $class->get_arg( $args, "stickyid" ) || '';
- $sticky = LJ::text_trim( $sticky, 0, 100 );
- unless ( $u->sticky_entry ( $sticky ) ) {
- $class->errors( "stickyid" => $class->ml( 'setting.stickyentry.error.invalid' ) ) ;
+ my $max_sticky_count = $u->count_max_stickies;
+ my @stickies;
+ # Create a hash that we will use to check for duplicate entries.
+ my %unique = ();
+ my $username = $u->user;
+ my $defaulturl = "http://$username.dreamwidth.org/(Entry Number).html";
@afuna Collaborator
afuna added a note

We could probably set this variable earlier and use it in both instances Just in Case (future consistency)

(though actually looking below, we may not need it, because we're only using the defaulturl to ignore the form submission if they didn't change anything -- but having the sample as a placeholder instead of the actual form text, means we won't need to do this!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/DW/Setting/StickyEntry.pm
((43 lines not shown))
return $ret;
}
sub save {
my ( $class, $u, $args ) = @_;
- my $sticky = $class->get_arg( $args, "stickyid" ) || '';
- $sticky = LJ::text_trim( $sticky, 0, 100 );
- unless ( $u->sticky_entry ( $sticky ) ) {
- $class->errors( "stickyid" => $class->ml( 'setting.stickyentry.error.invalid' ) ) ;
+ my $max_sticky_count = $u->count_max_stickies;
+ my @stickies;
+ # Create a hash that we will use to check for duplicate entries.
+ my %unique = ();
+ my $username = $u->user;
+ my $defaulturl = "http://$username.dreamwidth.org/(Entry Number).html";
+ for ( my $i=1; $i<=$max_sticky_count; $i++ ) {
@afuna Collaborator
afuna added a note

FYI, we can also write this as:

for my $i ( 1..$max_sticky_count ) ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/DW/Setting/StickyEntry.pm
((53 lines not shown))
+ my $max_sticky_count = $u->count_max_stickies;
+ my @stickies;
+ # Create a hash that we will use to check for duplicate entries.
+ my %unique = ();
+ my $username = $u->user;
+ my $defaulturl = "http://$username.dreamwidth.org/(Entry Number).html";
+ for ( my $i=1; $i<=$max_sticky_count; $i++ ) {
+ my $stickyi = $class->get_arg( $args, "stickyid${i}" ) || '';
+ # Unless this is a blank form entry...
+ unless ( $stickyi eq '' || $stickyi eq $defaulturl ) {
+ $stickyi = LJ::text_trim( $stickyi, 0, 100 );
+ my $ditemid = $u->is_valid_entry( $stickyi );
+ # is_valid_entry will return the correct itemid if a URL has been given. It will be
+ # undefined if the text box entry has a problem.
+ if ( $ditemid ) {
+ if ( exists $unique{ $ditemid } ) {
@afuna Collaborator
afuna added a note

style nitpick: don't need the spaces in $unique{$ditemid}

(Also, we don't need the "exists", since we can go with the truth/false value of $unique{$ditemid})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/DW/Setting/StickyEntry.pm
((54 lines not shown))
+ my @stickies;
+ # Create a hash that we will use to check for duplicate entries.
+ my %unique = ();
+ my $username = $u->user;
+ my $defaulturl = "http://$username.dreamwidth.org/(Entry Number).html";
+ for ( my $i=1; $i<=$max_sticky_count; $i++ ) {
+ my $stickyi = $class->get_arg( $args, "stickyid${i}" ) || '';
+ # Unless this is a blank form entry...
+ unless ( $stickyi eq '' || $stickyi eq $defaulturl ) {
+ $stickyi = LJ::text_trim( $stickyi, 0, 100 );
+ my $ditemid = $u->is_valid_entry( $stickyi );
+ # is_valid_entry will return the correct itemid if a URL has been given. It will be
+ # undefined if the text box entry has a problem.
+ if ( $ditemid ) {
+ if ( exists $unique{ $ditemid } ) {
+ $class->errors( "stickyid" => ( $class->ml( 'setting.stickyentry.error.duplicate' ) . $i ) ) ;
@afuna Collaborator
afuna added a note

Hmmm. For translation strings with variables, it's better to pass the variable to the translation string, instead of appending to the end -- this helps in case we need to change the text of the string, and the variable is no longer right at the end. so the way to do this is:

$class->ml( 'setting.stickyentry.error.duplicate', { stickyid => $i } )

And then have your text string be:

setting.stickyentry.error.duplicate=etc etc [[stickyid]] etc etc etc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/DW/Setting/StickyEntry.pm
((61 lines not shown))
+ # Unless this is a blank form entry...
+ unless ( $stickyi eq '' || $stickyi eq $defaulturl ) {
+ $stickyi = LJ::text_trim( $stickyi, 0, 100 );
+ my $ditemid = $u->is_valid_entry( $stickyi );
+ # is_valid_entry will return the correct itemid if a URL has been given. It will be
+ # undefined if the text box entry has a problem.
+ if ( $ditemid ) {
+ if ( exists $unique{ $ditemid } ) {
+ $class->errors( "stickyid" => ( $class->ml( 'setting.stickyentry.error.duplicate' ) . $i ) ) ;
+ return 1;
+ }
+ push( @stickies, $ditemid );
+ $unique{ $ditemid } = 1;
+ } else {
+ # As soon as we detect a problem with a sticky we break out of the subroutine.
+ $class->errors( "stickyid" => ( $class->ml( 'setting.stickyentry.error.invalid2' ) . $i ) ) ;
@afuna Collaborator
afuna added a note

Yep. (to the comment. But also same translation string advice as above)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/DW/Setting/StickyEntry.pm
((80 lines not shown))
}
+
+ # We pass in a reference to the array - which will be a reference to an empty array if the user has
@afuna Collaborator
afuna added a note

Hrrrm I think this comment is unneeded, because we have a bunch of other methods which are getters/setters at the same time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/LJ/S2/RecentPage.pm
((11 lines not shown))
my $stickyentry;
- $stickyentry = $u->get_sticky_entry
- if $skip == 0 && ! $opts->{securityfilter} && ! $opts->{tagids};
- # only show if visible to user
- if ( $stickyentry && $stickyentry->visible_to( $remote, $get->{viewall} ) ) {
- # create S2 entry object and show first on page
- my $entry = Entry_from_entryobj( $u, $stickyentry, $opts );
- # sticky entry specific things
- my $sticky_icon = Image_std( 'sticky-entry' );
- $entry->{_type} = 'StickyEntry';
- $entry->{sticky_entry_icon} = $sticky_icon;
- # show on top of page
- push @{$p->{entries}}, $entry;
+ if ( $skip == 0 && ! $opts->{securityfilter} && ! $opts->{tagids} ) {
+ for ( my $i = 0; $i < $u->count_max_stickies; $i++ ) {
@afuna Collaborator
afuna added a note

Logic looks good!

(see previous comment on using a range in a for loop too)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/LJ/User.pm
((5 lines not shown))
+sub is_sticky_entry {
+ my ( $u, $ditemid ) = @_;
+
+ my @stickies = $u->sticky_entry;
+
+ for ( my $i = 1; $i<=$u->count_max_stickies; $i++ ) {
+ return $i if ( $ditemid == $stickies[$i-1] );
+ }
+ return 0;
+}
+
+# Checks if some input is a valid URL or ID for an entry in the users journal, returns
+# the entry itemid if it is valid.
+#
+# Created to support multiple stickies but can probably replace duplicate code
+# in several over places.
@afuna Collaborator
afuna added a note

I like this reduction of code duplication

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/LJ/User.pm
@@ -2641,6 +2682,22 @@ sub large_journal_icon {
return $wrap_img->( "user" );
}
+# Make a particular entry into a particular sticky.
+sub make_sticky_entry {
+ my ( $u, $ditemid, $sticky_id ) = @_;
+
+ return undef if $sticky_id > $u->count_max_stickies;
+
+ my $sticky_entries = $u->prop( 'sticky_entry' );
+ my @stickies = split( /,/, $sticky_entries );
+
+ $stickies[$sticky_id-1] = int( $ditemid );
+ my $sticky_entry = join( ',', @stickies );
+
+ $u->set_prop( sticky_entry => $sticky_entry );
@afuna Collaborator
afuna added a note

Hmmmm. Why not use $u->sticky_entry below?

@afuna Collaborator
afuna added a note

Oh! Does this replace existing stickies in an index completely instead of moving them aside? I think that makes sense in the account settings, but not so much for the update page.

How about having both a make_sticky_entry and prepend/push_sticky_entry for both use cases? A little bit extra work but..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/LJ/User.pm
@@ -2952,6 +3009,23 @@ sub remove_from_class {
return $u->modify_caps( [], [$bit] );
}
+# Remove a particular entry from the sticky list
+sub remove_sticky_entry {
+ my ( $u, $ditemid ) = @_;
+
+ my $sticky_entries = $u->prop( 'sticky_entry' );
+ my @stickies = split( /,/, $sticky_entries );
+
+ my @new_stickies;
+
+ @new_stickies = grep { !/$ditemid/ } @stickies;
@afuna Collaborator
afuna added a note

Hmmm. Almost, but we'll want the comparison to be more exact (what if they have both a "234" and "123456" in their list of stickies?

We can use a direct comparison here: grep { $_ != $ditemid }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/LJ/User.pm
@@ -3172,40 +3246,83 @@ sub thread_expand_all {
}
#get/set Sticky Entry parent ID for settings menu
+# Expects an array of entries as input
+# Returns an array of entries
+# NB. This assumes that the inputs have already been validated as actual journal entries otherwise bad things
+# will happen.
sub sticky_entry {
@afuna Collaborator
afuna added a note

Maybe we should call this sticky_entries!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/LJ/User.pm
((8 lines not shown))
sub sticky_entry {
- my ( $u, $input ) = @_;
+ my ( $u, $input_ref ) = @_;
+
+
+ # The user may have previously had an account type that allowed more stickes.
+ # we want to preserve a record of these additional stickes in case they once
+ # more upgrade their account. This means we must first extract these
+ # if they exist.
+ my $sticky_entries = $u->prop( 'sticky_entry' );
@afuna Collaborator
afuna added a note

I like the thought put into this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/LJ/User.pm
((29 lines not shown))
- if ( defined $input ) {
- unless ( $input ) {
+ unless ( $input[0] ) {
@afuna Collaborator
afuna added a note

Hmm maybe check the length instead of item0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/LJ/User.pm
((45 lines not shown))
- # Validate the entry
- my $item = LJ::Entry->new( $u, ditemid => $ditemid );
- return 0 unless $item && $item->valid;
+ # sanity check the elements of the input array of candidate stickies.
+ my $new_sticky_count = 0;
+ foreach my $stickyid ( @input ) {
+ $new_sticky_count++;
+ return undef unless ( defined $u->is_valid_entry( $stickyid ) );
@afuna Collaborator
afuna added a note

I think defined is not necessary here (unless there's a specific reason for it to be!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/LJ/User.pm
@@ -3172,40 +3246,83 @@ sub thread_expand_all {
}
#get/set Sticky Entry parent ID for settings menu
+# Expects an array of entries as input
+# Returns an array of entries
@afuna Collaborator
afuna added a note

Hrrrrm. The comment says that it returns an array of entries, but sometimes we return 1 (if it was used as a setter).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/LJ/User.pm
((88 lines not shown))
sub get_sticky_entry {
- my $u = shift;
+ my ( $u, $i ) = @_;
+
+ return undef unless ( defined $i );
@afuna Collaborator
afuna added a note

style nitpick: don't need the parentheses here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/LJ/User.pm
((85 lines not shown))
}
+# Get's ith sticky entry from list
@afuna Collaborator
afuna added a note

psst don't need apostrophe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/LJ/User.pm
((6 lines not shown))
+ my ( $u, $ditemid ) = @_;
+
+ my @stickies = $u->sticky_entry;
+
+ for ( my $i = 1; $i<=$u->count_max_stickies; $i++ ) {
+ return $i if ( $ditemid == $stickies[$i-1] );
+ }
+ return 0;
+}
+
+# Checks if some input is a valid URL or ID for an entry in the users journal, returns
+# the entry itemid if it is valid.
+#
+# Created to support multiple stickies but can probably replace duplicate code
+# in several over places.
+sub is_valid_entry {
@afuna Collaborator
afuna added a note

Oh! I just remembered, there is a LJ::Entry->new_from_url(...) method, which seems relevant here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
cgi-bin/LJ/User.pm
@@ -2614,6 +2618,43 @@ sub invalidate_directory_record {
undef, $u->id);
}
+# checks whether an entry id corresponds to that of a sticky entry which is under user's max_sticky_count. Returns the position of the sticky if it is one.
+sub is_sticky_entry {
@afuna Collaborator
afuna added a note

Hmmm since this returns a pos instead of a true/false, I suggest renaming it to sticky_entry_index, or something similar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
htdocs/js/jquery.postform.js
((6 lines not shown))
+ if ( !$( "#issticky" ).is(":checked") )
+ $( "#sticky_positions" ).hide();
+
+ $( "#post_entry" ).bind( "journalselect", function(e, journal ) {
+ var warning_class = "sticky_msg_warning";
+ var $warning = $( "#"+warning_class );
+ var $posting_as_other = $( "#post_as_other").is(":checked");
+
+ if ( journal.name && journal.isremote && !$posting_as_other) {
+ $( "#sticky_component" ).sticky( "toggle", "community", ! journal.iscomm || journal.has_admin);
+ if ( $( "#usejournal").is("select") && journal.iscomm && journal.has_admin ) {
+ // In this situation although the user has sticky privileges for the journal they have
+ // not been pre-loaded onto the page.
+ if ( $warning.length == 0) {
+ $( "#sticky_component" ).sticky( "toggle_sticky_checked_options", false );
+ var $p = $( "<p></p>", { "class": warning_class, "id": warning_class } ).text( "WARNING: Unable to determine sticky settings for this community from this page. Checking Make Sticky Entry will make this entry into the first sticky on the journal and replace that sticky if it is already set. If that is not the desired behaviour please edit from either Account Settings->Display or by posting to the community directly" );
@afuna Collaborator
afuna added a note

Hrrrm. I like the thought put into this edge case, but I think it would be easier if we just don't give them the option to do this, if we can't detect if they're admin or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna afuna commented on the diff
views/entry/module-sticky.tt.text
@@ -0,0 +1,9 @@
+;; -*- coding: utf-8 -*-
+.header=Sticky Entries
+
+.label=Sticky [[position]]
+.label.sticky_pos=Sticky Position:
+.label_yes=Make Sticky Entry
+.sticky_label=Currently: [[num]] ([[name]])
+.sticky_position_req=All possible stickies are used. Please select one to replace.
+.is_sticky_warning=Please note altering the position of an existing sticky may cause the positions of other stickies to change.
@afuna Collaborator
afuna added a note

Hmm but currently don't we just overwrite the other sticky at that position instead of changing the positions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@afuna
Collaborator

I'm sorry it took so long!

I think the logic is mostly good; I've suggested a couple refinements but I didn't have much to say about the saving/fetching part, etc.

Most of my comments were interface/workflow related -- my biggest concern is overwriting the sticky at the current index, for the update page (vs the account settings). I think that many of the things I said are related to this behavior, so figuring this out is the most important part, because once this is fixed most of the things I brought up become moot.

@zorkian
Owner

Hiya! I'm going to place this up for grabs, but if you have any interest in getting back to it, please let us know!

@louiseadennis louiseadennis was unassigned by zorkian
@louiseadennis
Collaborator

No problem. When I merged master into my development branch I bodged some of the conflict resolution and the resulting broken mess has been sitting on dream hack depressing me which means there's been no progress.

@afuna
Collaborator

Sorry to hear that @annariel! It's almost there so I'll just finish this up :)

@afuna afuna self-assigned this
@afuna afuna referenced this pull request from a commit in afuna/dw-free
@afuna afuna [#312] Allow multiple stickies
* Allows multiple stickies to be set both in the post forms via a sticky
  module, and in the Display tab under Manage Account

* Allows for different sticky allocations depending upon account type
  and attempts to handle switching between account types elegantly

Much thanks to @annariel for her initial work on this.
4abd8fa
@afuna afuna referenced this pull request from a commit in afuna/dw-free
@afuna afuna [#312] Allow multiple stickies
* Allows multiple stickies to be set both in the post forms via a sticky
  module, and in the Display tab under Manage Account

* Allows for different sticky allocations depending upon account type
  and attempts to handle switching between account types elegantly

Much thanks to @annariel for her initial work on this.
6ccf1f3
@afuna afuna referenced this pull request from a commit in afuna/dw-free
@afuna afuna [#312] Allow multiple stickies
* Allows multiple stickies to be set both in the post forms via a sticky
  module, and in the Display tab under Manage Account

* Allows for different sticky allocations depending upon account type
  and attempts to handle switching between account types elegantly

Much thanks to @annariel for her initial work on this.
799924d
@zorkian
Owner

Closing this, as it's been superseded by @afuna's last PR.

Thanks for writing on this @annariel! Yay! :D

@zorkian zorkian closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 2, 2013
  1. Bug 2152 - Multiple stickies bugs.dwscoalition.org/show_bug.cgi?id=2152

    purplecat authored
    Allowing multiple stickies to be set both in the post forms, via a sticky module and in the Display tab under Manage account.
    Allows for different sticky allocations depending upon account type and attempts to handle switching between account types elegantly.
  2. (Bug 2152) Made changes to User.pm following on from code review disc…

    purplecat authored
    …ussion.
    
    (github.com/dreamwidth/dw-free/pull/276/files#r3386924)
  3. (Bug 2152) Made changes to Entry.pm following on from code review dis…

    purplecat authored
    …cussion.
    
    This involved alterations to module-sticky.tt, most notably to change the value of "sticky_select" form elements
    so that their results could be cast into an integer describing the desired position of the sticky (O indicating the
    entry is not a sticky).  This made the use of the form element more intuitive in Entry.pm.  Previously sticky
    position had to be determined by comparing the ditemid of an edited entry with that of sticky entries, not it
    can be determined from the form variable.  Variables in Entry.pm were re-named accordingly where appropriate.
  4. (Bug 2152) Making changes to StickyEntry.pm requested during code rev…

    purplecat authored
    …iew.
    
    This includes a change to the way is_sticky in User.pm handles its inputs.
    
    This commit also includes a bug fix to Entry.pm
  5. (Bug 2152) Final changes requested by code review.

    purplecat authored
    This has involved considerable extension and reworking of the entry from interface
    for the stickies to handle the various combinations of journals and posters that
    are possible from that form.
This page is out of date. Refresh to see the latest.
View
2  bin/upgrading/deadphrases.dat
@@ -1192,6 +1192,8 @@ general setting.sms.option.advanced
general setting.sms.option.carrier
general setting.sms.option.carrier.selectone
general setting.sms.option.phone
+general setting.stickyentry.error.invalid
+general setting.stickyentry.label
general setting.stylealwaysmine.label
general setting.stylealwaysmine.option
general setting.xpost.option.footer.vars.comment_image.alttext
View
10 bin/upgrading/en.dat
@@ -2967,10 +2967,20 @@ setting.sitescheme.label=Site Skin
setting.sitescheme.label=Site Scheme
+setting.stickyentry.details.label=<i>Note: blank entries will be ignored.</i>
+
setting.stickyentry.error.invalid=Invalid Dreamwidth entry ID or URL entered.
+setting.stickyentry.error.invalid2=Invalid Dreamwidth entry ID or URL entered for Sticky.
+
+setting.stickyentry.error.duplicate=Duplicate ID or URL entered for Sticky
+
setting.stickyentry.label=ID or URL of entry to make sticky
+setting.stickyentry.label2=IDs or URLs of Sticky Entries
+
+setting.stickyentryi.label=Sticky
+
setting.stylemine.label=Comment Pages
setting.stylemine.option2=View comment pages in your own journal style
View
87 cgi-bin/DW/Controller/Entry.pm
@@ -41,7 +41,7 @@ my %form_to_props = (
my @modules = qw(
tags currents displaydate
access journal comments
- age_restriction icons crosspost
+ age_restriction icons crosspost sticky
);
@@ -223,6 +223,12 @@ sub new_handler {
my $get = $r->get_args;
$usejournal ||= $get->{usejournal};
+
+ # sticky_pos becomes 0 (i.e., not a sticky) if this isn't a repost or if the sticky box
+ # isn't checked.
+ my $is_sticky = $post->{is_sticky};
+ my $sticky_pos = $is_sticky ? $post->{sticky_select} : 0;
+
my $vars = _init( { usejournal => $usejournal,
altlogin => $get->{altlogin},
remote => $remote,
@@ -231,6 +237,7 @@ sub new_handler {
trust_datetime_value => $trust_datetime_value,
crosspost => \%crosspost,
+ sticky_pos => int( $sticky_pos ),
@afuna Collaborator
afuna added a note

Small detail: I'd prefer to have the conversion to int happen where we set the variable, because then that way we know that if we need to use $sticky_pos anywhere else in the future, that'll be consistent/safe.

I like that presence of the checking though -- just in case :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
}, @_ );
# now look for errors that we still want to recover from
@@ -287,11 +294,14 @@ sub _init {
my @moodlist;
my $moods = DW::Mood->get_moods;
+ my @stickylist;
+ my $sticky_pos = $form_opts->{sticky_pos};
+
# we check whether the user can actually post to this journal on form submission
# journal we explicitly say we want to post to
my $usejournal = LJ::load_user( $form_opts->{usejournal} );
my @journallist;
- push @journallist, $usejournal if LJ::isu( $usejournal );
+ push @journallist, { label => $usejournal->username, value => $usejournal, administrator => $u->can_manage( $usejournal ) ? 1 : 0 } if LJ::isu( $usejournal );
# the journal we are actually posting to (whether implicitly or overriden by usejournal)
my $journalu = LJ::isu( $usejournal ) ? $usejournal : $u;
@@ -328,10 +338,15 @@ sub _init {
}
}
-
- @journallist = ( $u, $u->posting_access_list )
- unless $usejournal;
-
+ unless ( $usejournal ) {
+ my @postables = $u->posting_access_list;
@afuna Collaborator
afuna added a note

Ahhh I see what you're doing here! For clarity, I'd suggest moving the my @postables line to above the for loop (or even just use that in the for loop directly); but logic looks good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ # add in the user's journal
+ push @journallist, { label => $u->user, value => "", administrator => "1" };
+ foreach my $postable ( @postables ) {
+ push @journallist, { label => $postable->user, value => $postable->user,
+ administrator => $u->can_manage( $postable ) ? "1" : "0" };
+ }
+ }
# crosspost
my @accounts = DW::External::Account->get_external_accounts( $u );
@@ -361,6 +376,28 @@ sub _init {
push @moodlist, { id => $_, name => $moods->{$_}->{name} }
foreach sort { $moods->{$a}->{name} cmp $moods->{$b}->{name} } keys %$moods;
+ my @stickies = $journalu->sticky_entry;
+ my $checked = 0;
+ my $first_unused_sticky = 1;
+ my $max_stickies = $journalu->count_max_stickies;
+ my $entry_is_sticky = 0;
+ for my $i ( 0... $max_stickies-1 ) {
+ my $sticky = $journalu->get_sticky_entry( $i );
+ if ( $sticky ) {
+ my $subject = $sticky->subject_html;
+ my $sticky_name = $subject ? $subject : "No Subject";
+ $checked = 1 if ( $i + 1 == $sticky_pos );
+ $entry_is_sticky = $checked if $checked;
+ push @stickylist, { name => $sticky_name, ditemid => $sticky->ditemid, position => $i + 1, issticky => 1, checked => $checked };
+ $checked = 0;
+ # If all allowed sticky positions are taken then the first unused sticky is 0
+ # i.e., there isn't one.
+ $first_unused_sticky = $i == $max_stickies - 1 ? 0 : $i + 2;
+ } else {
+ push @stickylist, { name => "", ditemid => 0, position => $i + 1, issticky => 0, checked => 0 }
@afuna Collaborator
afuna added a note

ponder I think that an empty sticky name ends up being confusing unless you understand that the sticky is meant to refer to this entry -- so maybe we can say current entry, or similar -- but see my comment on the frontend template below, this may be moot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+ }
+
my ( @security, @custom_groups );
if ( $journalu && $journalu->is_community ) {
@security = (
@@ -412,6 +449,10 @@ sub _init {
moodtheme => \%moodtheme,
moods => \@moodlist,
+ stickies => \@stickylist,
+ first_unused_sticky => $first_unused_sticky,
@afuna Collaborator
afuna added a note

Hrrrm. I think that $first_unused_sticky, it makes most sense to have us assume that they want this latest sticky to go on top, instead of in the first blank.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ is_sticky => $entry_is_sticky,
+
journallist => \@journallist,
usejournal => $usejournal,
post_as => $form_opts->{altlogin} ? "other" : "remote",
@@ -471,6 +512,7 @@ sub _edit {
my @warnings;
my $post;
my %spellcheck;
+ my $sticky_pos;
if ( $r->did_post ) {
$post = $r->post_args;
@@ -484,6 +526,9 @@ sub _edit {
my $mode_preview = $post->{"action:preview"} ? 1 :0;
my $mode_spellcheck = $post->{"action:spellcheck"} ? 1 : 0;
my $mode_delete = $post->{"action:delete"} ? 1 : 0;
+
+ my $is_sticky = $post->{is_sticky};
+ $sticky_pos = $is_sticky ? $post->{sticky_select} : 0;
push @error_list, LJ::Lang::ml( 'bml.badinput.body' )
unless LJ::text_in( $post );
@@ -570,6 +615,8 @@ sub _edit {
%crosspost = map { $_ => 1 } keys %{ $xposthash || {} };
}
+ $sticky_pos = $journal->is_sticky_entry( $ditemid ) unless $r->did_post;
+
my $vars = _init( { usejournal => $journal->username,
remote => $remote,
@@ -577,6 +624,7 @@ sub _edit {
trust_datetime_value => $trust_datetime_value,
crosspost => \%crosspost,
+ sticky_pos => int( $sticky_pos ),
}, @_ );
# now look for errors that we still want to recover from
@@ -713,6 +761,11 @@ sub _form_to_backend {
}
}
+ if ( $post->{issticky} ) {
+ $props->{sticky_select} = defined $post->{sticky_select} ? $post->{sticky_select} : 1;
+ } else {
+ $props->{sticky_select} = 0;
+ }
# nuke taglists that are just blank
$props->{taglist} = "" unless $props->{taglist} && $props->{taglist} =~ /\S/;
@@ -837,6 +890,9 @@ sub _backend_to_form {
}
}
+ my $user = $entry->poster;
+ my $sticky_pos = $user->is_sticky_entry( $entry->{ditemid} );
+
return {
subject => $entry->subject_raw,
event => $entry->event_raw,
@@ -844,6 +900,7 @@ sub _backend_to_form {
icon => $entry->userpic_kw,
security => $security,
custom_bit => \@custom_groups,
+ is_sticky => $sticky_pos,
%formprops,
%otherprops,
@@ -923,9 +980,11 @@ sub _save_new_entry {
sub _do_post {
my ( $form_req, $flags, $auth, %opts ) = @_;
+
my $res = _save_new_entry( $form_req, $flags, $auth );
return %$res if $res->{errors};
+
# post succeeded, time to do some housecleaning
_persist_props( $auth->{poster}, $form_req );
@@ -944,7 +1003,6 @@ sub _do_post {
poststatus => $ret,
}
);
-
} else {
# e.g., bad HTML in the entry
push @warnings, { type => "warning",
@@ -968,6 +1026,9 @@ sub _do_post {
my $ditemid = $res->{itemid} * 256 + $res->{anum};
my $itemlink = $res->{url};
my $edititemlink = "$LJ::SITEROOT/entry/$juser/$ditemid/edit";
+ my $sticky_select = $form_req->{props}->{sticky_select};
+
+ $ju->make_sticky_entry( $ditemid, $sticky_select ) if $sticky_select;
my @links = (
{ url => $itemlink,
@@ -1003,6 +1064,7 @@ sub _do_post {
ditemid => $ditemid,
);
+
$render_ret = DW::Template->render_template(
'entry/success.tt', {
poststatus => $ret, # did the update succeed or fail?
@@ -1069,8 +1131,19 @@ sub _do_edit {
my $juser = $journal->user;
my $entry_url = $res->{url};
my $edit_url = "$LJ::SITEROOT/entry/$juser/$ditemid/edit";
+ my $u = $auth->{poster};
+ my $ju = $auth->{journal} || $auth->{poster};
@afuna Collaborator
afuna added a note

Created $u and $ju but never used?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ my $sticky_pos = $form_req->{props}->{sticky_select};
+
+ if ( $sticky_pos == 0 && $journal->is_sticky_entry( $ditemid ) ) {
@afuna Collaborator
afuna added a note

Ponder ponder. Okay this if statement is slightly convoluted. How about:

if ( $sticky_pos ) {
    $journal->make_sticky_entry(....)
} else {
    $journal->remove_sticky_entry($ditemid) if $journal->is_sticky_entry(...)
}

Which basically just reverses it and gets rid of one negative condition which is always a bit harder to parse.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $journal->remove_sticky_entry( $ditemid );
+ } else {
+ $journal->make_sticky_entry( $ditemid, $sticky_pos ) if $sticky_pos;
+ }
if ( $deleted ) {
+ $journal->remove_sticky_entry( $ditemid ) if $sticky_pos;
+
$ret .= LJ::Lang::ml( '/editjournal.bml.success.delete' );
} else {
$ret .= LJ::Lang::ml( '/editjournal.bml.success.edited' );
View
73 cgi-bin/DW/Setting/StickyEntry.pm
@@ -21,7 +21,7 @@ sub should_render {
}
sub label {
- $_[0]->ml( 'setting.stickyentry.label' );
+ $_[0]->ml( 'setting.stickyentry.label2' );
}
sub option {
@@ -30,29 +30,76 @@ sub option {
my $key = $class->pkgkey;
my $ret;
- $ret .= LJ::html_text({
- name => "${key}stickyid",
- id => "${key}stickyid",
- class => "text",
- value => $errs ? $class->get_arg( $args, "stickyid" ) : $u->sticky_entry,
- size => 30,
- maxlength => 100,
- });
+ my @stickies = $u->sticky_entry;
+ my $username = $u->user;
+ foreach my $i ( 1... $u->count_max_stickies ) {
+ my $url = "";
+ if ( $stickies[$i - 1] ) {
+ $url = "http://$username.dreamwidth.org/$stickies[$i - 1].html";
+ } else {
+ $url = "http://$username.dreamwidth.org/(Entry Number).html" if ( $i == 1 || $stickies [$i - 2] );
@afuna Collaborator
afuna added a note

Ooooh I like this... but I suggest that in this case, you use this as a placeholder HTML attribute, so that when someone clicks on the textbox, the example disappears without them having to select and delete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+ my $textentry = $errs ? $class->get_arg( $args, "stickyid${i}" ) : $url;
+
+ $ret .= "<label for='${key}stickyid${i}'>" . $class->ml( 'setting.stickyentryi.label' ) . " $i </label>";
+ $ret .= LJ::html_text({
+ name => "${key}stickyid${i}",
+ id => "${key}stickyid${i}",
+ class => "text",
+ value => "$textentry",
+ size => 50,
+ maxlength => 100,
@afuna Collaborator
afuna added a note

I think that works a lot better now! In addition, I'd like to suggest that, if there's no value, a "placeholder" attribute be put into place, as a hint to anyone putting in their first sticky entries (though hopefuly they'll just do it via the entry page!)

@louiseadennis Collaborator

I've added (Entry Number) in place of the ditemid in the first "blank" entry. Commit: louiseadennis@2f99b05

@afuna Collaborator
afuna added a note

Ah I just realized that I mentioned this before, but was likely unclear :)

Try putting a:

placeholder => "http://.../1234.html"

in the same place the name/id/value, etc got set

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ });
+ $ret .= "<br />";
+
+ }
+
+ # returns an error if any of the stickies are incorrectly formatted.
my $errdiv = $class->errdiv( $errs, "stickyid" );
$ret .= "<br />$errdiv" if $errdiv;
+ $ret .= "<br />" . $class->ml( 'setting.stickyentry.details.label' );
+
return $ret;
}
sub save {
my ( $class, $u, $args ) = @_;
- my $sticky = $class->get_arg( $args, "stickyid" ) || '';
- $sticky = LJ::text_trim( $sticky, 0, 100 );
- unless ( $u->sticky_entry ( $sticky ) ) {
- $class->errors( "stickyid" => $class->ml( 'setting.stickyentry.error.invalid' ) ) ;
+ my $max_sticky_count = $u->count_max_stickies;
+ my @stickies;
+ # Create a hash that we will use to check for duplicate entries.
+ my %unique = ();
+ my $username = $u->user;
+ my $defaulturl = "http://$username.dreamwidth.org/(Entry Number).html";
@afuna Collaborator
afuna added a note

We could probably set this variable earlier and use it in both instances Just in Case (future consistency)

(though actually looking below, we may not need it, because we're only using the defaulturl to ignore the form submission if they didn't change anything -- but having the sample as a placeholder instead of the actual form text, means we won't need to do this!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ for ( my $i=1; $i<=$max_sticky_count; $i++ ) {
@afuna Collaborator
afuna added a note

FYI, we can also write this as:

for my $i ( 1..$max_sticky_count ) ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ my $stickyi = $class->get_arg( $args, "stickyid${i}" ) || '';
+ # Unless this is a blank form entry...
+ unless ( $stickyi eq '' || $stickyi eq $defaulturl ) {
+ $stickyi = LJ::text_trim( $stickyi, 0, 100 );
+ my $ditemid = $u->is_valid_entry( $stickyi );
+ # is_valid_entry will return the correct itemid if a URL has been given. It will be
+ # undefined if the text box entry has a problem.
+ if ( $ditemid ) {
+ if ( exists $unique{ $ditemid } ) {
@afuna Collaborator
afuna added a note

style nitpick: don't need the spaces in $unique{$ditemid}

(Also, we don't need the "exists", since we can go with the truth/false value of $unique{$ditemid})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $class->errors( "stickyid" => ( $class->ml( 'setting.stickyentry.error.duplicate' ) . $i ) ) ;
@afuna Collaborator
afuna added a note

Hmmm. For translation strings with variables, it's better to pass the variable to the translation string, instead of appending to the end -- this helps in case we need to change the text of the string, and the variable is no longer right at the end. so the way to do this is:

$class->ml( 'setting.stickyentry.error.duplicate', { stickyid => $i } )

And then have your text string be:

setting.stickyentry.error.duplicate=etc etc [[stickyid]] etc etc etc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ return 1;
+ }
+ push( @stickies, $ditemid );
+ $unique{ $ditemid } = 1;
+ } else {
+ # As soon as we detect a problem with a sticky we break out of the subroutine.
+ $class->errors( "stickyid" => ( $class->ml( 'setting.stickyentry.error.invalid2' ) . $i ) ) ;
@afuna Collaborator
afuna added a note

Yep. (to the comment. But also same translation string advice as above)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ return 1;
+ }
+ }
}
+
+ # We pass in a reference to the array - which will be a reference to an empty array if the user has
@afuna Collaborator
afuna added a note

Hrrrm I think this comment is unneeded, because we have a bunch of other methods which are getters/setters at the same time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ # blanked all their stickies. In User.pm sticky_entry is called without an argument just to
+ # get the list of current stickies, in that case the parameter will be undefined.
+ $u->sticky_entry ( \@stickies );
return 1;
}
View
38 cgi-bin/LJ/S2/RecentPage.pm
@@ -160,23 +160,29 @@ sub RecentPage
die $err if $err;
- # prepare sticky entry for S2 - only show sticky entry on first page of Recent Entries, not on skip= pages
- # or tag and security subfilters
+ # Prepare sticky entries for S2.
+ # Only show sticky entry on first page of Recent Entries.
+ # Do not show stickies unless they have the relevant permissions.
+ # Do not sticky posts on tagged view but display in place.
+ # On skip pages show sticky entries in place.
my $stickyentry;
- $stickyentry = $u->get_sticky_entry
- if $skip == 0 && ! $opts->{securityfilter} && ! $opts->{tagids};
- # only show if visible to user
- if ( $stickyentry && $stickyentry->visible_to( $remote, $get->{viewall} ) ) {
- # create S2 entry object and show first on page
- my $entry = Entry_from_entryobj( $u, $stickyentry, $opts );
- # sticky entry specific things
- my $sticky_icon = Image_std( 'sticky-entry' );
- $entry->{_type} = 'StickyEntry';
- $entry->{sticky_entry_icon} = $sticky_icon;
- # show on top of page
- push @{$p->{entries}}, $entry;
+ if ( $skip == 0 && ! $opts->{securityfilter} && ! $opts->{tagids} ) {
+ for ( my $i = 0; $i < $u->count_max_stickies; $i++ ) {
@afuna Collaborator
afuna added a note

Logic looks good!

(see previous comment on using a range in a for loop too)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ # only show if visible to user
+ $stickyentry = $u->get_sticky_entry( $i );
+ if ( $stickyentry && $stickyentry->visible_to( $remote, $get->{viewall} ) ) {
+ # create S2 entry object and show first on page
+ my $entry = Entry_from_entryobj( $u, $stickyentry, $opts );
+ # sticky entry specific things
+ my $sticky_icon = Image_std( 'sticky-entry' );
+ $entry->{_type} = 'StickyEntry';
+ $entry->{sticky_entry_icon} = $sticky_icon;
+ # show on top of page
+ push @{$p->{entries}}, $entry;
+ }
+ }
}
-
+
my $lastdate = "";
my $itemnum = 0;
my $lastentry = undef;
@@ -193,7 +199,7 @@ sub RecentPage
$itemnum++;
my $ditemid = $itemid * 256 + $anum;
- next if $itemnum > 0 && $stickyentry && $stickyentry->ditemid == $ditemid;
+ next if $itemnum > 0 && $stickyentry && $u->is_sticky_entry( $ditemid );
my $entry_obj = LJ::Entry->new( $u, ditemid => $ditemid );
View
162 cgi-bin/LJ/User.pm
@@ -2325,6 +2325,10 @@ sub count_max_mod_queue_per_poster {
return $_[0]->get_cap( 'mod_queue_per_poster' );
}
+sub count_max_stickies {
+ return $_[0]->get_cap( 'stickies' );
+}
+
sub count_max_subscriptions {
return $_[0]->get_cap( 'subscriptions' );
}
@@ -2614,6 +2618,43 @@ sub invalidate_directory_record {
undef, $u->id);
}
+# checks whether an entry id corresponds to that of a sticky entry which is under user's max_sticky_count. Returns the position of the sticky if it is one.
+sub is_sticky_entry {
@afuna Collaborator
afuna added a note

Hmmm since this returns a pos instead of a true/false, I suggest renaming it to sticky_entry_index, or something similar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ my ( $u, $ditemid ) = @_;
+
+ my @stickies = $u->sticky_entry;
+
+ for ( my $i = 1; $i<=$u->count_max_stickies; $i++ ) {
+ return $i if ( $ditemid == $stickies[$i-1] );
+ }
+ return 0;
+}
+
+# Checks if some input is a valid URL or ID for an entry in the users journal, returns
+# the entry itemid if it is valid.
+#
+# Created to support multiple stickies but can probably replace duplicate code
+# in several over places.
@afuna Collaborator
afuna added a note

I like this reduction of code duplication

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+sub is_valid_entry {
@afuna Collaborator
afuna added a note

Oh! I just remembered, there is a LJ::Entry->new_from_url(...) method, which seems relevant here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ my ( $u, $input ) = @_;
+
+ # Get the item ID number from the input.
+ my $ditemid;
+ if ( $input =~ m!/(\d+)\.html! ) {
+ $ditemid = $1;
+ } elsif ( $input =~ m!(\d+)! ) {
+ $ditemid = $1;
+ } else {
+ return undef;
+ }
+
+ # Validate the entry
+ my $item = LJ::Entry->new( $u, ditemid => $ditemid );
+ return undef unless $item && $item->valid;
+
+ return $ditemid;
+}
+
# <LJFUNC>
# name: LJ::User::large_journal_icon
@@ -2641,6 +2682,22 @@ sub large_journal_icon {
return $wrap_img->( "user" );
}
+# Make a particular entry into a particular sticky.
+sub make_sticky_entry {
+ my ( $u, $ditemid, $sticky_id ) = @_;
+
+ return undef if $sticky_id > $u->count_max_stickies;
+
+ my $sticky_entries = $u->prop( 'sticky_entry' );
+ my @stickies = split( /,/, $sticky_entries );
+
+ $stickies[$sticky_id-1] = int( $ditemid );
+ my $sticky_entry = join( ',', @stickies );
+
+ $u->set_prop( sticky_entry => $sticky_entry );
@afuna Collaborator
afuna added a note

Hmmmm. Why not use $u->sticky_entry below?

@afuna Collaborator
afuna added a note

Oh! Does this replace existing stickies in an index completely instead of moving them aside? I think that makes sense in the account settings, but not so much for the update page.

How about having both a make_sticky_entry and prepend/push_sticky_entry for both use cases? A little bit extra work but..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+ return 1;
+}
# des: Given a list of caps to add and caps to remove, updates a user's caps.
# args: cap_add, cap_del, res
@@ -2952,6 +3009,23 @@ sub remove_from_class {
return $u->modify_caps( [], [$bit] );
}
+# Remove a particular entry from the sticky list
+sub remove_sticky_entry {
+ my ( $u, $ditemid ) = @_;
+
+ my $sticky_entries = $u->prop( 'sticky_entry' );
+ my @stickies = split( /,/, $sticky_entries );
+
+ my @new_stickies;
+
+ @new_stickies = grep { !/$ditemid/ } @stickies;
@afuna Collaborator
afuna added a note

Hmmm. Almost, but we'll want the comparison to be more exact (what if they have both a "234" and "123456" in their list of stickies?

We can use a direct comparison here: grep { $_ != $ditemid }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+ my $sticky_entry = join( ',', @new_stickies );
+ $u->set_prop( sticky_entry => $sticky_entry );
+
+ return 1;
+}
+
# Sets/deletes userprop(s) by name for a user.
# This adds or deletes from the [dbtable[userprop]]/[dbtable[userproplite]]
@@ -3172,40 +3246,83 @@ sub thread_expand_all {
}
#get/set Sticky Entry parent ID for settings menu
+# Expects an array of entries as input
+# Returns an array of entries
@afuna Collaborator
afuna added a note

Hrrrrm. The comment says that it returns an array of entries, but sometimes we return 1 (if it was used as a setter).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+# NB. This assumes that the inputs have already been validated as actual journal entries otherwise bad things
+# will happen.
sub sticky_entry {
@afuna Collaborator
afuna added a note

Maybe we should call this sticky_entries!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
- my ( $u, $input ) = @_;
+ my ( $u, $input_ref ) = @_;
+
+
+ # The user may have previously had an account type that allowed more stickes.
+ # we want to preserve a record of these additional stickes in case they once
+ # more upgrade their account. This means we must first extract these
+ # if they exist.
+ my $sticky_entries = $u->prop( 'sticky_entry' );
@afuna Collaborator
afuna added a note

I like the thought put into this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ my @entries = split( /,/, $sticky_entries );
+
+ my $max_sticky_count = $u->count_max_stickies;
+ my $max_sticky_count_from_zero = $max_sticky_count - 1;
+ my $entry_length = @entries;
+
+ my @currently_unused_stickies = @entries[$max_sticky_count..$entry_length];
+
+ # Check we've been sent input and it isn't empty. If so we need to alter the sticky entries stored.
+ if ( defined $input_ref ) {
+ my @input = @$input_ref;
- if ( defined $input ) {
- unless ( $input ) {
+ unless ( $input[0] ) {
@afuna Collaborator
afuna added a note

Hmm maybe check the length instead of item0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
$u->set_prop( sticky_entry => '' );
return 1;
}
- #also takes URL
- my $ditemid;
- if ( $input =~ m!/(\d+)\.html! ) {
- $ditemid = $1;
- } elsif ( $input =~ m!(\d+)! ) {
- $ditemid = $1;
- } else {
- return 0;
- }
- # Validate the entry
- my $item = LJ::Entry->new( $u, ditemid => $ditemid );
- return 0 unless $item && $item->valid;
+ # sanity check the elements of the input array of candidate stickies.
+ my $new_sticky_count = 0;
+ foreach my $stickyid ( @input ) {
+ $new_sticky_count++;
+ return undef unless ( defined $u->is_valid_entry( $stickyid ) );
@afuna Collaborator
afuna added a note

I think defined is not necessary here (unless there's a specific reason for it to be!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
- $u->set_prop( sticky_entry => $ditemid );
+ # The user may have reused a sticky from before their account was downgraded. To keep
+ # stickies unique we should remove this from the list of unused stickies.
+ my @new_unused_stickies;
+ # We create a hash from the input for quick membership checking.
+ my %sticky_hash = map { $_ => 1 } @input;
+ foreach my $unused_sticky ( @currently_unused_stickies ) {
+ push @new_unused_stickies, $unused_sticky unless ( exists $sticky_hash{ $unused_sticky } )
+ }
+
+ # This shouldn't happen but, just in case, we check the number of new stickies and
+ # if we have more than we're allowed we trim the input array accordingly.
+ @input = @input[0..$max_sticky_count-1] unless ( $new_sticky_count < $max_sticky_count );
+
+ # We add the currently_unused_stickies onto the end of the new stickies
+ # NB. This has the side effect that, if the user hasn't allocated all their
+ # sticky quota but has previously used more than their quota that some of their
+ # old stickies will "shuffle up" to fill in the space. I think this is
+ # desirable behaviour, but it may surprise some users and should probably
+ # be documented somewhere.
+ my $sticky_entry = join( ',', ( @input, @new_unused_stickies ) );
+
+ $u->set_prop( sticky_entry => $sticky_entry );
return 1;
}
- return $u->prop( 'sticky_entry' );
+
+ my @current_entries = @entries[0..$max_sticky_count-1];
+ return @current_entries;
}
+# Get's ith sticky entry from list
@afuna Collaborator
afuna added a note

psst don't need apostrophe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
sub get_sticky_entry {
- my $u = shift;
+ my ( $u, $i ) = @_;
+
+ return undef unless ( defined $i );
@afuna Collaborator
afuna added a note

style nitpick: don't need the parentheses here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
- if ( my $ditemid = $u->sticky_entry ) {
- my $item = LJ::Entry->new( $u, ditemid => $ditemid );
- return $item if $item->valid;
+ if ( my @stickies = $u->sticky_entry ) {
+ if ( my $ditemid = $stickies[$i] ) {
+ my $item = LJ::Entry->new( $u, ditemid => $ditemid );
+ return $item if $item->valid;
+ }
}
return undef;
}
@@ -4896,7 +5013,7 @@ sub entryform_panels {
[ "access", "journal", "currents", "comments", "age_restriction" ],
# FIXME: should be [ "icons" "crosspost" "scheduled" ]
- [ "icons", "crosspost" ],
+ [ "icons", "crosspost", "sticky" ],
],
show => {
"tags" => 1,
@@ -4908,6 +5025,7 @@ sub entryform_panels {
"age_restriction" => 0,
"icons" => 1,
"crosspost" => 0,
+ "sticky" => 1,
#"scheduled" => 0,
#"status" => 1,
View
52 htdocs/js/jquery.postform.js
@@ -265,27 +265,29 @@ init: function(formData) {
function initJournalSelect() {
$("#usejournal").change(function() {
var $this = $(this);
- var journal, iscomm;
+ var journal, iscomm, has_admin;
if ( $this.is("select") ) {
var $option = $("option:selected", this);
journal = $option.text();
iscomm = $option.val() !== "";
+ has_admin = $option.data("administrator") == 1;
} else {
journal = $this.val();
iscomm = journal !== $("#poster_remote").val();
+ has_admin = $("#canmanage_usejournal").val() == 1;
}
- $(this).trigger( "journalselect", {"name":journal, "iscomm":iscomm, isremote: true});
+ $(this).trigger( "journalselect", {"name":journal, "iscomm":iscomm, isremote: true, "has_admin":has_admin});
});
$("#postas_usejournal, #post_username").change(function() {
- var journal, iscomm;
+ var journal, iscomm, has_admin;
var postas = $.trim($("#post_username").val());
journal = $.trim($("#postas_usejournal").val()) || postas;
iscomm = journal !== postas;
console.log(journal, postas)
- $(this).trigger( "journalselect", {"name":journal, "iscomm":iscomm, isremote: false});
+ $(this).trigger( "journalselect", {"name":journal, "iscomm":iscomm, isremote: false, "has_admin": false});
});
$("#post_as_other").click(function() {
- $("#post_entry").trigger( "journalselect", { name: undefined, iscomm: false, isremote: true } );
+ $("#post_entry").trigger( "journalselect", { name: undefined, iscomm: false, isremote: true, has_admin: false } );
})
$("#post_as_remote").click(function() {
$("#usejournal").triggerHandler("change");
@@ -389,6 +391,45 @@ init: function(formData) {
});
}
+ function initSticky() {
+ $( "#sticky_component" ).sticky();
+ if ( !$( "#issticky" ).is(":checked") )
+ $( "#sticky_positions" ).hide();
+
+ $( "#post_entry" ).bind( "journalselect", function(e, journal ) {
+ var warning_class = "sticky_msg_warning";
+ var $warning = $( "#"+warning_class );
+ var $posting_as_other = $( "#post_as_other").is(":checked");
+
+ if ( journal.name && journal.isremote && !$posting_as_other) {
+ $( "#sticky_component" ).sticky( "toggle", "community", ! journal.iscomm || journal.has_admin);
+ if ( $( "#usejournal").is("select") && journal.iscomm && journal.has_admin ) {
+ // In this situation although the user has sticky privileges for the journal they have
+ // not been pre-loaded onto the page.
+ if ( $warning.length == 0) {
+ $( "#sticky_component" ).sticky( "toggle_sticky_checked_options", false );
+ var $p = $( "<p></p>", { "class": warning_class, "id": warning_class } ).text( "WARNING: Unable to determine sticky settings for this community from this page. Checking Make Sticky Entry will make this entry into the first sticky on the journal and replace that sticky if it is already set. If that is not the desired behaviour please edit from either Account Settings->Display or by posting to the community directly" );
@afuna Collaborator
afuna added a note

Hrrrm. I like the thought put into this edge case, but I think it would be easier if we just don't give them the option to do this, if we can't detect if they're admin or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $p.insertBefore( "#sticky_options" );
+ }
+ } else {
+ $warning.remove();
+ if ( $( "#issticky" ).is(":checked") )
+ $( "#sticky_component" ).sticky( "toggle_sticky_checked_options", true );
+ }
+ } else if ( $posting_as_other ) {
+ $warning.remove();
+ $( "#sticky_component" ).sticky( "toggle", "unknown", false );
+ } else {
+ $warning.remove();
+ $( "#sticky_component" ).sticky( "toggle", "unknown", journal.has_admin );
+ }
+ });
+
+ $( "#issticky" ).click(function() {
+ $( "#sticky_component" ).sticky( "toggle_sticky_checked_options", $(this).is(":checked") );
+ });
+ }
+
function initPostButton() {
$("#submit_entry").data("label",$("#submit_entry").val());
$("#post_entry").bind("journalselect", function(e, journal) {
@@ -469,6 +510,7 @@ init: function(formData) {
initAccess();
initPostButton();
initCrosspost();
+ initSticky();
initToolbar();
$.getJSON("/__rpc_entryformcollapse", null, function(data) {
View
82 htdocs/js/jquery.sticky.js
@@ -0,0 +1,82 @@
+// Interface Control for the Sticky Entries Module on the Post and Edit pages
+//
+// Authors: Louise Dennis
+//
+// Copyright (c) 2013 by Dreamwidth Studios, LLC.
+//
+// This program is free software; you may redistribute it and/or modify it under
+// the same terms as Perl itself. For a copy of the license, please reference
+// 'perldoc perlartistic' or 'perldoc perlgpl'.
+
+(function($){
+
+var $sticky_checked;
+var $is_sticky;
+
+$.widget( "dw.sticky", {
+options: {
+ strings: {
+ stickyDisabled: {
+ community: "Only administrators can sticky entries in communities.",
+ unknown: "Can not determine sticky permissions for this user and journal.",
+ no_admin: "You do not have the persmission to create stickies on this journal.",
+ draft: "Draft entries cannot be stickied."
+ }
+ }
+},
+
+_create: function() {
+ $sticky_checked = $( "#issticky" ).is(":checked");
+ $is_sticky = $( "#issticky" ).is(":checked");
+},
+
+toggle_sticky_checked_options: function( sticky_val ) {
+ $sticky_checked = sticky_val;
+ // $warning has content if the journal sticky information is out of date with the
+ // journal selected for use.
+ var $warning = $( "#sticky_msg_warning" );
+
+ if ( $warning.length == 0 ) {
+ var $first_unused_sticky = $( "#first_unset_sticky" ).val();
+ if ( $first_unused_sticky > 0 && ! $is_sticky )
+ $( "#" + $first_unused_sticky + "_sticky_select" ).prop('checked', sticky_val);
+ if ( sticky_val )
+ $( "#sticky_positions" ).slideDown();
+ else
+ $( "#sticky_positions" ).hide();
+ }
+},
+
+// to display or not to display the sticky options
+toggle: function( why, allowThisSticky ) {
+ var self = this;
+
+ var msg_class = "sticky_msg";
+ var $msg = $( "#"+msg_class );
+
+ if ( allowThisSticky ) {
+ $msg.remove();
+ if ( $sticky_checked )
+ $( "#issticky" ).prop( 'checked', true );
+ $( "#sticky_options" ).slideDown();
+ } else if ( $msg.length == 0 && self.options.strings.stickyDisabled[why] ) {
+ var $p = $( "<p></p>", { "class": msg_class, "id": msg_class } ).text( self.options.strings.stickyDisabled[why] );
+ $p.insertBefore( "#sticky_options" );
+ $( "#sticky_options" ).hide();
+ if ( $sticky_checked )
+ $( "#issticky" ).prop( 'checked', false );
+ } else if ( self.options.strings.stickyDisabled[why] != $msg.text() ) {
+ $msg.remove();
+ var $p = $( "<p></p>", { "class": msg_class, "id": msg_class } ).text( self.options.strings.stickyDisabled[why] );
+ $p.insertBefore( "#sticky_options" );
+ $( "#sticky_options" ).hide();
+ if ( $sticky_checked )
+ $( "#issticky" ).prop( 'checked', false );
+ }
+
+}
+
+
+});
+
+})(jQuery);
View
15 htdocs/stc/postform.css
@@ -337,6 +337,21 @@ ul.icon-functions li {
margin-bottom:.3em;
}
+/* Stickies */
+
+#sticky_component .info {
+ margin-left: 1em;
+}
+
+#sticky_component dl {
+ margin-left: 35%;
+}
+
+#sticky_component legend {
+ float: left;
+ width: 35%;
+}
+
/* Publishing */
#post_as fieldset legend {
float: left;
View
1  views/entry/display/module-journal.tt
@@ -26,6 +26,7 @@ the same terms as Perl itself. For a copy of the license, please reference
[%- END -%]
[%# helper fields for JS #%]
[%- form.hidden( name = "usejournal", id = "usejournal", value = journalu.user ) -%]
+ [%- form.hidden( name = "canmanage_usejournal", id = "canmanage_usejournal", value=journallist.first.administrator ) -%]
[%- form.hidden( name = "poster_remote", id="poster_remote", value = remote.user ) %]
</ul>
View
3  views/entry/form.tt
@@ -53,6 +53,9 @@ the same terms as Perl itself. For a copy of the license, please reference
"js/md5.js"
"js/jquery.crosspost.js"
+ # stickies
+ "js/jquery.sticky.js"
+
# collapsing
"js/jquery.collapsible.js"
"stc/jquery.collapsible.css"
View
28 views/entry/module-journal.tt
@@ -52,26 +52,16 @@ the same terms as Perl itself. For a copy of the license, please reference
<div id="post_to" class="posting_settings">
<label for="usejournal">[%- ".label.post_to" | ml %]</label>
[%- IF journallist.size > 1 %]
- [%-
- journalselect = [];
- FOREACH journal IN journallist;
- IF journal.equals( remote );
- journalselect.push( "", journal.user );
- ELSE;
- journalselect.push( journal.user, journal.user );
- END;
- END
- -%]
-
- [% form.select(
- name = "usejournal"
- id = "usejournal"
-
- items = journalselect
- ) -%]
+ <select name="usejournal" class="select" id="usejournal">
+ [% FOREACH journal = journallist %]
+ <option value="[%- journal.value | html %]" data-administrator="[%- journal.administrator %]">
+ [%- journal.label | html %]</option>
+ [% END %]
+ </select>
[% ELSE %]
- [% journallist.first.ljuser_display%]</span>
- [% form.hidden( name = "usejournal", id = "usejournal", value = journallist.first.user ) %]
+ <span>[% journallist.first.value.ljuser_display%]</span>
+ [% form.hidden( name = "usejournal", id = "usejournal", value = journallist.first.label );
+ form.hidden( name = "canmanage_usejournal", id = "canmanage_usejournal", value = journallist.first.administrator ) %]
[% END %]
</div>
[% END %]
View
87 views/entry/module-sticky.tt
@@ -0,0 +1,87 @@
+[%# views/entry/module-sticky.tt
+
+Module for sticky / metadata in the entry form
+
+Authors: Louise Dennis
+
+Copyright (c) 2012 by Dreamwidth Studios, LLC.
+
+This program is free software; you may redistribute it and/or modify it under
+the same terms as Perl itself. For a copy of the license, please reference
+'perldoc perlartistic' or 'perldoc perlgpl'.
+-%]
+ <fieldset>
+ <h3 class='ui-corner-top'>[% ".header" | ml %]</h3>
+ <div class='inner'>
+
+ <div id='sticky_options'>
+ <div>
+ [% label_yes = ".label_yes" | ml %]
+ [% IF is_sticky;
+ form.checkbox( label = label_yes
+ name = "issticky"
+ id = "issticky"
+ checked = 1
+ value=1
+ );
+ ELSE;
+ form.checkbox( label = label_yes
+ name = "issticky"
+ id = "issticky"
+
+ value=1
+ );
+ END;
+ %]
+ </div>
+ <div id='sticky_positions'>
+ [%# first_unused_sticky = 0 if there are no free sticky options
@afuna Collaborator
afuna added a note

Hmmm, what if instead of a list of radioboxes which looks ilke so:

Sticky Position: () Sticky 1
                    Currently: 1618 (No Subject)
                 () Sticky 2

Use textboxes and emphasize the subject instead:

[ ] Make Sticky Entry
(expanded section)
[ 1 ] this entry
[ 2 ] (No Subject) - 1618
[ 3 ] Some entry with a subject

With the assumption / default being that we want to make this entry be the topmost sticky entry, and an option to reorder.

Actually, for simplicity's sake, how do you feel about just having:

[ ] Sticky to top of journal/community

And if that's checked, then expand to show a link to the accounts page to reorder, with some indication that this will become the topmost. That might balance the desire to keep the flow simple with the ability to have some flexibility.

With an assumption made that we want this entry to be the top most sticky entry

@afuna Collaborator
afuna added a note

Status message: Sticky #1 - reorder

Where reorder is a link?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ otherwise it shows the first. If it equals 1 we assume there
+ are no choices of sticky position (the entry will become the first
+ sticky so we don't bother to display the options) %]
+ [% show = 1; not_sticky = 1; IF first_unused_sticky != 1 %]
+ [% IF first_unused_sticky == 0 && ! is_sticky %]
+ <p>[% ".sticky_position_req" | ml %]</p>
+ [% END %]
+ [% IF is_sticky %]
+ <p>[% ".is_sticky_warning" | ml %]</p>
+ [% END %]
+ <legend><span>[% ".label.sticky_pos" | ml %]</span></legend>
+ <dl>
+ [% FOREACH sticky IN stickies %]
+ <dt>[%- IF show;
+ label = ".label" | ml ;
+ IF sticky.checked ;
+ form.radio( label = label _ sticky.position
+
+ name = "sticky_select"
+ id = sticky.position _ "_sticky_select"
+ checked = sticky.checked
+ value=sticky.position
+ );
+ not_sticky = 0;
+ ELSE;
+ form.radio( label = dw.ml( ".label", { position = sticky.position } )
+ name = "sticky_select"
+ id = sticky.position _ "_sticky_select"
+
+ value=sticky.position
+ );
+ END -%]
+ </dt>
+ [% IF sticky.issticky %]
+ <div class='info'>
+ <dd> [% ".sticky_label" | ml ( num = sticky.ditemid, name = sticky.name ) %]</dd>
+ </div>
+ [% ELSE;
+ show = 0;
+ END %]
+ [% END %]
+ [% END %]
+ </dl>
+ [% END %]
+ [% form.hidden( name="first_unset_sticky", id="first_unset_sticky", value=first_unused_sticky ); %]
+ </div>
+ </div>
+ </div>
+ </fieldset>
View
9 views/entry/module-sticky.tt.text
@@ -0,0 +1,9 @@
+;; -*- coding: utf-8 -*-
+.header=Sticky Entries
+
+.label=Sticky [[position]]
+.label.sticky_pos=Sticky Position:
+.label_yes=Make Sticky Entry
+.sticky_label=Currently: [[num]] ([[name]])
+.sticky_position_req=All possible stickies are used. Please select one to replace.
+.is_sticky_warning=Please note altering the position of an existing sticky may cause the positions of other stickies to change.
@afuna Collaborator
afuna added a note

Hmm but currently don't we just overwrite the other sticky at that position instead of changing the positions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.