Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Adding a spoiler tag #333

Closed
wants to merge 1 commit into from

6 participants

Thibaut Renaux lahwran dxgiovanni RainbowCrash Ross Allan Neil Williams
Thibaut Renaux

This is an implementation of the following feature request: http://www.reddit.com/r/ideasfortheadmins/comments/oqnxk/on_behalf_of_the_entire_book_and_tvshow_subreddit/

This adds a "spoiler" tag, which acts the same way as a NSFW tag: submissions can be marked as being spoilers, and get a new thumbnail and a stamp. A submission can be marked as both being a spoiler and being NSFW (NSFW taking precedence).

The spoiler setting can be changed on a per-community basis: if it's not enabled, submissions cannot be marked as spoilers (it is off by default). When enabled, users also have the ability, through a checkbox in the sidebar, to enable or disable the display of spoilered submissions (just like they can choose to hide NSFW submissions, except this works on a per-community basis).

lahwran

I would love to see this accepted.

dxgiovanni

Would LOVE to see this implemented. There are currently some per-community workarounds remapping the NSFW tag that can lead to very comical results.

RainbowCrash

Hoping to hear a status update on this from the admins. It would be seriously great to have this feature.

lahwran

I heard recently that it was already implemented once, but it was removed quickly because of negative feedback.

RainbowCrash

Wait, as in this pull request was implemented?

lahwran

no, something similar which added subcategories of NSFW tags, iirc including spoiler

Ross Allan

I would also love to see this accepted.

Neil Williams
Owner

I'm going to close this as we'd rather implement a sitewide spoiler option via extending the link flair framework. Thanks for the pull request.

Neil Williams spladug closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 30, 2012
  1. Thibaut Renaux

    Added spoiler tag

    Tailszefox authored
