将默认群组页面更改为/messages

您好,

当从 /g 页面访问群组时,是否有办法让群组 URL 指向 /g/group-slug/messages 而不是 /g/group-slug/members

我们有几个群组用于群组消息。让人们少点击一次即可到达他们群组的消息将很有帮助。这比查看群组成员对我们来说更重要。

我知道可以通过直接链接来做到这一点,但我希望它来自 /g?type=my 页面,该页面非常动态且以用户为中心。

4 个赞

它们不是常规链接。它们是通过 link-to Ember 组件处理的,并且涉及到一些路由。

最简单的方法是劫持该元素的点击事件并在那里执行你的操作。这会放在主题的 common > header 中。

<script
  type="text/x-handlebars"
  data-template-name="/connectors/group-index-box-after/link-to-group-inbox"></script>

<script type="text/discourse-plugin" version="0.8">
  const DiscourseURL = require("discourse/lib/url").default;
  api.registerConnectorClass('group-index-box-after', 'link-to-group-inbox', {
    setupComponent(args) {
      const group = args.model;

       if (group.is_group_user && group.has_messages) {
         const groupLink = document.querySelector(`.group-box.${group.name}`);
         const newHref = `/g/${group.name}/messages`;

         // 更新浏览器标题并处理新标签页
         groupLink.href = newHref;

         // 重定向链接
         groupLink.addEventListener("click", (event) => {
            DiscourseURL.routeTo(newHref);
            event.preventDefault();
         }, {once: true})
       }
     }
  });
</script>

如果用户是该组成员并且该组有消息,它将重定向到收件箱。否则,它将回退到默认的 /members 页面。

7 个赞

太棒了——这太神奇了!!!!它效果很好。谢谢。


稍后……

抱歉,我遇到了一个后续问题,需要您提供一点帮助!

我的几个群组仍然显示 /g/group-slug/messages,尽管它们没有任何消息。

仔细检查后,它们过去曾有过消息,这些消息已被转换为主题或删除。Data Explorer 显示这些群组在 Groups 表中 has_messagesTrue

我尝试通过 Rails 为这些群组更改它,但似乎无法实现:

[2] pry(main)> Group.find_by_name(“group-slug”).has_messages
=> true
[3] pry(main)> Group.find_by_name(“group-slug”).has_messages = false
=> false
[4] pry(main)> Group.find_by_name(“group-slug”).has_messages
=> true

有什么建议吗?除了删除群组并重新创建(我不太愿意这样做)之外。

3 个赞

您只需要在 rails 控制台中运行此行。它应该会更新所有组。

Group.refresh_has_messages!
1 个赞

这对我来说都奏效了,除了两个——谢谢。最后这两个顽固的,我想我只能删除并重新创建了!

在这样做的时候,我发现了原因——这是一个小小的 #bug。

在将群组私信转换为主题时,会保留被邀请者的信息。虽然如果主题被转换回来,这会很好,但它确实意味着在运行 Group.refresh_has_messages! 时,他们会被错误地计算在内。

2 个赞

是否也可以劫持点击@提及的组后,再点击进入组所获得的链接?我认为这是不使用URL就能访问组的仅有的两种方式。

我现在想要的是(是不是很贪心?),让所有指向组的链接都像你的代码处理/g页面链接那样。

1 个赞

@Johani,这可以做到吗?我研究了一下,这显然远远超出了我的能力范围。

当然,您可以在主题/组件的 header 标签中尝试类似以下的代码。我留下了一些注释,如果您想跟随。准备好使用时可以删除它们。

同样的应用规则。如果用户是组成员并且该组有消息,Discourse 将导航到组收件箱。否则,用户将进入成员目录。

<script type="text/discourse-plugin" version="0.8">
  // Part 1: modify the path for the links in the group cards. This ensure that the link
  // title reflects where it leads and handles opening the link a new tab.
  const discourseComputed = require("discourse-common/utils/decorators").default;

  api.modifyClass("component:group-card-contents", {
    // The groupPath property is used to generate the href for the group links
    // in the group card. Let's modify it
    @discourseComputed("group")
    groupPath(group) {
      // get the default value from core
      let groupURL = this._super(...arguments);

      // if the user matches our requirment, modify the url so it goes to the inbox
      if (group.is_group_user && group.has_messages) {
        groupURL = `${groupURL}/messages/`;
      }

      // return either the default or modified value
      return groupURL;
    }
  });

  // Part 2: modify in-app routing. This ensures that regular in-app navigation is
  // handled correctly and takes the user to the group inbox if they meet the
  // requirements

  const DiscourseURL = require("discourse/lib/url").default;
  const { groupPath } = require("discourse/lib/url");
  const { action } = require("@ember/object");

  api.modifyClass("controller:user-card", {

    // showGroup here is an action that belongs to the user-card controller.
    // This is what gets called when you click on the group name / avatar inside group cards
    @action
    showGroup(group) {
      // call super to make sure code from core is loaded first
      this._super(...arguments);

      // group path is a built-in Discourse url helper function
      let groupURL = groupPath(group.name);

      // if the user matches the requirments, modify the url
      if (group.is_group_user && group.has_messages) {
        groupURL = `${groupURL}/messages/`;
      }

      // call routeTo() with either the default or the modified groupURL
      DiscourseURL.routeTo(groupURL);
    }
  });
</script>
2 个赞

你太棒了!它适用于任何使用卡片的情况。

现在只有一种类型的链接仍然是无向的:当在群组私人消息中时,群组的链接。从群组消息导航到群组(以及收件箱)时,这实际上非常方便。

你认为我们也能抓住它吗?

(顺便说一句,一旦我们完成,我会将其打包成一个 TC 并为此创建一个主题,以便其他人可以轻松访问)

2 个赞

这些链接使用了略有不同的序列化器——因为在那里不需要所有的组数据。

不过,您可以在初始页面视图中存储当前用户群组的过滤列表,并将其用作检查成员资格的参考。这些信息已包含在初始负载中,因此不会产生额外请求等开销。类似这样:

<script type="text/discourse-plugin" version="0.8">
  const user = api.getCurrentUser();

  if (!user) {
    return;
  }

  const userGroups = user.groups.map(group => group.name);

  api.reopenWidget("pm-map-user-group", {
    transform(attrs) {

      const group = attrs.group;
      const isGroupUser = Object.values(userGroups).includes(group.name);

      // {href: "/g/foo"};
      let groupURL = this._super(...arguments);

      if (isGroupUser && group.has_messages) {
        groupURL.href = `${groupURL.href}/messages/`;
      }

      return groupURL;
    }
  });
</script>

将此代码段保留在其自己的脚本标签中,并将其添加到标题中,与其他代码段一起。您将其分开是因为如果用户未登录,它会快速退出。

1 个赞

:partying_face: 我们到了!效果非常好,在手机上也能用。

感谢Joe的惊人坚持。我最好履行我的承诺,开始着手开发那个#theme-component,对吧?

稍后……
来了:

1 个赞

我还有一件事需要帮助才能完全完成。我知道这有点厚脸皮。

我现在正尝试修改 Pavilion JavaScript,就是无法让它正常工作。这是我尝试修改的内容:

createWidget('layouts-group-link', {
  tagName: 'li.layouts-group-link',
  buildKey: (attrs) => `layouts-group-link-${attrs.id}`,

  getGroupTitle(group) {
    return h('span.group-title', group.name);
  },

  isOwner(group) {
    if (group.owner) {
      return h('span.group-owner-icon', iconNode('shield-alt'));
    }
  },

  html(attrs) {
    const contents = [this.getGroupTitle(attrs), this.isOwner(attrs)];
    return contents;
  },

  click() {
      DiscourseURL.routeTo(`/g/${this.attrs.name}/messages`);
  },
});

我该如何将其应用到最后一段 click(){etc} 中?我已经尝试了我能想到的一切,但都失败了。我最终只会完全破坏链接。

      if (group.is_group_user && group.has_messages) {
        groupURL = `${groupURL}/messages/`;
      }
1 个赞

没关系!!!@keegan 已经解决了:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.

对于一些存在“消息幽灵”的群组,这不起作用。可以通过以下查询来识别这些群组(前提是群组互动设置中已限制消息传递):

SELECT id, name, has_messages, messageable_level
From groups
Where messageable_level < 10
AND messageable_level <> 3
AND has_messages = true
ORDER by id

你也可以通过修改 groups 表来强制重置(当然是在 Rails 控制台中,请先备份!)。

Group.where(id: XXX).update_all(has_messages: false)

如果这不起作用或恢复了,你可能还需要清理 topic_groupstopic_allowed_groups 表:

TopicGroup.where(group_id: XXX).destroy_all
TopicAllowedGroup.where(group_id: XXX).destroy_all

此主题已在 30 天后自动关闭。不再允许回复。