FEATURE: opt-in guidance on topics for users without access (#7852)

FEATURE: opt-in guidance on topics for users without access (#7852)

Co-Authored-By: majakomel maja.komel@gmail.com Co-Authored-By: Robin Ward robin.ward@gmail.com

diff --git a/app/assets/javascripts/discourse/components/topic-join-group-notice.js.es6 b/app/assets/javascripts/discourse/components/topic-join-group-notice.js.es6
new file mode 100644
index 0000000..1fd4f92
--- /dev/null
+++ b/app/assets/javascripts/discourse/components/topic-join-group-notice.js.es6
@@ -0,0 +1,17 @@
+import { default as computed } from "ember-addons/ember-computed-decorators";
+
+export default Ember.Component.extend({
+  classNames: ["topic-notice"],
+
+  @computed("model.group.{full_name,name,allow_membership_requests}")
+  accessViaGroupText(group) {
+    const name = group.full_name || group.name;
+    const suffix = group.allow_membership_requests ? "request" : "join";
+    return I18n.t(`topic.group_${suffix}`, { name });
+  },
+
+  @computed("model.group.allow_membership_requests")
+  accessViaGroupButtonText(allowRequest) {
+    return `groups.${allowRequest ? "request" : "join"}`;
+  }
+});
diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6
index 41fc658..e358cd3 100644
--- a/app/assets/javascripts/discourse/controllers/topic.js.es6
+++ b/app/assets/javascripts/discourse/controllers/topic.js.es6
@@ -941,6 +941,46 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
       }
     },
 
