diff --git a/r2/r2/controllers/api.py b/r2/r2/controllers/api.py index 33d07145f..14511d0e8 100644 --- a/r2/r2/controllers/api.py +++ b/r2/r2/controllers/api.py @@ -1227,15 +1227,21 @@ class ApiController(RedditController): tr._is_enabled = True - @validatedForm(links = VByName('links', thing_cls = Link, multiple = True)) - def POST_fetch_links(self, form, jquery, links): + @validatedForm(links = VByName('links', thing_cls = Link, multiple = True), + show = VByName('show', thing_cls = Link, multiple = False)) + def POST_fetch_links(self, form, jquery, links, show): b = IDBuilder([l._fullname for l in links], wrap = ListingController.builder_wrapper) l = OrganicListing(b) l.num_margin = 0 l.mid_margin = 0 + jquery.replace_things(l, stubs = True) + if show: + jquery('.organic-listing .link:visible').hide() + jquery('.organic-listing .id-%s' % show._fullname).show() + @noresponse(VUser(), ui_elem = VOneOf('id', ('organic',))) def POST_disable_ui(self, ui_elem): diff --git a/r2/r2/models/populatedb.py b/r2/r2/models/populatedb.py index ec0d2fa8a..c1c77982b 100644 --- a/r2/r2/models/populatedb.py +++ b/r2/r2/models/populatedb.py @@ -22,23 +22,27 @@ from r2.models import * from r2.lib import promote +import string import random def populate(sr_name = 'reddit.com', sr_title = "reddit.com: what's new online", num = 100): create_accounts(num) - a = Author._query(limit = 1) + a = list(Account._query(limit = 1))[0] + + try: + sr = Subreddit._new(name = sr_name, title = sr_title, + ip = '0.0.0.0', author_id = a._id) + sr._commit() + except SubredditExists: + pass - sr = Subreddit._new(name = sr_name, title = sr_title, - ip = '0.0.0.0', author_id = a._id) - sr._commit() create_links(num) def create_accounts(num): - chars = 'abcdefghijklmnopqrztuvwxyz' for i in range(num): - name_ext = ''.join([ random.choice(chars) + name_ext = ''.join([ random.choice(string.letters) for x in range(int(random.uniform(1, 10))) ]) name = 'test_' + name_ext diff --git a/r2/r2/public/static/js/jquery.reddit.js b/r2/r2/public/static/js/jquery.reddit.js index 1090a2356..7f0506a4f 100644 --- a/r2/r2/public/static/js/jquery.reddit.js +++ b/r2/r2/public/static/js/jquery.reddit.js @@ -248,6 +248,16 @@ $.things = function() { return $(sel); }; +$.fn.things = function() { + /* + * try to find all things that occur below a given selector, like: + * $('.organic-listing').things('t3_12345') + */ + var sel = $.map(arguments, function(x) { return ".thing.id-" + x; }) + .join(", "); + return this.find(sel); +}; + $.listing = function(name) { /* * Given an element name (a sitetable ID or a thing ID, with diff --git a/r2/r2/public/static/js/reddit.js b/r2/r2/public/static/js/reddit.js index c6c5a1f52..f926011b4 100644 --- a/r2/r2/public/static/js/reddit.js +++ b/r2/r2/public/static/js/reddit.js @@ -496,7 +496,8 @@ function updateEventHandlers(thing) { /* set the click cookie. */ add_thing_to_cookie(this, "click"); /* remember this as the last thing clicked */ - last_click(thing); + var wasorganic = $(this).parents('.organic-listing').length > 0; + last_click(thing, wasorganic); }); if (listing.filter(".organic-listing").length) { @@ -528,20 +529,80 @@ function updateEventHandlers(thing) { } }; -function last_click(thing) { - var cookie = "last_thing"; - if(thing) { - var data = {href: window.location.href, - what: $(thing).thing_id()}; - $.cookie_write({name: cookie, data: data}); - } - else { - var current = $.cookie_read(cookie).data; - if(current && current.href == window.location.href) { - $.cookie_write({name: cookie, data: ""}); - return current.what; +function last_click(thing, organic) { + /* called with zero arguments, marks the last-clicked item on this + page (to which the user probably clicked the 'back' button in + their browser). Otherwise sets the last-clicked item to the + arguments passed */ + var cookie = "last_thing"; + if(thing) { + var data = {href: window.location.href, + what: $(thing).thing_id(), + organic: organic}; + $.cookie_write({name: cookie, data: data}); + } else { + var current = $.cookie_read(cookie).data; + if(current && current.href == window.location.href) { + /* if they got there organically, make sure that it's in the + organic box */ + var olisting = $('.organic-listing'); + if(current.organic && olisting.length == 1) { + if(olisting.find('.thing:visible').thing_id() == current.what) { + /* if it's available in the organic box, *and* it's the one + that's already shown, do nothing */ + + } else { + var thing = olisting.things(current.what); + + if(thing.length > 0 && !thing.hasClass('stub')) { + /* if it's available in the organic box and not a stub, + switch index to it */ + olisting.find('.thing:visible').hide(); + thing.show(); + } else { + /* we're going to have to put it into the organic box + somehow */ + var thingelsewhere = $.things(current.what).filter(':not(.stub):first'); + + if(thingelsewhere.length > 0) { + /* if it's available on the page somewhere else, we can + clone it up into the organic box rather than go to + the server for it */ + + /* if there was a stub before, remove it */ + thing.remove(); + + var othercopy = thingelsewhere.clone(); + olisting.find('.thing:visible').before(othercopy).hide(); + othercopy.show(); + } else { + /* either it's available in the organic box, but the + data there is a stub, or it's not available at + all. either way, we need a server round-trip */ + thing.remove(); + + /* and add a new stub */ + + olisting.find('.thing:visible') + .before('