Browse Source

Add warning/confirmation for reposting link topics

If a user tries to post a link topic that's been posted before, this
will add a warning below the form with info about the previous posts and
ask them to confirm that they want to re-post. Currently, this doesn't
have any sort of time/group/etc. restrictions and will just find
previous topics from all time.

The method for doing this is a big ugly to be able to handle both the
no-JS and with-JS posting methods, but it's not too bad.
merge-requests/74/head
Deimos 5 years ago
parent
commit
ff5465c4f8
  1. 6
      tildes/scss/modules/_toast.scss
  2. 1
      tildes/static/js/behaviors/autocomplete-input.js
  3. 79
      tildes/tildes/templates/includes/new_topic_form.jinja2
  4. 47
      tildes/tildes/templates/new_topic.jinja2
  5. 48
      tildes/tildes/views/topic.py

6
tildes/scss/modules/_toast.scss

@ -2,8 +2,14 @@
// SPDX-License-Identifier: AGPL-3.0-or-later // SPDX-License-Identifier: AGPL-3.0-or-later
.toast { .toast {
@extend %text-container;
margin: 1rem 0; margin: 1rem 0;
font-weight: bold; font-weight: bold;
ul {
margin-bottom: 1rem;
}
} }
.toast-minor { .toast-minor {

1
tildes/static/js/behaviors/autocomplete-input.js

@ -70,6 +70,7 @@ $.onmount("[data-js-autocomplete-input]", function() {
for (var i = 0; i < dataPieces.length; i++) { for (var i = 0; i < dataPieces.length; i++) {
if (dataPieces[i].indexOf("tags=") === 0) { if (dataPieces[i].indexOf("tags=") === 0) {
dataPieces[i] += $autocompleteInput.val(); dataPieces[i] += $autocompleteInput.val();
$autocompleteInput.val("");
break; break;
} }
} }

79
tildes/tildes/templates/includes/new_topic_form.jinja2

@ -0,0 +1,79 @@
{# Copyright (c) 2019 Tildes contributors <code@tildes.net> #}
{# SPDX-License-Identifier: AGPL-3.0-or-later #}
{% from "macros/datetime.jinja2" import adaptive_date_responsive %}
{% from 'macros/forms.jinja2' import markdown_textarea, topic_tagging %}
<form
id="new-topic"
method="post"
autocomplete="off"
action="/~{{ group.path }}/topics"
data-ic-post-to="/~{{ group.path }}/topics"
data-js-prevent-double-submit
data-js-confirm-leave-page-unsaved
>
<input type="hidden" name="csrf_token" value="{{ get_csrf_token() }}">
<div class="toast toast-minor">
<h2>Tildes prioritizes high-quality content and discussions</h2>
<p>Please post topics that are interesting, informative, or have the potential to start a good discussion.</p>
<p>Please <em>avoid</em> posting topics that are primarily for entertainment or that don't have discussion value.</p>
</div>
<div class="form-group">
<label class="form-label" for="title">Title</label>
<input class="form-input" id="title" name="title" type="text" placeholder="Title" required data-js-auto-focus
{% if title %}value="{{ title }}"{% endif %}
>
</div>
<fieldset>
<legend>Enter a link, text, or both:</legend>
<div class="form-group">
<label class="form-label" for="link">Link</label>
<input class="form-input" id="link" name="link" type="URL" placeholder="Link"
{% if link %}value="{{ link }}"{% endif %}
>
<p class="form-input-note">If you enter a link, your post will be a link topic (whether you also include text or not).</p>
</div>
<div class="form-group">
{{ markdown_textarea(text=markdown) }}
<p class="form-input-note">If you enter only text (and no link), your post will be a text topic.</p>
<p class="form-input-note">If you also enter a link, this text will be posted as the first comment and can be used to add more information or give your thoughts on the linked content. Adding text when posting a link is not required, but it can help get the discussion started.</p>
</p>
</div>
</fieldset>
{{ topic_tagging(autocomplete_options=group.common_topic_tags, value=tags) }}
<div class="form-buttons">
<button type="submit" class="btn btn-primary">Post topic</button>
{% if previous_topics %}
<div class="form-status form-status-error">Link has been posted before, see below</div>
{% endif %}
</div>
{% if previous_topics %}
<div class="toast toast-minor toast-warning">
<h2>This link has been posted previously:</h2>
<ul>
{% for previous_topic in previous_topics %}
<li>{{ adaptive_date_responsive(previous_topic.created_time) }} in ~{{ previous_topic.group }}: <a href="{{ previous_topic.permalink }}" target="_blank">{{ previous_topic.title }}</a></li>
{% endfor %}
</ul>
<p>If you want to post it again anyway, check the box below and click the "Post topic" button above again.</p>
<div class="form-group ml-2">
<label class="form-checkbox">
<input type="checkbox" id="confirm_repost" name="confirm_repost" value="true">
<i class="form-icon"></i> Re-post this link in ~{{ group }}
</label>
</div>
</div>
{% endif %}
</form>

47
tildes/tildes/templates/new_topic.jinja2

@ -3,8 +3,6 @@
{% extends 'base_no_sidebar.jinja2' %} {% extends 'base_no_sidebar.jinja2' %}
{% from 'macros/forms.jinja2' import markdown_textarea, topic_tagging %}
{% block title %}New topic{% endblock %} {% block title %}New topic{% endblock %}
{% block header_context_link %} {% block header_context_link %}
@ -14,48 +12,5 @@
{% block main_heading %}Post a new topic in ~{{ group.path }}{% endblock %} {% block main_heading %}Post a new topic in ~{{ group.path }}{% endblock %}
{% block content %} {% block content %}
<form
id="new-topic"
method="post"
autocomplete="off"
action="/~{{ group.path }}/topics"
data-ic-post-to="/~{{ group.path }}/topics"
data-js-prevent-double-submit
data-js-confirm-leave-page-unsaved
>
<input type="hidden" name="csrf_token" value="{{ get_csrf_token() }}">
<div class="toast toast-minor">
<h2>Tildes prioritizes high-quality content and discussions</h2>
<p>Please post topics that are interesting, informative, or have the potential to start a good discussion.</p>
<p>Please <em>avoid</em> posting topics that are primarily for entertainment or that don't have discussion value.</p>
</div>
<div class="form-group">
<label class="form-label" for="title">Title</label>
<input class="form-input" id="title" name="title" type="text" placeholder="Title" required data-js-auto-focus>
</div>
<fieldset>
<legend>Enter a link, text, or both:</legend>
<div class="form-group">
<label class="form-label" for="link">Link</label>
<input class="form-input" id="link" name="link" type="URL" placeholder="Link">
<p class="form-input-note">If you enter a link, your post will be a link topic (whether you also include text or not).</p>
</div>
<div class="form-group">
{{ markdown_textarea() }}
<p class="form-input-note">If you enter only text (and no link), your post will be a text topic.</p>
<p class="form-input-note">If you also enter a link, this text will be posted as the first comment and can be used to add more information or give your thoughts on the linked content. Adding text when posting a link is not required, but it can help get the discussion started.</p>
</p>
</div>
</fieldset>
{{ topic_tagging(autocomplete_options=group.common_topic_tags) }}
<div class="form-buttons">
<button type="submit" class="btn btn-primary">Post topic</button>
</div>
</form>
{% include "includes/new_topic_form.jinja2" %}
{% endblock %} {% endblock %}

48
tildes/tildes/views/topic.py

@ -4,12 +4,14 @@
"""Views related to posting/viewing topics and comments on them.""" """Views related to posting/viewing topics and comments on them."""
from collections import namedtuple from collections import namedtuple
from typing import Any, Optional
from typing import Any, Optional, Union
from marshmallow import missing, ValidationError from marshmallow import missing, ValidationError
from marshmallow.fields import String
from marshmallow.fields import Boolean, String
from pyramid.httpexceptions import HTTPFound from pyramid.httpexceptions import HTTPFound
from pyramid.renderers import render_to_response
from pyramid.request import Request from pyramid.request import Request
from pyramid.response import Response
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy import cast from sqlalchemy import cast
from sqlalchemy.sql.expression import any_, desc from sqlalchemy.sql.expression import any_, desc
@ -43,14 +45,50 @@ DefaultSettings = namedtuple("DefaultSettings", ["order", "period"])
@view_config(route_name="group_topics", request_method="POST", permission="post_topic") @view_config(route_name="group_topics", request_method="POST", permission="post_topic")
@use_kwargs(TopicSchema(only=("title", "markdown", "link"))) @use_kwargs(TopicSchema(only=("title", "markdown", "link")))
@use_kwargs({"tags": String(missing="")})
@use_kwargs({"tags": String(missing=""), "confirm_repost": Boolean(missing=False)})
def post_group_topics( def post_group_topics(
request: Request, title: str, markdown: str, link: str, tags: str
) -> HTTPFound:
request: Request,
title: str,
markdown: str,
link: str,
tags: str,
confirm_repost: bool,
) -> Union[HTTPFound, Response]:
"""Post a new topic to a group.""" """Post a new topic to a group."""
# pylint: disable=too-many-arguments
group = request.context group = request.context
if link: if link:
# check to see if this link has been posted before
previous_topics = (
request.db_session.query(Topic)
.filter(Topic.link == link)
.order_by(desc(Topic.created_time))
.limit(5)
.all()
)
if previous_topics and not confirm_repost:
# Render partial form for Intercooler.js request, whole page for normal POST
# (I don't like this much, there must be a better way to handle this)
if "X-IC-Request" in request.headers:
template = "tildes:templates/includes/new_topic_form.jinja2"
else:
template = "tildes:templates/new_topic.jinja2"
return render_to_response(
template,
{
"group": group,
"title": title,
"link": link,
"markdown": markdown,
"tags": tags,
"previous_topics": previous_topics,
},
request=request,
)
new_topic = Topic.create_link_topic( new_topic = Topic.create_link_topic(
group=group, author=request.user, title=title, link=link group=group, author=request.user, title=title, link=link
) )

Loading…
Cancel
Save