+    joinGroup() {
+      const groupId = this.get("model.group.id");
+      if (groupId) {
+        if (this.get("model.group.allow_membership_requests")) {
+          const groupName = this.get("model.group.name");
+          return ajax(`/groups/${groupName}/request_membership`, {
+            type: "POST",
+            data: {
+              topic_id: this.get("model.id")
+            }
+          })
+            .then(() => {
+              bootbox.alert(
+                I18n.t("topic.group_request_sent", {
+                  group_name: this.get("model.group.full_name")
+                }),
+                () =>
+                  this.previousURL
+                    ? DiscourseURL.routeTo(this.previousURL)
+                    : DiscourseURL.routeTo("/")
+              );
+            })
+            .catch(popupAjaxError);
+        } else {
+          const topic = this.model;
+          return ajax(`/groups/${groupId}/members`, {
+            type: "PUT",
+            data: { user_id: this.get("currentUser.id") }
+          })
+            .then(() =>
+              topic.reload().then(() => {
+                topic.set("view_hidden", false);
+                topic.postStream.refresh();
+              })
+            )
+            .catch(popupAjaxError);
+        }
+      }
+    },
+
     replyAsNewTopic(post, quotedText) {
       const composerController = this.composer;
 
diff --git a/app/assets/javascripts/discourse/models/topic.js.es6 b/app/assets/javascripts/discourse/models/topic.js.es6
index bc53717..4d3056b 100644
--- a/app/assets/javascripts/discourse/models/topic.js.es6
+++ b/app/assets/javascripts/discourse/models/topic.js.es6
@@ -481,12 +481,12 @@ const Topic = RestModel.extend({
 
   // Update our attributes from a JSON result
   updateFromJson(json) {
-    this.details.updateFromJson(json.details);
-
     const keys = Object.keys(json);
-    keys.removeObject("details");
-    keys.removeObject("post_stream");
+    if (!json.view_hidden) {
+      this.details.updateFromJson(json.details);
 
+      keys.removeObjects(["details", "post_stream"]);
+    }
     keys.forEach(key => this.set(key, json[key]));
   },
 
diff --git a/app/assets/javascripts/discourse/routes/topic-from-params.js.es6 b/app/assets/javascripts/discourse/routes/topic-from-params.js.es6
index 63a0ebc..c545cff 100644
--- a/app/assets/javascripts/discourse/routes/topic-from-params.js.es6
+++ b/app/assets/javascripts/discourse/routes/topic-from-params.js.es6
@@ -35,6 +35,11 @@ export default Discourse.Route.extend({
         // TODO we are seeing errors where closest post is null and this is exploding
         // we need better handling and logging for this condition.
 
+        // there are no closestPost for hidden topics
+        if (topic.view_hidden) {
+          return;
+        }
+
         // The post we requested might not exist. Let's find the closest post
         const closestPost = postStream.closestPostForPostNumber(
           params.nearPost || 1
@@ -76,5 +81,14 @@ export default Discourse.Route.extend({
           console.log("Could not view topic", e);
         }
       });
+  },
+
+  actions: {
+    willTransition() {
+      this.controllerFor("topic").set(
+        "previousURL",
+        document.location.pathname
+      );
+    }
   }
 });
diff --git a/app/assets/javascripts/discourse/templates/components/topic-join-group-notice.hbs b/app/assets/javascripts/discourse/templates/components/topic-join-group-notice.hbs
new file mode 100644
index 0000000..3285ea5
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/components/topic-join-group-notice.hbs
@@ -0,0 +1,5 @@
+{{accessViaGroupText}}
+{{d-button action=action
+    class="btn-primary topic-join-group"
+    icon="user-plus"
+    label=accessViaGroupButtonText}}
diff --git a/app/assets/javascripts/discourse/templates/topic.hbs b/app/assets/javascripts/discourse/templates/topic.hbs
index 18ba28b..1673cb3 100644
--- a/app/assets/javascripts/discourse/templates/topic.hbs
+++ b/app/assets/javascripts/discourse/templates/topic.hbs
@@ -1,144 +1,95 @@
 {{#discourse-topic multiSelect=multiSelect enteredAt=enteredAt topic=model hasScrolled=hasScrolled}}
-  {{#if model}}
-    {{add-category-tag-classes category=model.category tags=model.tags}}
-    <div class="container">
-      {{discourse-banner user=currentUser banner=site.banner overlay=hasScrolled hide=model.errorLoading}}
-    </div>
-  {{/if}}
+  {{#if model.view_hidden}}
+    {{topic-join-group-notice model=model action=(action "joinGroup")}}
+  {{else}}
+    {{#if model}}
+      {{add-category-tag-classes category=model.category tags=model.tags}}
+      <div class="container">
+        {{discourse-banner user=currentUser banner=site.banner overlay=hasScrolled hide=model.errorLoading}}
+      </div>
+    {{/if}}
 
-  {{#if showSharedDraftControls}}
-    {{shared-draft-controls topic=model}}
-  {{/if}}
+    {{#if showSharedDraftControls}}
+      {{shared-draft-controls topic=model}}
+    {{/if}}
 
-  {{plugin-outlet name="topic-above-post-stream" args=(hash model=model)}}
+    {{plugin-outlet name="topic-above-post-stream" args=(hash model=model)}}
 
-  {{#if model.postStream.loaded}}
-    {{#if model.postStream.firstPostPresent}}
-      {{#topic-title cancelled=(action "cancelEditingTopic") save=(action "finishedEditingTopic") model=model}}
-        {{#if editingTopic}}
-          <div class="edit-topic-title">
-          {{#if model.isPrivateMessage}}
-            <span class="private-message-glyph">{{d-icon "envelope"}}</span>
-          {{/if}}
-            {{text-field id="edit-title" value=buffered.title maxlength=siteSettings.max_topic_title_length autofocus="true"}}
-            {{#if showCategoryChooser}}
-              {{category-chooser
-                class="small"
-                value=(unbound buffered.category_id)
-                onSelectAny=(action "topicCategoryChanged")}}
+    {{#if model.postStream.loaded}}
+      {{#if model.postStream.firstPostPresent}}
+        {{#topic-title cancelled=(action "cancelEditingTopic") save=(action "finishedEditingTopic") model=model}}
+          {{#if editingTopic}}
+            <div class="edit-topic-title">
+            {{#if model.isPrivateMessage}}
+              <span class="private-message-glyph">{{d-icon "envelope"}}</span>
             {{/if}}
+              {{text-field id="edit-title" value=buffered.title maxlength=siteSettings.max_topic_title_length autofocus="true"}}
+              {{#if showCategoryChooser}}
+                {{category-chooser
+                  class="small"
+                  value=(unbound buffered.category_id)
+                  onSelectAny=(action "topicCategoryChanged")}}
+              {{/if}}
 

[... diff too long, it was truncated ...]

GitHub sha: 71bf9ec1

1 Like

This commit has been mentioned on Discourse Meta. There might be relevant details there:

This commit has been mentioned on Discourse Meta. There might be relevant details there: