Przeglądaj źródła

Add commenting controls

Karl Hobley 4 lat temu
rodzic
commit
3174ffee08

+ 84 - 0
client/scss/components/_comments-controls.scss

@@ -0,0 +1,84 @@
+.comments-controls {
+    padding-right: $mobile-nice-padding;
+
+    @include media-breakpoint-up(sm) {
+        padding-right: $desktop-nice-padding;
+    }
+}
+
+.comments-toggle {
+    float: right;
+    position: relative;
+    width: 42px;
+    height: 42px;
+    cursor: pointer;
+
+    // Wagtail adds some top padding to labels on mobile
+    padding: 0;
+
+    &__icon {
+        position: absolute;
+        left: 0;
+        bottom: 10px;
+        width: 30px;
+        height: 30px;
+        color: $color-white;
+        opacity: 0.6;
+        transition: opacity 100ms cubic-bezier(0.4, 0, 0.2, 1);
+    }
+
+    &__count {
+        position: absolute;
+        top: -10px;
+        right: 0;
+        width: 22px;
+        height: 22px;
+        box-sizing: border-box;
+        border-radius: 50%;
+        background-color: #00b0b1;
+        border: 1px solid #007d7e;
+        color: $color-white;
+        font-size: 10px;
+        font-weight: bold;
+        text-align: center;
+
+        &:empty {
+            display: none;
+        }
+    }
+
+    [type=checkbox] {
+        position: absolute;
+        opacity: 0;
+        pointer-events: none;
+        top: -20px;
+    }
+
+    [type=checkbox]:checked + &__icon {
+        opacity: 1;
+    }
+
+    [type=checkbox]:focus + &__icon {
+        outline: 3px solid $color-focus-outline;
+    }
+}
+
+.comment-notifications-toggle {
+    float: right;
+    height: 42px;
+    margin-right: 30px;
+
+    label {
+        padding: 0;
+        margin: 0;
+        padding-top: 5px;
+        font-weight: normal;
+        font-size: 11px;
+        text-transform: uppercase;
+        color: $color-white;
+    }
+
+    .switch__toggle {
+        margin-left: 15px;
+    }
+}

+ 28 - 0
client/scss/components/_switch.scss

@@ -81,4 +81,32 @@ $switch-color-middle-grey: #777;
         opacity: 0;
         pointer-events: none;
     }
+
+    // Colour changes for when displaying on teal background
+    &--teal-background {
+        $background: #005b5e;
+
+        .switch__toggle {
+            &::before {
+                background-color: $background;
+                border: $switch-border solid $background;
+                opacity: 0.6;
+            }
+
+            &::after {
+                background-color: $color-white;
+                opacity: 0.5;
+            }
+        }
+
+        [type=checkbox]:checked + .switch__toggle::before {
+            // Override the white-background styling
+            background-color: $background;
+            border-color: $background;
+        }
+
+        [type=checkbox]:checked + .switch__toggle::after {
+            opacity: 1;
+        }
+    }
 }

+ 10 - 0
client/scss/components/_tabs.scss

@@ -72,6 +72,16 @@
         margin-top: 0;
         background-color: $color-header-bg;
     }
