These spec are flaky only in CI, not locally and not in GitHub actions.
The previous attempt was in 44eabde, but actually the failure happens
a bit earlier. This is another attempt to fix these specs. Quite a lot of
async logic is happening in emulateAutocomplete(), a call to settled()
in the end should help make it more reliable.
At the moment, PMs to groups with default notification level set to
`watching_first_post` do not generate "emailable" notifications. This happens
because, topic user notification level which is indirectly derived
from the group's default notification level is set to `tracking` if the
group's notification level happens to be `watching_first_post`.
This leads to a `group_message_summary` notification being created
instead of a `private_message` notification which results in no email
alerts being sent when a topic is created.
As this `watching_first_post` --> `tracking` switcheroo appears to be
intentional instead being a bug, this change extends `PostAlerter`'s
`notify_pm_users` method to create a `private_message` notification for
first posts created in a `watching_first_post` group even if the topic
user notification level is set to `tracking`
This commit attempts to have a bullet proof solution to the following case:
- long press on message (finger is still pressed)
- menu appears
- a button is now at finger location
- user releases finger
- a click is triggered on the button
Classic event canceling solution won't work here for performance reasons as we need the event to be passive in a scroll list.
In some cases, plugins may want to hide some of these actions
at all times, overriding the rules for canX with hiding these
buttons. To achieve this, a plugin can call the API
`removeChatComposerSecondaryButtons` and pass the list of button
IDs that should be removed as argument, like the example below:
```
withPluginApi("1.2.0", (api) => {
api.removeChatComposerSecondaryActions("copyLink", "select");
});
```
---------
Co-authored-by: Martin Brennan <martin@discourse.org>
These specs were skipped in d6d5eae1. They sometimes failed, and only on CI,
not in GitHub Actions.
I wasn't able to reproduce failures locally, but I expect clicking the send button
in chat composer should be more reliable than emulating pressing <kbd>Enter</kbd>.
When editing a message, we call `message.cook()` in the beginning of
`#sendEditMessage` methods, but when sending a new message,
the call to `message.cook()` is hidden in the `stageMessage` method.
We can just call `message.cook()` before sending the message, no matter
whether this is a new message or an edited message.
No test as this is very much a hack while lightbox is being revamped. We currently have no good/easy way AFAIK to stop event propagation on escape in magnificpopup.
This behavior has been possible for a long time and has been made more in recent commits. On PWA iOS when release the touch after the mobile actions menu has been shown, if the finger was over one of the buttons of the menu, it would trigger a click.
This commit should now correctly trap and cancel events.
The following case would create the perception of a broken back button on desktop:
- open discourse on home page
- click chat button in header
- hit back button
- observes that we are still on the channel didn't navigate to homepage as we would have expected
The back button is actually working but it's in a loop. We were doing a `transitionTo` after finding the ideal channel to show, so the browser history would look something like this:
- home
- chat index
- channel page
When hitting back, we would go to chat index which would run the same logic and transition us to channel page.
This change will use `replaceWith` to replace the chat index step by the channel step, this way our history will now look like this:
- home
- channel page
Hitting back will now correctly bring us to home.
This commit attempts to refactor our long press logic to make it more resilient and precise.
With this improvement two very UX/UI changes have been made:
- scale animation on long press
- prevents click on reaction to propagate to the message which would cause the active state of the message to trigger
This fixes an issue where a user could send an empty
string as a chat message .e.g ' ' and the message would
be posted. We don't want this, we need to strip the message
first before validating for length etc.
What does this change do?
This change is a continuation of
2191b879c6 and adds an input filter to the
edit sidebar categories modal which the user can use to filter through
the list of categories by the category's name.
Note that if a child category is being shown, all of its ancestors will
be shown even if the names of the ancestors do not match the given
filter. This is to ensure that we continue to display the hierarchy of a
child category even if the parent category does not match the filter.
Followup to e6c6c342d9,
we missed one part of this refactor which was to give
the correct composer element reference to ChatComposerUploads.
Without this the pasteEventListener for uploads was not
bound so uploading via paste did not work.
I tried to test this, and though I can write binary/text to
the clipboard and paste it into the composer, it does not
seem to be possible to end up with a paste event that
has clipboardData.files filled in, which is what is used
for the uploads. I think this is a restriction of JS
generally, and there doesn't seem to be a way to work around
it, so unfortunately we have to have no test for this still.
Why does this commit do?
This commit adds support for sub-subcategories in the new edit sidebar
categories modal added in fc296b9a81. Note
that sub-subcategories are enabled when `max_category_nesting` is set to
`3`.
* DEV: Implement staff logs for user columns edits
* deleted extra space in staff logger detail string, deleted string when no changes are made, added basic test coverage for EditDirectoryColumnsController
* fixed change made to #self.staff_actions un UserHistory
* implemented a method that builds the details, previous_values and new_values in a dynamic way
* removed details of changes
* refactored small merge
Usually, when a user is promoted to TL2 two messages are sent. The
first one is a system message 'tl2_promotion_message' which triggers a
'system_message_sent' Discourse event.
When the event is fired and if Discourse Narrative Bot is enabled, then
a second message is sent to the recipient of the first message. The
recipients was determined by looking at the list of users that can
access that topic and pick the last one. This method does not work if
'site_contact_group_name' site setting is set because it adds the group
in the list of recipients.
A solution to this problem would have been to select the last user in
the list of 'topic_allowed_users', but an even better solution is to
pass the name of the recipients when the 'system_message_sent'
Discourse event is fired.
This commit contains multiple changes to improve the composer behavior especially in the context of a thread:
- Generally rename anything of the form `chatChannelThread...` to `chatThread...``
- Moves the textarea interactor instance inside the composer server
- Improves the focus state and closing of panel related to the use of the Escape shortcut
- Creates `Chat::ThreadList` as a component instead of having `Chat::Thread::ListItem` and others which could imply they were children of a the `Chat::Thread` component
Adds a new `[grid]` tag that can arrange images (or other media) into a grid in posts.
The grid defaults to a 3-column with a few exceptions:
- if there are only 2 or 4 items, it defaults to a 2-column grid (because it generally looks better)
- on mobile, it defaults to a 2-column grid
- if there is only one item, the grid has no effect
Calling pluck is instantly making a SELECT, while passing the relationship allows rails to build a correct query.
Before (2 selects):
```
pry(main)> Post.where(topic_id: Topic.where(id: [1,3,4]).pluck(:id)).count
(1.3ms) SELECT "topics"."id" FROM "topics" WHERE "topics"."deleted_at" IS NULL AND "topics"."id" IN (1, 3, 4)
Post Count (0.5ms) SELECT COUNT(*) FROM "posts" WHERE "posts"."deleted_at" IS NULL AND "posts"."topic_id" IN (1, 3, 4)
```
After (1 select):
```
pry(main)> Post.where(topic_id: Topic.where(id: [1,3,4])).count
Post Count (2.7ms) SELECT COUNT(*) FROM "posts" WHERE "posts"."deleted_at" IS NULL AND "posts"."topic_id" IN (SELECT "topics"."id" FROM "topics" WHERE "topics"."deleted_at" IS NULL AND "topics"."id" IN (1, 3, 4))
```
This removes the modal container named-outlet/controller/template and replaces it with a component. Named outlets will be removed in Ember 4.x, so this change is part of that upgrade project.
Smaller changes include:
- update some of the computed values to be getters rather than calculated during `show()`.
- update tests which were previously depending on the modal class persisting after the modal was closed
Much of the logic in the service will be deprecated once we introduce component-based modals.
This work is split out from https://github.com/discourse/discourse/pull/21304
Previously merged in 80b77b2e and then reverted due to issues with the PM invite modal. This PR fixes the issue, and introduces a test which would have caught the issue.
Previously, there was an issue where closing the message actions menu on mobile would unintentionally trigger a click event on an element below it, such as a thread indicator or a reaction. With the recent fix, this problem has been resolved. Now, when you close the menu, it will no longer interfere with or activate any elements positioned underneath it.
Why is this change required?
Right now, we're awaiting on the promise returned by
`this.pmTopicTrackingState.startTracking()` which blocks the rendering
of the template until the promise resolves. However, this blocking of
the rendering ends up introducing yet another intermediate loading state
in the UI which we find unsightly. Instead of blocking the rendering, we
allow the promise to resolve in the background and display the
new/unread counts when the promise resolves.
What this change?
We are currently not fully satisfied with the current way to edit the
categories and tags that appears in the sidebar where the user is
redirected to the tracking preferences tab in the user's profile causing
the user to lose context of the current page. In addition, the dropdown
to select categories or tags limits the amount of information we can
display.
Since editing or adding a custom categories section is already using a
modal, we have decided to switch editing the categories and tags that
appear in the sidebar to use a modal as well.
This commit ships a first pass of the edit categories modal such that we
can keep the commit small and reviewable. The incomplete nature of the
feature is also reflected in the fact that the feature is hidden behind
a new `new_edit_sidebar_categories_tags_interface_groups` site setting.
One user can create a post or chat message with a hashtag they
have permission to use, but then when other users look at that
post they will see an empty space next to the hashtag because they
do not have the permission to load the colors in CSS classes for
the related category.
This fixes the issue by adding a default color with a special
CSS class if the user doesn't have permission to see the linked
channel/category on the hashtag.
Display modal for combined new and unread view with options:
- [x] Dismiss new topics
- [x] Dismiss new posts
- [ ] Stop tracking these topics so they stop appearing in my new list
Previously, the topic is pinned/unpinned even when the bookmark icon is pressed in the topic list page. Because we didn't check the class names of topic status icons.
What is this change required?
The `enable_offline_indicator` site setting is disabled by default so
there is no need for us to be rendering an extra Ember component when
the site setting is not enabled.
Why this change?
Before this change, the `GroupNotificationsButton` is rendered in the
template of `userPrivateMessages` route based on a conditional that
checks if the `isGroup` property is true. However, the `isGroup`
property is determined based on the child route that is rendered.
However, this leads to "jankiness" in the UI because the
`GroupNotificationsButton` will be rendered once the route is entered
even if the model for the child route has not been resolved yet.
What is the solution?
In order to avoid this, we move the rendering of the
`GroupNotificationsButton` into the template of the
`userPrivateMessages.group` route and rely on the `in-element` helper to
render it into the right spot in the template of the
`userPrivateMessages` route.