[gnome-software] Only allow the user to enter a review if it matches our style guide
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Only allow the user to enter a review if it matches our style guide
- Date: Tue, 9 Feb 2016 17:22:37 +0000 (UTC)
commit 1217511e5601a5b4fd9d2d33bf6f00b3411691c6
Author: Richard Hughes <richard hughsie com>
Date: Tue Feb 9 16:20:54 2016 +0000
Only allow the user to enter a review if it matches our style guide
We don't want one or two word reviews, we want thoughtful prose that's taken
time to write.
src/gs-review-dialog.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++
src/gs-review-dialog.ui | 3 ++
2 files changed, 92 insertions(+), 0 deletions(-)
---
diff --git a/src/gs-review-dialog.c b/src/gs-review-dialog.c
index a89dd1b..7712044 100644
--- a/src/gs-review-dialog.c
+++ b/src/gs-review-dialog.c
@@ -27,13 +27,21 @@
#include "gs-review-dialog.h"
#include "gs-star-widget.h"
+#define DESCRIPTION_LENGTH_MAX 3000 /* chars */
+#define DESCRIPTION_LENGTH_MIN 60 /* chars */
+#define SUMMARY_LENGTH_MAX 70 /* chars */
+#define SUMMARY_LENGTH_MIN 15 /* chars */
+#define WRITING_TIME_MIN 20 /* seconds */
+
struct _GsReviewDialog
{
GtkDialog parent_instance;
GtkWidget *star;
GtkWidget *summary_entry;
+ GtkWidget *post_button;
GtkWidget *text_view;
+ guint timer_id;
};
G_DEFINE_TYPE (GsReviewDialog, gs_review_dialog, GTK_TYPE_DIALOG)
@@ -69,22 +77,103 @@ gs_review_dialog_get_text (GsReviewDialog *dialog)
}
static void
+gs_review_dialog_changed_cb (GsReviewDialog *dialog)
+{
+ GtkTextBuffer *buffer;
+ gboolean all_okay = TRUE;
+ const gchar *msg = NULL;
+
+ /* require rating, summary and long review */
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->text_view));
+ if (dialog->timer_id != 0) {
+ /* display nothing */
+ all_okay = FALSE;
+ } else if (gs_star_widget_get_rating (GS_STAR_WIDGET (dialog->star)) == 0) {
+ /* TRANSLATORS: the review is not acceptable */
+ msg = _("Please choose a star rating");
+ all_okay = FALSE;
+ } else if (gtk_entry_get_text_length (GTK_ENTRY (dialog->summary_entry)) < SUMMARY_LENGTH_MIN) {
+ /* TRANSLATORS: the review is not acceptable */
+ msg = _("The summary is too short");
+ all_okay = FALSE;
+ } else if (gtk_entry_get_text_length (GTK_ENTRY (dialog->summary_entry)) > SUMMARY_LENGTH_MAX) {
+ /* TRANSLATORS: the review is not acceptable */
+ msg = _("The summary is too long");
+ all_okay = FALSE;
+ } else if (gtk_text_buffer_get_char_count (buffer) < DESCRIPTION_LENGTH_MIN) {
+ /* TRANSLATORS: the review is not acceptable */
+ msg = _("The description is too short");
+ all_okay = FALSE;
+ } else if (gtk_text_buffer_get_char_count (buffer) > DESCRIPTION_LENGTH_MAX) {
+ /* TRANSLATORS: the review is not acceptable */
+ msg = _("The description is too long");
+ all_okay = FALSE;
+ }
+
+ /* tell the user what's happening */
+ gtk_widget_set_tooltip_text (dialog->post_button, msg);
+
+ /* can the user submit this? */
+ gtk_widget_set_sensitive (dialog->post_button, all_okay);
+}
+
+static gboolean
+gs_review_dialog_timeout_cb (gpointer user_data)
+{
+ GsReviewDialog *dialog = GS_REVIEW_DIALOG (user_data);
+ dialog->timer_id = 0;
+ gs_review_dialog_changed_cb (dialog);
+ return FALSE;
+}
+
+static void
gs_review_dialog_init (GsReviewDialog *dialog)
{
+ GtkTextBuffer *buffer;
gtk_widget_init_template (GTK_WIDGET (dialog));
gs_star_widget_set_icon_size (GS_STAR_WIDGET (dialog->star), 32);
+
+ /* require the user to spend at least 30 seconds on writing a review */
+ dialog->timer_id = g_timeout_add_seconds (WRITING_TIME_MIN,
+ gs_review_dialog_timeout_cb,
+ dialog);
+
+ /* update UI */
+ g_signal_connect_swapped (dialog->star, "rating-changed",
+ G_CALLBACK (gs_review_dialog_changed_cb), dialog);
+ g_signal_connect_swapped (dialog->summary_entry, "notify::text",
+ G_CALLBACK (gs_review_dialog_changed_cb), dialog);
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->text_view));
+ g_signal_connect_swapped (buffer, "changed",
+ G_CALLBACK (gs_review_dialog_changed_cb), dialog);
+
+ gtk_widget_set_sensitive (dialog->post_button, FALSE);
+
+}
+
+static void
+gs_review_row_dispose (GObject *object)
+{
+ GsReviewDialog *dialog = GS_REVIEW_DIALOG (object);
+ if (dialog->timer_id > 0)
+ g_source_remove (dialog->timer_id);
+ G_OBJECT_CLASS (gs_review_dialog_parent_class)->dispose (object);
}
static void
gs_review_dialog_class_init (GsReviewDialogClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ object_class->dispose = gs_review_row_dispose;
+
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-review-dialog.ui");
gtk_widget_class_bind_template_child (widget_class, GsReviewDialog, star);
gtk_widget_class_bind_template_child (widget_class, GsReviewDialog, summary_entry);
gtk_widget_class_bind_template_child (widget_class, GsReviewDialog, text_view);
+ gtk_widget_class_bind_template_child (widget_class, GsReviewDialog, post_button);
}
GtkWidget *
diff --git a/src/gs-review-dialog.ui b/src/gs-review-dialog.ui
index aa4b109..a9c2e18 100644
--- a/src/gs-review-dialog.ui
+++ b/src/gs-review-dialog.ui
@@ -37,6 +37,9 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
+ <style>
+ <class name="suggested-action"/>
+ </style>
</object>
<packing>
<property name="pack-type">end</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]