+
+    li.right {
+        float: right;
+        margin-right: 0;
+        margin-left: 2px;
+    }
+
+    li.wide {
+        width: unset;
+    }
 }
 
 .tab-content {

+ 1 - 0
client/scss/styles.scss

@@ -134,6 +134,7 @@ These are classes for components.
 @import 'components/skiplink';
 @import 'components/workflow-tasks';
 @import 'components/switch';
+@import 'components/comments-controls';
 
 
 /* OVERRIDES

+ 9 - 2
client/src/components/CommentApp/main.tsx

@@ -22,7 +22,8 @@ import {
   selectCommentFactory,
   selectEnabled,
   selectFocused,
-  selectIsDirty
+  selectIsDirty,
+  selectCommentCount
 } from './selectors';
 import CommentComponent from './components/Comment';
 import { CommentFormSetComponent } from './components/Form';
@@ -144,7 +145,8 @@ export class CommentApp {
     selectComments,
     selectEnabled,
     selectFocused,
-    selectIsDirty
+    selectIsDirty,
+    selectCommentCount
   }
   actions = commentActionFunctions;
 
@@ -209,6 +211,11 @@ export class CommentApp {
     this.store.dispatch(setFocusedComment(commentId, { updatePinnedComment: true }));
     return commentId;
   }
+  setVisible(visible: boolean) {
+    this.store.dispatch(updateGlobalSettings({
+      commentsEnabled: visible,
+    }));
+  }
   renderApp(
     element: HTMLElement,
     outputElement: HTMLElement,

+ 6 - 0
client/src/components/CommentApp/selectors/index.ts

@@ -47,3 +47,9 @@ export const selectIsDirty = createSelector(
       return Array.from(comment.replies.values()).some(reply => reply.deleted || reply.originalText !== reply.text);
     });
   });
+
+export const selectCommentCount = (state: State) => (
+  [...state.comments.comments.values()].filter(
+    (comment: Comment) => !comment.deleted && !comment.resolved
+  ).length
+);

+ 27 - 0
client/src/entrypoints/admin/page-editor.js

@@ -377,6 +377,33 @@ $(() => {
         $icon.addClass('icon-view').removeClass('icon-spinner');
       });
   });
+
+  // Comments toggle
+  $('.comments-toggle input[type=checkbox]').change((e) => {
+    // Show/hide comments
+    window.commentApp.setVisible(e.target.checked);
+
+    // Show/hide comment notifications toggle
+    if (e.target.checked) {
+      $('.comment-notifications-toggle').show();
+    } else {
+      $('.comment-notifications-toggle').hide();
+    }
+  });
+
+  // Keep number of comments up to date with comment app
+  const updateCommentCount = () => {
+    const commentCount = window.commentApp.selectors.selectCommentCount(window.commentApp.store.getState());
+
+    if (commentCount > 0) {
+      $('.comments-toggle__count').text(commentCount);
+    } else {
+      // Note: CSS will hide the circle when its content is empty
+      $('.comments-toggle__count').text('');
+    }
+  };
+  window.commentApp.store.subscribe(updateCommentCount);
+  updateCommentCount();
 });
 
 let updateFooterTextTimeout = -1;

+ 3 - 1
wagtail/admin/edit_handlers.py

@@ -365,11 +365,13 @@ class TabbedInterface(BaseFormEditHandler):
 
     def __init__(self, *args, **kwargs):
         self.base_form_class = kwargs.pop('base_form_class', None)
+        self.show_comments_toggle = kwargs.pop('show_comments_toggle', False)
         super().__init__(*args, **kwargs)
 
     def clone_kwargs(self):
         kwargs = super().clone_kwargs()
         kwargs['base_form_class'] = self.base_form_class
+        kwargs['show_comments_toggle'] = self.show_comments_toggle
         return kwargs
 
 
@@ -921,7 +923,7 @@ def get_edit_handler(cls):
                                    heading=gettext_lazy('Settings'),
                                    classname='settings'))
 
-        edit_handler = TabbedInterface(tabs, base_form_class=cls.base_form_class)
+        edit_handler = TabbedInterface(tabs, base_form_class=cls.base_form_class, show_comments_toggle=True)
 
     return edit_handler.bind_to(model=cls)
 

+ 21 - 1
wagtail/admin/templates/wagtailadmin/edit_handlers/tabbed_interface.html

@@ -1,10 +1,30 @@
-{% load wagtailadmin_tags %}
+{% load wagtailadmin_tags i18n %}
 <ul class="tab-nav merged" role="tablist">
     {% for child in self.children %}
         <li class="{{ child.classes|join:" " }} {% if forloop.first %}active{% endif %}" role="tab" aria-controls="tab-{{ child.heading|cautious_slugify }}">
             <a href="#tab-{{ child.heading|cautious_slugify }}" class="{% if forloop.first %}active{% endif %}">{{ child.heading }}</a>
         </li>
     {% endfor %}
+
+    {% if self.show_comments_toggle %}
+        <li class="right wide">
+            <div class="comments-controls">
+                <label class="comments-toggle" aria-label="{% trans 'Show comments' %}">
+                    <input type="checkbox" checked>
+                    {% icon name="comment-dots" class_name="comments-toggle__icon" %}
+                    <div class="comments-toggle__count">{# populated in page-editor.js #}</div>
+                </label>
+
+                <div class="comment-notifications-toggle">
+                    <label class="switch switch--teal-background">
+                        {% trans "Comment notifications" %}
+                        <input type="checkbox" checked>
+                        <span class="switch__toggle"></span>
+                    </label>
+                </div>
+            </div>
+        </li>
+    {% endif %}
 </ul>
 
 <div class="tab-content">

+ 3 - 0
wagtail/admin/templates/wagtailadmin/icons/comment-dots.svg

@@ -0,0 +1,3 @@
+<symbol id="icon-comment-dots" viewBox="0 0 512 512">
+    <path d="M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5c-2.2 2.3-2.8 5.7-1.5 8.7S4.8 480 8 480c66.3 0 116-31.8 140.6-51.4 32.7 12.3 69 19.4 107.4 19.4 141.4 0 256-93.1 256-208S397.4 32 256 32zM128 272c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128 0c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128 0c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"></path>
+</symbol>

+ 1 - 1
wagtail/admin/templates/wagtailadmin/pages/edit.html

@@ -183,4 +183,4 @@
             LockUnlockAction('{{ csrf_token|escapejs }}', '{% url 'wagtailadmin_pages:edit' page.id %}');
         });
     </script>
-{% endblock %}
+{% endblock %}

+ 1 - 0
wagtail/admin/wagtail_hooks.py

@@ -725,6 +725,7 @@ def register_icons(icons):
         'cogs.svg',
         'collapse-down.svg',
         'collapse-up.svg',
+        'comment-dots.svg',
         'comment.svg',
         'cross.svg',
         'date.svg',