This page is out of date. Refresh to see the latest.
35 r2/r2/controllers/api.py
View
@@ -716,6 +716,28 @@ def POST_unmarknsfw(self, thing):
# flag search indexer that something has changed
changed(thing)
+
+ @noresponse(VUser(),
+ VModhash(),
+ VSrCanAlter('id'),
+ thing = VByName('id'))
+ def POST_markspoiler(self, thing):
+ thing.spoiler = True
+ thing._commit()
+
+ # flag search indexer that something has changed
+ changed(thing)
+
+ @noresponse(VUser(),
+ VModhash(),
+ VSrCanAlter('id'),
+ thing = VByName('id'))
+ def POST_unmarkspoiler(self, thing):
+ thing.spoiler = False
+ thing._commit()
+
+ # flag search indexer that something has changed
+ changed(thing)
@noresponse(VUser(), VModhash(),
thing = VByName('id'))
@@ -1264,6 +1286,7 @@ def POST_upload_sr_img(self, file, header, sponsor, name, form_id, img_type):
over_18 = VBoolean('over_18'),
allow_top = VBoolean('allow_top'),
show_media = VBoolean('show_media'),
+ allow_spoilers = VBoolean('allow_spoilers'),
show_cname_sidebar = VBoolean('show_cname_sidebar'),
type = VOneOf('type', ('public', 'private', 'restricted', 'archived')),
link_type = VOneOf('link_type', ('any', 'link', 'self')),
@@ -1281,8 +1304,8 @@ def POST_site_admin(self, form, jquery, name, ip, sr,
redir = False
kw = dict((k, v) for k, v in kw.iteritems()
if k in ('name', 'title', 'domain', 'description', 'over_18',
- 'show_media', 'show_cname_sidebar', 'type', 'link_type', 'lang',
- "css_on_cname", "header_title",
+ 'show_media', 'allow_spoilers', 'show_cname_sidebar', 'type', 'link_type',
+ 'lang', "css_on_cname", "header_title",
'allow_top'))
#if a user is banned, return rate-limit errors
@@ -2064,6 +2087,14 @@ def POST_setflairenabled(self, form, jquery, flair_enabled):
setattr(c.user, 'flair_%s_enabled' % c.site._id, flair_enabled)
c.user._commit()
jquery.refresh()
+
+ @validatedForm(VUser(),
+ VModhash(),
+ spoilers_enabled = VBoolean("spoilers_enabled"))
+ def POST_setspoilersenabled(self, form, jquery, spoilers_enabled):
+ setattr(c.user, 'allow_spoilers_%d' % c.site._id, spoilers_enabled)
+ c.user._commit()
+ jquery.refresh()
@validatedForm(
VFlairManager(),
1  r2/r2/lib/js.py
View
@@ -243,6 +243,7 @@ def outputs(self):
"login.js",
"analytics.js",
"flair.js",
+ "spoilers.js",
"reddit.js",
"utils.js",
)
1  r2/r2/lib/jsontemplates.py
View
@@ -252,6 +252,7 @@ class LinkJsonTemplate(ThingJsonTemplate):
clicked = "clicked",
hidden = "hidden",
over_18 = "over_18",
+ spoiler = "spoiler",
likes = "likes",
domain = "domain",
title = "title",
19 r2/r2/lib/pages/pages.py
View
@@ -504,6 +504,11 @@ def __init__(self, site = None):
self.flair_prefs = FlairPrefs()
else:
self.flair_prefs = None
+
+ if c.user_is_loggedin and c.site.allow_spoilers:
+ self.spoilers_prefs = SpoilersPrefs()
+ else:
+ self.spoilers_prefs = None
CachedTemplate.__init__(self)
@@ -2629,6 +2634,20 @@ def __init__(self, user=None):
matching_template=matching_template,
wrapped_user=wrapped_user)
+class SpoilersPrefs(CachedTemplate):
+ def __init__(self):
+ sr_spoilers_enabled = getattr(c.site, 'allow_spoilers', False)
+ user_spoilers_enabled = getattr(c.user, 'allow_spoilers_%s' % c.site._id,
+ True)
+
+ wrapped_user = WrappedUser(c.user, subreddit=c.site,
+ force_show_flair=True,
+ include_flair_selector=True)
+ CachedTemplate.__init__(
+ self,
+ sr_spoilers_enabled=sr_spoilers_enabled,
+ user_spoilers_enabled=user_spoilers_enabled,
+ wrapped_user=wrapped_user)
class FriendList(UserList):
"""Friend list on /pref/friends"""
19 r2/r2/lib/pages/things.py
View
@@ -34,7 +34,8 @@ class PrintableButtons(Styled):
def __init__(self, style, thing,
show_delete = False, show_report = True,
show_distinguish = False, show_marknsfw = False,
- show_unmarknsfw = False, show_indict = False, is_link=False, **kw):
+ show_unmarknsfw = False, show_markspoiler = False, show_unmarkspoiler = False,
+ show_indict = False, is_link=False, **kw):
show_ignore = (thing.show_reports or
(thing.reveal_trial_info and not thing.show_spam))
approval_checkmark = getattr(thing, "approval_checkmark", None)
@@ -56,6 +57,8 @@ def __init__(self, style, thing,
show_distinguish = show_distinguish,
show_marknsfw = show_marknsfw,
show_unmarknsfw = show_unmarknsfw,
+ show_markspoiler = show_markspoiler,
+ show_unmarkspoiler = show_unmarkspoiler,
**kw)
class BanButtons(PrintableButtons):
@@ -88,6 +91,18 @@ def __init__(self, thing, comments = True, delete = True, report = True):
show_unmarknsfw = True
else:
show_unmarknsfw = False
+
+ allow_spoilers = getattr(thing.subreddit, "allow_spoilers", False)
+
+ if (thing.can_ban or is_author) and not thing.spoiler and allow_spoilers:
+ show_markspoiler = True
+ else:
+ show_markspoiler = False
+
+ if (thing.can_ban or is_author) and thing.spoiler and allow_spoilers:
+ show_unmarkspoiler = True
+ else:
+ show_unmarkspoiler = False
# do we show the delete button?
show_delete = is_author and delete and not thing._deleted
@@ -128,6 +143,8 @@ def __init__(self, thing, comments = True, delete = True, report = True):
show_distinguish = show_distinguish,
show_marknsfw = show_marknsfw,
show_unmarknsfw = show_unmarknsfw,
+ show_markspoiler = show_markspoiler,
+ show_unmarkspoiler = show_unmarkspoiler,
show_comments = comments,
# promotion
promoted = thing.promoted,
5 r2/r2/lib/wrapped.pyx
View
@@ -460,11 +460,14 @@ class CachedTemplate(Templated):
getattr(c.user, "gold", False),
template_hash]
- # if viewing a single subreddit, take flair settings into account.
+ # if viewing a single subreddit, take flair and spoilers settings into account.
if c.user and hasattr(c.site, '_id'):
keys.extend([
c.site.flair_enabled, c.site.flair_position,
c.user.flair_enabled_in_sr(c.site._id),
+ c.user.pref_show_flair,
+ c.site.allow_spoilers,
+ c.user.spoilers_enabled_in_sr(c.site._id),
c.user.pref_show_flair])
keys = [make_cachable(x, *a) for x in keys]
3  r2/r2/models/account.py
View
@@ -543,6 +543,9 @@ def system_user(cls):
def flair_enabled_in_sr(self, sr_id):
return getattr(self, 'flair_%d_enabled' % sr_id, True)
+
+ def spoilers_enabled_in_sr(self, sr_id):
+ return getattr(self, 'allow_spoilers_%d' % sr_id, True)
class FakeAccount(Account):
_nodb = True
19 r2/r2/models/link.py
View
@@ -51,6 +51,7 @@ class Link(Thing, Printable):
_defaults = dict(is_self = False,
over_18 = False,
nsfw_str = False,
+ spoiler = False,
reported = 0, num_comments = 0,
moderator_banned = False,
banned_before_moderator = False,
@@ -226,6 +227,14 @@ def keep_item(self, wrapped):
if is_nsfw or is_from_nsfw_sr:
return False
+ # hide spoilered links if the user doesn't want to see them
+ if(c.user_is_loggedin):
+ is_spoiler = bool(wrapped.spoiler)
+ show_spoilers = getattr(user, 'allow_spoilers_%d' % wrapped.subreddit._id, True)
+
+ if(is_spoiler and not show_spoilers):
+ return False
+
return True
# none of these things will change over a link's lifetime
@@ -358,9 +367,11 @@ def add_props(cls, user, wrapped):
item.over_18 = bool(item.over_18 or item.subreddit.over_18 or
item.nsfw_str)
item.nsfw = item.over_18 and user.pref_label_nsfw
-
item.is_author = (user == item.author)
+ if item.spoiler and not getattr(item.subreddit, "allow_spoilers", False):
+ item.spoiler = False
+
item.thumbnail_sprited = False
# always show a promo author their own thumbnail
if item.promoted and (user_is_admin or item.is_author) and item.has_thumbnail:
@@ -371,6 +382,12 @@ def add_props(cls, user, wrapped):
item.thumbnail_sprited = True
else:
item.thumbnail = ""
+ elif item.spoiler:
+ if show_media:
+ item.thumbnail = "spoiler"
+ item.thumbnail_sprited = True
+ else:
+ item.thumbnail = ""
elif not show_media:
item.thumbnail = ""
elif item.has_thumbnail:
1  r2/r2/models/modaction.py
View
@@ -63,6 +63,7 @@ class ModAction(tdb_cassandra.UuidThing, Printable):
'type': _('type'),
'link_type': _('link type'),
'over_18': _('toggle viewers must be over 18'),
+ 'allow_spoilers': _('toggle allow spoiler posts'),
'allow_top': _('toggle allow in default set'),
'show_media': _('toggle show thumbnail images of content'),
'domain': _('domain'),
1  r2/r2/models/subreddit.py
View
@@ -66,6 +66,7 @@ class Subreddit(Thing, Printable):
css_on_cname = True,
domain = None,
over_18 = False,
+ allow_spoilers = False,
mod_actions = 0,
sponsorship_text = "this reddit is sponsored by",
sponsorship_url = None,
20 r2/r2/public/static/css/reddit.css
View
@@ -2740,6 +2740,21 @@ form input[type=radio] {margin: 2px .5em 0 0; }
border-radius: 3px;
}
+.entry .buttons li.spoiler-stamp {
+ font-size: x-small;
+}
+
+.spoiler-stamp acronym {
+ color: #336699;
+ font-size: x-small;
+ text-decoration: none;
+ padding: 0 2px;
+ border: 1px solid #5f99cf !important;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+}
+
.entry .buttons li.trial-stamp, .entry .buttons li.reported-stamp {
border: 1px solid black !important;
padding: 0 4px;
@@ -2813,6 +2828,11 @@ form input[type=radio] {margin: 2px .5em 0 0; }
background-image: url(../nsfw2.png); /* SPRITE */
}
+.thumbnail.spoiler {
+ height: 70px;
+ background-image: url(../spoiler2.png); /* SPRITE */
+}
+
.thumbnail.self {
height: 50px;
background-image: url(../self_default2.png); /* SPRITE */
8 r2/r2/public/static/js/spoilers.js
View
@@ -0,0 +1,8 @@
+$(function() {
+ // Event handlers for sidebar spoilers prefs.
+ $(".spoilerstoggle").submit(function() {
+ return post_form(this, 'setspoilersenabled');
+ });
+
+ $(".spoilerstoggle input").change(function() { $(this).parent().submit(); });
+});
BIN  r2/r2/public/static/spoiler2.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 r2/r2/templates/createsubreddit.html
View
@@ -163,6 +163,14 @@
${_("show thumbnail images of content")}
</label>
</li>
+ <li>
+ <input class="nomargin" type="checkbox"
+ name="allow_spoilers" id="allow_spoilers"
+ ${thing.site and thing.site.allow_spoilers and "checked='checked'" or ""}/>
+ <label for="allow spoilers">
+ ${_("allow posts to be tagged as spoilers")}
+ </label>
+ </li>
</ul>
</div>
</%utils:line_field>
9 r2/r2/templates/link.html
View
@@ -73,6 +73,13 @@
</acronym>
</li>
%endif
+ %if thing.spoiler:
+ <li class="rounded spoiler-stamp stamp">
+ <acronym title="${_('Spoiler content')}">
+ ${_("SPOILER")}
+ </acronym>
+ </li>
+ %endif
${self.buttons()}
${self.admintagline()}
</ul>
@@ -153,7 +160,7 @@
</%def>
<%def name="thing_css_class(what)" buffered="True">
-${parent.thing_css_class(what)} ${"over18" if thing.over_18 else ""}
+${parent.thing_css_class(what)} ${"over18" if thing.over_18 else ""} ${"spoiler" if thing.spoiler else ""}
</%def>
<%def name="subreddit()" buffered="True">
6 r2/r2/templates/printablebuttons.html
View
@@ -64,6 +64,12 @@
%if thing.show_unmarknsfw:
<li>${ynbutton(_("un-nsfw"), _("unmarked"), "unmarknsfw")}</li>
%endif
+ %if thing.show_markspoiler:
+ <li>${ynbutton(_("spoiler"), _("spoilered"), "markspoiler")}</li>
+ %endif
+ %if thing.show_unmarkspoiler:
+ <li>${ynbutton(_("un-spoiler"), _("unspoilered"), "unmarkspoiler")}</li>
+ %endif
</%def>
<%def name="distinguish_setter(name, value=None)">
33 r2/r2/templates/spoilersprefs.html
View
@@ -0,0 +1,33 @@
+## The contents of this file are subject to the Common Public Attribution
+## License Version 1.0. (the "License"); you may not use this file except in
+## compliance with the License. You may obtain a copy of the License at
+## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
+## License Version 1.1, but Sections 14 and 15 have been added to cover use of
+## software over a computer network and provide for limited attribution for the
+## Original Developer. In addition, Exhibit A has been modified to be consistent
+## with Exhibit B.
+##
+## Software distributed under the License is distributed on an "AS IS" basis,
+## WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+## the specific language governing rights and limitations under the License.
+##
+## The Original Code is Reddit.
+##
+## The Original Developer is the Initial Developer. The Initial Developer of
+## the Original Code is CondeNet, Inc.
+##
+## All portions of the code written by CondeNet are Copyright (c) 2006-2010
+## CondeNet, Inc. All Rights Reserved.
+################################################################################
+
+%if thing.sr_spoilers_enabled:
+ <form class="toggle spoilerstoggle">
+ <input id="spoilers_enabled" type="checkbox" name="spoilers_enabled"
+ %if thing.user_spoilers_enabled:
+ checked="checked"
+ %endif
+ >
+ ${_("Show spoilers on this reddit.")}
+ </form>
+%endif
+
4 r2/r2/templates/subredditinfobar.html
View
@@ -61,6 +61,10 @@ <h1 class="hover redditname">
%if thing.flair_prefs:
${thing.flair_prefs}
%endif
+
+ %if thing.spoilers_prefs:
+ ${thing.spoilers_prefs}
+ %endif
%if thing.sr.description:
${thing.sr.usertext}
Something went wrong with that request. Please try again.