Commit Graph

2087 Commits

Author SHA1 Message Date
Joffrey JAFFEUX 6ba24b3599
UX: prevents long press on reaction to open actions (#20899)
This is super hard to write a test as a combination of: long press, mobile and popup.
2023-03-30 20:01:38 +02:00
Martin Brennan f8ff97b2ec
DEV: Add specs to ChannelSerializer and StructuredChannelSerializer (#20872)
This adds specs to the mentioned serializers to catch regressions
with MessageBus last_ids and to ensure the correct ones are being
returned and passed down to the ChannelSerializer.

Followup to d8ad5c3
2023-03-30 12:16:32 +10:00
Jan Cernik afe3e36363
DEV: Remove lazy-yt and replace with lazy-videos (#20722)
- Refactors the old plugin to remove jquery usage
- Adds support for Vimeo videos (default on) and Tiktok (experimental and default off)
2023-03-29 11:54:25 -04:00
Joffrey JAFFEUX 69de5b161f
FIX: ensures removing a reaction doesn’t remove others (#20869) 2023-03-29 08:39:52 +02:00
Martin Brennan 70c0955722
DEV: Uncomment chat upload system specs (#20859)
These were commented in  daaa41ae07,
doesn't seem to have made an observable difference, uncommenting
these now to see if chat system specs still pass.
2023-03-28 10:55:01 -04:00
Martin Brennan d8ad5c38b9
FIX: channel_message_bus_last_id was incorrect (#20858)
Followup to 3ea8df4b06,

I forgot to wrap the call to Chat::Publisher.root_message_bus_channel(object.chat_channel.id)
in MessageBus.last_id, so the channel_message_bus_last_id key was
ending up as e.g. "/chat/58" instead of the last ID value.
2023-03-28 16:01:27 +10:00
Martin Brennan 3ea8df4b06
DEV: Fix excessive MessageBus#last_id calls in chat (#20855)
We noticed via profiling that chat was doing N redis calls
per channel. Part of this was from the kick_message_bus_last_id
from 520d4f504b being incorrectly
passed down for DM channels rather that public channels, and the
other part was from the root MessageBus channel last_id
being fetched in ChannelSerializer for every single channel.

This commit fixes both issues, for me going from 134 redis calls
on page load to 20 locally.

Also deletes an old file missed in 12a18d4d55
2023-03-28 14:45:45 +10:00
Martin Brennan c912c58d6c
FIX: Make chat tracking payload backwards compatible (#20852)
Followup cab4b2cfba,
this was causing client JS errors because the old version
of the client was expecting the old keys, but the new
ruby version of the app was sending different keys via
the MessageBus payload. We can remove this in a couple
of weeks.
2023-03-28 12:56:32 +10:00
Martin Brennan cab4b2cfba
DEV: Introduce bulk channel tracking publisher (#20838)
This commit introduces a Chat::Publisher and MessageBus endpoint
that allows for updating a user's channel tracking state in bulk for
multiple channels, rather than having to do it for one channel
at a time.

This also required an improvement to ChannelUnreadsQuery -- now
multiple channel IDs can be passed to this to get the unread counts
and mention counts for those channels for a user, also increasing
efficiency rather than having to do a query for every individual
channel.

Followup to #20802
2023-03-28 09:36:28 +10:00
Penar Musaraj daaa41ae07
WIP: Skip system specs with upload fabricators (#20821)
A shot in the dark to see if these are the culprits for the many random
spec failures in CI.
2023-03-27 13:11:17 -04:00
Jarek Radosz cbabc01e0e
DEV: Make `capabilities` into a service (#18678) 2023-03-27 19:06:36 +02:00
Joffrey JAFFEUX 05174a6abd
DEV: correctly tests text is rendered in replies (#20845) 2023-03-27 15:42:30 +02:00
Jarek Radosz 65b1381575
DEV: Fix a constant redefinition warning (#20842) 2023-03-27 13:34:25 +02:00
Martin Brennan 55ef4d9a98
FIX: Make sure marking channels read propagates to all tabs (#20802)
Instead of just marking the state read in JS for each channel
after the AJAX call, we can instead just rely on the MessageBus
user-tracking-state chat channel, and publish the state to all
the channels affected in MarkAllUserChannelsRead. This will make
it so the blue dots for the channels are cleared across all tabs.
2023-03-24 10:12:35 +01:00
Joffrey JAFFEUX 67913e59e0
FIX: relies only on message bus to set tracking state (#20785)
This manual set was happening only after the request so was not much faster than just waiting on message bus update. It's not by itself changing any behavior or fixing any bug but it makes reasoning about the whole state easier as it happens in only one central place.
2023-03-23 11:11:13 +01:00
Alan Guo Xiang Tan 2d46824a87
DEV: Switch to data attributes to represent sidebar section name (#20771)
Data attributes are less restrictive than the class attribute.
2023-03-23 13:09:45 +08:00
Martin Brennan 5d4c5d959a
FIX: Make sure "last visit" is not shown after marking all messages read (#20782)
Followup to a0381157e9, we just
need to make sure we set currentUserMembership.last_read_message_id
to the last_read_message_id from the updated memberships after marking
all channels read, otherwise we do not scroll to the bottom and still
show the "last visit" separators in channels that have been
marked read.
2023-03-23 13:18:55 +10:00
Discourse Translator Bot 6406d8e4cb
Update translations (#20760) 2023-03-22 12:13:36 +01:00
Martin Brennan a0381157e9
FEATURE: Mark all chat channels read with a shortcut (#20629)
This commit adds a keyboard shortcut (Shift+ESC) for chat which marks all
of the chat channels that the user is currently a following member of as read,
updating their `last_read_message_id`. This is done via a new service.

It also includes some refactors and controller changes:

* The old mark message read route from `ChatController` is now supplanted
  by the `Chat::Api::ReadsController#update` route.
* The new controller can handle either marking a single or all messages read,
  and uses the correct service based on the route and params.
* The `UpdateUserLastRead` service is now used (it wasn't before), and has been slightly
  updated to just use the guardian user ID.
2023-03-22 13:24:07 +10:00
Martin Brennan 786f7503b4
DEV: Skip channel-wide mention chat specs (#20770)
These were added in 7dd317b875
but are now consistently failing with described_class.chat_summary(user, {})
returning nil. Skipping for now because they are holding up other
things.

To reproduce failure run:

RSPEC_SEED=46586 bundle exec rake plugin:spec
2023-03-22 12:44:01 +10:00
Martin Brennan 520d4f504b
FEATURE: Auto-remove users without permission from channel (#20344)
There are many situations that may cause users to lose permission to
send messages in a chat channel. Until now we have relied on security
checks in `Chat::ChatChannelFetcher` to remove channels which the
user may have a `UserChatChannelMembership` record for but which
they do not have access to.

This commit takes a more proactive approach. Now any of these following
`DiscourseEvent` triggers may cause `UserChatChannelMembership`
records to be deleted:

* `category_updated` - Permissions of the category changed
   (i.e. CategoryGroup records changed)
* `user_removed_from_group` - Means the user may not be able to access the
   channel based on `GroupUser` or also `chat_allowed_groups`
* `site_setting_changed` - The `chat_allowed_groups` was updated, some
   users may no longer be in groups that can access chat.
* `group_destroyed` - Means the user may not be able to access the
   channel based on `GroupUser` or also `chat_allowed_groups`

All of these are handled in a distinct service run in a background
job. Users removed are logged via `StaffActionLog` and then we
publish messages on a per-channel basis to users who had their
memberships deleted.

When the user has a channel they are kicked from open, we show
a dialog saying "You no longer have access to this channel".

When they click OK we redirect them either:

* To their first other public channel, if they have any followed
* The chat browse page if they don't

This is to save on tons of requests from kicked out users getting messages
from other channels.

When the user does not have the kicked channel open, we can just
silently yoink it out of their sidebar and turn off subscriptions.
2023-03-22 10:19:59 +10:00
Joffrey JAFFEUX b5c4e1b813
FIX: do not refresh metadata of not followed channel (#20766) 2023-03-21 20:13:44 +01:00
Andrei Prigorshnev 0562f952ed
DEV: no need to pass down `skip_notifications` for expanding mentions (#20683)
This refactoring simplifies ChatNotifier a bit. I wanted to drop 
that argument for expand_direct_mentions too, but that needs 
a bit deeper refactoring, so it's better to do it separately.

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2023-03-21 19:44:24 +04:00
Kris 147941a5d7
UX: update chat icon to d-chat (#20744) 2023-03-21 10:40:42 -04:00
Joffrey JAFFEUX 7ccc7b75b2
FIX: ensures user with multiple tabs see own reactions (#20759)
Prior to this fix, we wouldn't display reactions done on different tabs. So, if user A was reacting on tab 1, tab 2 wouldn't display this reaction.

Since few weeks ago we now have the guarantee to have uniq reactions on a message which should prevent any duplicate.

This commit also removes various skipped tests related to reactions and makes `sign_in` explicit at the beginning of each test.

<!-- NOTE: All pull requests should have tests (rspec in Ruby, qunit in JavaScript). If your code does not include test coverage, please include an explanation of why it was omitted. -->
2023-03-21 15:25:35 +01:00
Joffrey JAFFEUX 92797109ba
DEV: uses container resize event instead of mutation (#20757)
This commit takes advantage of the `ResizeObserver` to know when dates should be re-computed, it works like this:

```
scrollable-div
--  child-enclosing-div with resize observer
---- message 1
---- message 2
---- message x
```

It also switches to bottom/height for date separators sizing, instead of bottom/top, it prevents a bug where setting the top of the first item (at the top) would cause scrollbar to move to top.

<!-- NOTE: All pull requests should have tests (rspec in Ruby, qunit in JavaScript). If your code does not include test coverage, please include an explanation of why it was omitted. -->
2023-03-21 11:30:32 +01:00
Martin Brennan 0a06974a8a
DEV: Rough chat message loading and posting in thread (#20579)
This commit does a couple of things:

* Adds the ability to load messages in the chat thread panel when it is open. This just loads the most recent N messages, same as a channel, and does nothing more, no scrolling or anything like that.
* Displays the messages in an extremely simple unordered list with no additional features.
* Allows posting new messages to the thread, and echoes them into the main channel, but does not respond to any sort of MessageBus events.

I've moved messages/clearMessages/addMessages/findMessage code out of the `ChatChannel` model
and into a new `ChatMessagesManager` class, which is instantiated in both the `ChatChannel` model
and the `ChatThread` model. This allows both to manage messages in the same way via the
`TrackedArray` pattern.

This is all hidden behind experimental flags, there is no way to make this not completely broken
in a single commit. Much more work and refactoring needs to be done first.

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2023-03-21 15:29:10 +10:00
Joffrey JAFFEUX 53cadac4b8
UX: disables composer auto focus on drawer (#20751)
This behavior was interfering with topics shortcuts.
2023-03-20 22:24:12 +01:00
Joffrey JAFFEUX 25d06faa8b
FIX: correctly checks for chat enabled in incoming webhooks controller (#20730)
This commit also moves the spec into the correct folder
2023-03-20 09:42:36 +01:00
Jarek Radosz 38fdd842f5
UX: Fix chat separator alignment (#20669)
Also: work around 1px svg shift in scroll-to-bottom button
2023-03-18 18:03:54 +01:00
Joffrey JAFFEUX aeab38aff1
UX: disable arrow up to edit if last message is not editable (#20729) 2023-03-17 23:08:10 +01:00
Joffrey JAFFEUX aa8eff5e16
FIX: ensures updateLastRead is called when receiving a message (#20728)
This behavior is hard to test as it's mostly fixing a race condition: User A sends a message at the same time than User B, which as a result doesn't cause a scroll for the second message and we don't update last read unless we do a small up and down scroll.

`updateLastRead` is debounced so it has no direct consequences to call it slightly more often than what should ideally be needed.
2023-03-17 22:46:59 +01:00
Joffrey JAFFEUX cfee0cfee9
FIX: ensures lightbox is working after collapse/expand (#20724)
Prior to this fix, the upload was removed from DOM when collapsed and not decorated again on expand, which was causing lightbox to not get reapplied. The fix is reverting to previous state where content was not removed from DOM.
2023-03-17 18:26:32 +01:00
Joffrey JAFFEUX c5e5b6d5ab
DEV: fixes a flakey spec (#20721) 2023-03-17 18:01:19 +01:00
Joffrey JAFFEUX 184ce647ea
FIX: correctly infer polymorphic class from bookmarkable type (#20719)
Prior to this change `registered_bookmarkable` would return `nil` as  `type` in `Bookmark.registered_bookmarkable_from_type(type)` would be `ChatMessage` and we registered a `Chat::Message` class.

This commit will now properly rely on each model `polymorphic_class_for(name)` to help us infer the proper type from a a `bookmarkable_type`.

Tests have also been added to ensure that creating/destroying chat message bookmarks is working correctly.

---

Longer explanation

Currently when you save a bookmark in the database, it's associated to another object through a polymorphic relationship, which will is represented by two columns: `bookmarkable_id` and `bookmarkable_type`. The `bookmarkable_id` contains the id of the relationship (a post ID for example) and the `bookmarkable_type` contains the type of the object as a string by default, (`"Post"` for example).

Chat plugin just started namespacing objects, as a result a model named `ChatMessage` is now named `Chat::Message`, to avoid complex and risky migrations we rely on methods provided by rails to alter the `bookmarkable_type` when we save it: we want to still save it as `"ChatMessage"` and not `"Chat::Message"`. And, to retrieve the correct model when we load the bookmark from the database: we want `"ChatMessage"` to load the `Chat::Message` model and not the `ChatMessage`model which doesn't exist anymore.

On top of this the bookmark codepath is allowing plugins to register types and will check against these types, so we alter this code path to be able to do a similar ChatMessage <-> Chat::Message dance and allow to check the type is valid. In the specific case of this commit, we were retrieving a `"ChatMessage"` bookmarkable_type from the DB and looking for it in the registered bookmarkable types which contain `Chat::Message` and not `ChatMessage`.
2023-03-17 17:20:24 +01:00
Joffrey JAFFEUX 12a18d4d55
DEV: properly namespace chat (#20690)
This commit main goal was to comply with Zeitwerk and properly rely on autoloading. To achieve this, most resources have been namespaced under the `Chat` module.

- Given all models are now namespaced with `Chat::` and would change the stored types in DB when using polymorphism or STI (single table inheritance), this commit uses various Rails methods to ensure proper class is loaded and the stored name in DB is unchanged, eg: `Chat::Message` model will be stored as `"ChatMessage"`, and `"ChatMessage"` will correctly load `Chat::Message` model.
- Jobs are now using constants only, eg: `Jobs::Chat::Foo` and should only be enqueued this way

Notes:
- This commit also used this opportunity to limit the number of registered css files in plugin.rb
- `discourse_dev` support has been removed within this commit and will be reintroduced later

<!-- NOTE: All pull requests should have tests (rspec in Ruby, qunit in JavaScript). If your code does not include test coverage, please include an explanation of why it was omitted. -->
2023-03-17 14:24:38 +01:00
Blake Erickson 5103d249aa DEV: Skip chat channel test
The screenshot looks good, but the test appears to be bad. Skipping this
test for now, will follow-up later.
2023-03-16 15:27:09 -06:00
Blake Erickson 6dcb099547 FIX: Escaped mentions in chat excerpts
Mentions are now displayed as using the non-cooked message which fixes
the problem. This is not ideal. I think we might want to rework how
these excerpts are created and rendered in the near future.

Co-authored-by: Jan Cernik <jancernik12@gmail.com>
2023-03-16 15:27:09 -06:00
Blake Erickson a373bf2a01 SECURITY: XSS on chat excerpts
Non-markdown tags weren't being escaped in chat excerpts. This could be
triggered by editing a chat message containing a tag (self XSS), or by
replying to a chat message with a tag (XSS).

Co-authored-by: Jan Cernik <jancernik12@gmail.com>
2023-03-16 15:27:09 -06:00
Andrei Prigorshnev 7dd317b875
DEV: add test cases for email notifications about channel-wide mentions (#20691)
A follow-up to e6c04e2d.
2023-03-16 21:43:56 +04:00
Andrei Prigorshnev 94fd884297
DEV: remove unused string (#20662)
The button was removed in fca6805a
2023-03-16 00:15:07 +04:00
Andrei Prigorshnev e6c04e2dc2
FIX: do not send emails when channel-wide mentions are disabled in a channel (#20677)
This regressed with the commit fa543cd. Starting from that commit, we create mention records even if a user shouldn't be notified. So when sending emails, we should be making sure if a notification was actually created for a mention. This is essentially the whole fix that we need here. Tests will be provided in a following PR.
2023-03-14 21:45:05 +04:00
Discourse Translator Bot 4cf065c480
Update translations (#20671) 2023-03-14 15:04:54 +01:00
Joffrey JAFFEUX 727100d1e2
DEV: adds a `addChatDrawerStateCallback` API (#20640)
Usage:

```javascript
api.addChatDrawerStateCallback(({ isDrawerActive, isDrawerExpanded }) => {
  // do something
});
```

Note this commit also uses this new API to add a css class (chat-drawer-active) on the body when the drawer is active.
2023-03-10 18:49:59 +01:00
Joffrey JAFFEUX ada89d6124
FIX: ensures edited message is correctly re-decorated (#20637) 2023-03-10 17:06:13 +01:00
Joffrey JAFFEUX 60ce3d24fa
FIX: more consistent scroll to bottom (#20634)
This fix uses direct `scrollTop` manipulation instead of `scrollIntoView` when we are certain we actually want the bottom of the screen. This avoids a range of issues especially in safari but also chrome where the scroll position was not correct at the end of `scrollIntoView`, especially due to images.
2023-03-10 16:25:21 +01:00
Andrei Prigorshnev 7df40fc905
DEV: do not fabricate a notification when fabricating a chat_mention (#20636)
This is just a little clean-up in tests. In the past, when creating a `chat_mention` 
record, we always created a related notification. Starting from fa543cda 
notifications and chat_mentions are fully decoupled from each other. So if we're 
testing just chat mentions there is no need to fabricate notifications for them.
2023-03-10 18:32:33 +04:00
Martin Brennan 168de52538
DEV: Change sidebar header dropdown to use wait_for_animation (#20627)
* DEV: Change sidebar header dropdown to use wait_for_animation

Introduced in 54351e1b8a, this
helper should remove the need to have to add the .animated
CSS class in JS for the sidebar.

* DEV: Revert spec change
2023-03-10 14:54:57 +10:00
Andrei Prigorshnev e292c45924
DEV: better split create_notification! and send_notifications logic (#20562)
`create_notification!` - creates a notification in the database, `send_notifications` sends desktop and mobile notifications. This PR moves some code to decouple these two tasks more explicitly. It only moves code without changing any behavior, and the job is covered with tests (see chat_notify_mentioned_spec).
2023-03-09 22:17:18 +04:00
Joffrey JAFFEUX 73be7b3dd8
FIX: improves unread state precision (#20615)
- Will consider a message read only one the bottom of the message has been read
- Will allow to mark a message bigger than the view port as read
- Code should be more performant as the scroll is doing less (albeit more often)
- Gives us a very precise scroll state. Problem with throttling scroll is that you could end up never getting the even where scrollTop is at 0, opening a whole range of edge cases to handle
2023-03-09 19:06:33 +01:00