Commit Graph

173 Commits

Author SHA1 Message Date
Martin Brennan 07c3782e51
FEATURE: Show unread in sidebar for unread channel threads (#22342)
This commit makes it so that when the user has unread threads
for a channel we show a blue dot in the sidebar (or channel index
for mobile/drawer).

This blue dot is slightly different from the channel unread messages:

1. It will only show if the new thread messages were created since
   the user last viewed the channel
2. It will be cleared when the user views the channel, but the threads
   are still considered unread because we want the user to click into
   the thread list to view them

This necessitates a change to the current user serializer to also
include the unread thread overview, which is all unread threads
across all channels and their last reply date + time.
2023-07-17 13:00:49 +10:00
Martin Brennan 10d155ea41
DEV: Further improve thread list query and add spec (#22610)
Followup to d7ef7b9c03,
this adds a spec to test the case where old threads are
still unread for the user and should show at the top regardless
of pagination, and fixes some issues/makes some slight refactors.
2023-07-14 16:08:35 +10:00
Martin Brennan 72bbc2fa8a
FIX: created_at datetime format inconsistencies in chat (#22611)
This commit attempts to fix an issue where we are ending
up with bad created_at date formats for last messages, which
is breaking the DM sort order and sometimes causing DM channels
to fall off the list, or show "Invalid date" on mobile.

I have not been able to consistently reproduce these issues
locally, however the serialzier for the channels index uses
MultiJSON.dump() and the Chat::Publisher uses .to_json, both of
which format created_at differently for messages.

The former is `2023-07-05T06:53:25.977Z` (iso8601).

The latter is `2023-07-14 03:59:22 UTC` (.to_s default).

Since we are doing comparison and sorting of these dates on the UI
we need consistent formatting for the JS Date parsers (and moment)
to deal with.

If the issue still occurs after this we can investigate further.
2023-07-14 16:05:01 +10:00
Joffrey JAFFEUX d7ef7b9c03
FIX: simplify channel threads lookup for pagination (#22596)
The previous query with subqueries was complicated to make right with pagination, this new query should be working correctly and is passing tests.
2023-07-13 16:44:22 +02:00
Joffrey JAFFEUX 32e32f43b5
FIX: prevents user to restore message deleted by staff (#22571)
It could only occur on message created by the user itself and deleted while the user was looking at the channel.

It more generally fix the trash service which was not correctly setting the author of the delete.
2023-07-13 10:16:15 +02:00
Joffrey JAFFEUX c996e5502f
FEATURE: enable_public_channels site setting (#22565)
`SiteSetting.enable_public_channels` allows site admin to decide if public channels are available at all. There's no distinction between admins or not as we expect admins to create private category channels if they want to limit usage.
2023-07-13 10:00:25 +02:00
Martin Brennan b1978e7ad8
DEV: Add last_message_id to channel and thread (#22488)
Initial migration and changes to models as well as
changing the following services to update last_message_id:

* Chat::MessageCreator
* Chat::RestoreMessage
* Chat::TrashMessage

The data migration will set the `last_message_id` for all existing
threads and channels in the database.

When we query the thread list as well as the channel,
we look at the last message ID for the following:

* Channel - Sorting DM channels, and channel metadata for the list of channels
* Thread - Last reply details for thread indicators and thread list
2023-07-13 10:28:11 +10:00
Roman Rizzi 61aeb2da90
FEATURE: Inline topic summary. Cached version accessible to everyone. (#22551)
* FEATURE:  Inline topic summary. Cached version accessible to everyone.

Anons and non-members of the `custom_summarization_allowed_groups_map` groups can see cached summaries for any accessible topic. After the first 12 hours and if the posts to summarize have changed, allowed users clicking on the button will automatically re-generate it.

* Ensure chat summaries work and prevent model hallucinations when there are no messages.
2023-07-12 11:21:51 -03:00
Joffrey JAFFEUX aca0bf69ef
WIP: threads list pagination (#22502)
This implementation will need more work in the future. For simplification of tracking and other events (new thread, delete/restore OM...) we used the threads from `threadsManager` which makes pagination more complicated as we already have some results when we start.

Note this commit also simplify `Collection` to only have one `load` method which can be called repeatedly.
2023-07-12 09:38:44 +02:00
Martin Brennan 3ea8203719
FIX: Track thread in UI when user sends first message (#22462)
When a user sends their first message in a thread we
automatically track the thread in the backend, but we
don't reflect this in the UI until the user re-opens
the thread. This commit fixes that by showing the new
tracking level in the UI.
2023-07-07 13:09:06 +10:00
Joffrey JAFFEUX c0808b2537
FIX: correctly makes dm creator to follow channel (#22470)
In previous changes we prevented creating a channel to also make users follow the channel. We were forcing recipients to follow the channel on message sent but this was not including the creator of the message itself.

This commit fixes it and also write an end-to-end system spec to cover these cases. The message creator service is currently being rewritten and should correctly test and ensure this logic is present.

This commit also makes changes on the frontend to instantly follow a DM when you open it, this change prevents a green dot to appear for a split second when you send a message in a channel you were previously not following. Only recipients will see the green dot.
2023-07-06 21:42:19 +02:00
Mark VanLandingham 3171fd1a0a
DEV: Introduce Chat Notices with publishing method (#22369) 2023-07-06 08:26:25 -05:00
Martin Brennan f69748e325
FIX: Mark threads read when threading enabled for a channel (#22458)
Since we create threads in the background regardless of whether
threading is enabled for a channel, we get the unexpected behaviour
of everyone having a lot of unread threads when threading is enabled
for the channel.

To counteract this, when the admin enables threads for a channel
we can just run a high priority background job to mark all threads
as read in the channel for all users, so they are essentially
starting from a clean slate.
2023-07-06 16:24:56 +10:00
Martin Brennan 37a8036b2d
FIX: Better handling of deleted thread original messages (#22402)
This commit includes several fixes and improvements to thread
original message handling:

1. When a thread's original message is deleted, the thread no longer
   counts as unread for a user
2. When a thread original message is deleted and the user is looking
   at the thread list, it will be removed from the list
3. When a thread original message is restored and the user is looking
   at the thread list, it will be added back to the list if it was
   previously loaded
2023-07-06 09:47:34 +10:00
Joffrey JAFFEUX 2ce9364c08
FIX: do not filter on category name (#22442) 2023-07-05 21:12:39 +02:00
Joffrey JAFFEUX d75d64bf16
FEATURE: new jump to channel menu (#22383)
This commit replaces two existing screens:
- draft
- channel selection modal

Main features compared to existing solutions
- features are now combined, meaning you can for example create multi users DM
- it will show users with chat disabled
- it shows unread state
- hopefully a better look/feel
- lots of small details and fixes...

Other noticeable fixes
- starting a DM with a user, even from the user card and clicking <kbd>Chat</kbd> will not show a green dot for the target user (or even the channel) until a message is actually sent
- it should almost never do a full page reload anymore

---------

Co-authored-by: Martin Brennan <mjrbrennan@gmail.com>
Co-authored-by: Jordan Vidrine <30537603+jordanvidrine@users.noreply.github.com>
Co-authored-by: chapoi <101828855+chapoi@users.noreply.github.com>
Co-authored-by: Mark VanLandingham <markvanlan@gmail.com>
2023-07-05 18:18:27 +02:00
Alan Guo Xiang Tan 1e26a521c2
FIX: Error when loading a channel with threading enabled but no threads (#22434)
Without this fix, the following error is raised:

```
ActiveRecord::StatementInvalid:
  PG::SyntaxError: ERROR:  syntax error at or near ")"
  LINE 4:   WHERE thread_id IN ()
```
2023-07-05 14:33:49 +08:00
Martin Brennan f6072ba804
DEV: Move user count update for channels to ensure_consistency! (#22321)
This fixes a longstanding TODO to move the contents of the
UpdateUserCountsForChannels job to the ensure_consistency!
method of Chat::Channel, which runs every 15 mins as part of
periodical updates.

This commit also addresses the performance issue of the original,
where we would fetch all channels and do an individual query to
get the count and update the count of each one. Now we do it all
in one query, and only publish the changed channels to the UI.
2023-07-03 11:41:51 +10:00
Martin Brennan 3f1024de76
DEV: Refactor DM channel creation into new service pattern (#22144)
This will be used when we move the channel creation for DMs
to happen when we first send a message in a DM channel to avoid
a double-request. For now we can just have a new API endpoint
for creating this that the existing frontend code can use,
that uses the new service pattern.

This also uses the new policy pattern for services where the policy
can be defined in a class so a more dynamic reason for the policy
failing can be sent to the controller.

Co-authored-by: Loïc Guitaut <loic@discourse.org>
2023-07-03 10:18:37 +10:00
Joffrey JAFFEUX ea0b8ca38c
FEATURE: allows to enable/disable threading in UI (#22307)
Enabling/Disabling threading has been possible through command line until now. This commit introduces two new UIs:

- When creating a channel, it will be available once the category has been selected
- On the settings page of a channel for admins
2023-06-29 07:19:12 +02:00
Martin Brennan 1194ed10e1
FEATURE: Track last_viewed_at datetime for channel members (#22294)
Whenever a user opens a channel or marks it read, we now
update the last_viewed_at datetime for that channel membership
record. This is so we will be able to show thread unread indicators
in the channel sidebar that clear independently of the main thread
unread indicators. This unread functionality will follow in another
PR.
2023-06-29 09:22:17 +10:00
Martin Brennan 58c8f91d9a
DEV: Use same excerpt everywhere in chat (#22319)
Followup to c6b43ce68b

We can just use the rich excerpt everywhere since we know
we don't need text_entities -- that introduced security issues
just to fix a spec.
2023-06-29 09:20:20 +10:00
Martin Brennan 41ebbab4ff
FIX: Chat threads N1 (#22322)
Followup to 1526d1f97d

This commit fixes an N1 for mentions/user status
when querying chat threads. This only happened if
any of the thread OMs had mentions.
2023-06-28 15:41:51 +10:00
Martin Brennan 1526d1f97d
FEATURE: Sort thread list by unread threads first (#22272)
* FEATURE: Sort thread list by unread threads first

This commit changes the thread list to show the threads that
have unread messages at the top of the list sorted by the
last reply date + time, then all other threads sorted by
last reply date + time.

This also fixes some issues by removing the last_reply
relationship on the thread, which did not work for complex
querying scenarios because its order would be discarded.

* FIX: Various fixes for thread list loading

* Use the channel.threadsManager and find the channel first rather
  than use activeChannel in the threads manager, otherwise we may
  be looking at differenct channels.
* Look at threadsManager directly instead of storing result for threads
  list otherwise it can get out of sync because of replace: true in
  other places we are loading threads into the store.
* Fix sorting for thread.last_reply, needed a resort.
2023-06-28 13:14:01 +10:00
Roman Rizzi f4e7a80600
DEV: Cache summarization strategy results. (#22230)
Updates the interface for implementing summarization strategies and adds a cache layer to summarize topics once.

The cache stores the final summary and each chunk used to build it, which will be useful when we have to extend or rebuild it.
2023-06-27 11:44:34 -03:00
Andrei Prigorshnev 3ea31f443c
FEATURE: Export chat messages to CSV file (#22113)
To export chat messages, go to `/admin/plugins/chat` and click the Create export 
button in the _Export chat messages_ section. You'll receive a direct message 
when the export is finished.

Currently, this exports all messages from the last 6 months, but not more than 
10000 messages.

This exports all chat messages, including messages from private channels and 
users' direct conversations. This also exports messages that were deleted.
2023-06-21 16:13:36 +04:00
Jan Cernik e51bbfa4e8
FEATURE: Scroll to first message when clicking date in chat (#21926)
This PR adds a new parameter to fetch chat messages: `target_date`.

It can be used to fetch messages by a specific date string. Note that it does not need to be the `created_at` date of an existing message, it can be any date. Similar to `target_message_id`, it retrieves an array of past and future messages following the query limits.
2023-06-20 15:58:38 +02:00
Martin Brennan d6374fdc53
FEATURE: Allow users to manually track threads without replying (#22100)
This commit adds a tracking dropdown to each individual thread, similar to topics,
that allows the user to change the notification level for a thread manually. Previously
the user had to reply to a thread to track it and see unread indicators.

Since the user can now manually track threads, the thread index has also been changed
to only show threads that the user is a member of, rather than threads that they had sent
messages in.

Unread indicators also respect the notification level -- Normal level thread tracking
will not show unread indicators in the UI when new messages are sent in the thread.
2023-06-16 12:08:26 +10:00
Martin Brennan f75ac9da30
FEATURE: Thread indicator improvements and participants (#21909)
This commit adds the initial part of thread indicator improvements:

* Show the reply count, last reply date and excerpt,
and the participants of the thread's avatars and
count of additional participants
* Add a participants component for the thread that
can be reused for the list
* Add a query class to get the thread participants
* Live update the thread indicator more consistently
with the last reply and participant details
image image

In subsequent PRs we will cache the participants since
they do not change often, and improve the thread list
further with participants.

This commit also adds a showPresence boolean (default
true) to ChatUserAvatar, since we don't want to show the
online indicator for thread participants.

---------

Co-authored-by: chapoi <charlie@discourse.org>
2023-06-15 10:49:27 +10:00
Joffrey JAFFEUX 5a035e2f5d
PERF: fixes multiple N+1 while loading threads (#22106) 2023-06-14 13:51:52 +02:00
Martin Brennan cb87ef52de
FIX: Backfill chat thread memberships (#21971)
Since we created user_chat_thread_memberships in
cc2570f we haven't
yet backfilled it for users who previously sent a message in
in threads -- this migration creates the UserChatThreadMemberships
needed for those threads, making sure the last read message id
is accurate for those participants.
2023-06-14 13:54:51 +10:00
Roman Rizzi 8938ecabc2
FEATURE: Custom content summarization strategies. (#21813)
* FEATURE: Content custom summarization strategies.

This PR establishes a pattern for plugins to register alternative ways of summarizing content by extending a class that defines an interface.

Core controls which strategy we'll use and who has access to it through the `summarization_strategy` and `custom_summarization_allowed_groups`. It also defines the UI for summarizing topics.

Other plugins can access this summarization mechanism and implement their features, removing cross-plugin customizations, as it currently happens between chat and the discourse-ai plugin.

* Group membership validation and rate limiting

* Work with objects instead of classes

* Port summarization feature from discourse-ai to chat

* Rename available summaries to 'Top Replies' and 'Summary'
2023-06-13 14:21:46 -03:00
Martin Brennan 482ef0782d
FIX: Do not allow blank chat messages (#21968)
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.
2023-06-08 16:06:09 +10:00
Joffrey JAFFEUX 6c3a51328c
FIX: removes destroyed mentioned used (#21841)
This would generate a 500 as we would call id on a nil object.
2023-05-31 00:21:09 +02:00
Joffrey JAFFEUX 111ac4c7f2
FIX: call composer reset with correct params (#21777)
We were calling reset without the proper params which was causing errors in the console. This commit does the following changes:

- ensures `composer.cancel()` is the only way to cancel editing/reply
- adds a `draftSaved` property to chat message to allow for better tests
- writes a spec to ensure the flow is correct
- adds more page objects for better tests
- homogenize the default state of objects on chat message

Co-authored-by: Martin Brennan <martin@discourse.org>
2023-05-30 18:37:30 +02:00
Martin Brennan c57ae992b3
FIX: Page size edge case for null last_read_message_id (#21811)
Followup 55ef2d0698.

In the cases where the user has no last_read_message_id for
a channel, we want to make sure that a page_size is set for
the ChannelViewBuilder + MessagesQuery, otherwise we end up
loading way more messages than needed (the additional message
loading was fixed in the last commit).
2023-05-29 20:12:01 +02:00
Joffrey JAFFEUX 55ef2d0698
FIX: auto fill was not happening on first load (#21809)
This commit attempts to fix the case where the messages loaded initially don't fill the screen. It would prevent user to scroll and as a result to load more.

There are multiple fixes in this commit:
- the main fix is removing this code which was preventing the actual fill:

```javascript
        // prevents an edge case where user clicks bottom arrow
        // just after scrolling to top
        if (loadingPast && this.#isAtBottom()) {
          return;
        }
```

- ensures we always give a page site to the `chatApi.channel(...)` call if we have one, in the current state when `fetchFromLastRead` was `true` we would not set `args.page_size`
- ensures the `query_paginated_messages` is having a valid page size, which is not nil and not > `MAX_PAGE_SIZE`
- write a spec for the autofill, it was a challenging spec to write but it should give us the confidence we need here
2023-05-29 17:34:44 +02:00
Martin Brennan 6ddd17a756
DEV: Remove old ChatController routes for messages & lookup (#21723)
Since 5cce829 and the new
channel view builder, we have no need of these obsolete
routes which have way too much logic in the controller, which
has been superseded by the view builder anyway.

Remove the routes and update the channel message loading to use it.
2023-05-29 09:37:10 +02:00
Martin Brennan 7a9514922b
FEATURE: Improving thread list item and header (#21749)
* Moved the settings cog from thread list to thread and
  put it in a new header component
* Remove thread original message component, no longer needed
  and the list item and thread indicator styles/content
  will be quite different
* Start adding content (unread indicator etc.) to the thread
  list item and changing structure to be more like designs
* Serialize the last thread reply when opening the thread index,
  show in list and update with message bus
2023-05-29 09:11:55 +02:00
Joffrey JAFFEUX acb4c19eea
PERF: sends publish_new_channel only when not followed (#21755) 2023-05-26 17:13:05 +02:00
Martin Brennan 594636183d
FIX: N+1 query for chat message serializer on mentions (#21767)
Followup to d4a5b79592,
this introduced an N1 because every message in the list
we had to query users for the mentions and then the user's
status too. Instead we can just include both in Chat::MessagesQuery.
2023-05-26 12:44:03 +02:00
Martin Brennan 39d213a023
DEV: Add explicit order for chat mentioned users (#21765)
Followup d4a5b79592
which could sometimes flake on tests due to ordering issues.
2023-05-26 11:47:55 +02:00
Martin Brennan ae74d5b32e
FIX: Chat deleted last read message and tracking state issues (#21762)
#### FIX: Do not use client lastReadMessageId when fetching channel messages

We had an issue where the following happened:

1. User opened channel and saw the last message, and we set the
   lastReadMessageId on the server and the client
2. User navigated to another channel
3. Another user deleted the message in the original channel
4. The first user navigated back to the original channel before
   the MessageBus event for the deleted message arrived, and got
   a 404 error because we were sending the deleted lastReadMessageId as
   target_message_id to the channel controller.

Instead of this which is a bit flaky and is hard to cover all
the issues for, instead we can pass a fetch_from_last_read boolean
param to the channels controller, and just get the user's
last_read_message_id straight from the database to use for the
target_message_id. This gets rid of any sources of race conditions
or lack of updates from MessageBus.

#### FIX: Include missing memberships for thread tracking publish

When we publish the channel/message tracking state for a
user and that message was a thread reply the publisher
was erroring because we were not telling Chat::TrackingStateReportQuery
to return missing memberships (which have zeroed out unread counts)
as well, which is what we do for the channel tracking state here.
Also just make sure that the TrackingStateReport does not error
when passed an ID it doesn't have data for.
2023-05-26 10:44:27 +02:00
Martin Brennan c3779a371f
FIX: Serialize thread membership for user (#21743)
This commit follows up b6c5a2da08
by serializing the user's thread memberships in these cases:

1. When we do the initial channel fetch with messages, we get
   all threads and all the user's thread memberships for those
   messages.
2. When the thread list is fetched, we get all the user's memberships
   in that list.
3. When the single thread is fetched, either from opening it from
   the list, an OM indicator, or just from doing .find() on the
   manager when a new MessageBus message comes in

This will let us track the lastReadMessageId on the client, and
will also let us fix an issue where the unread indicator in the
channel header was incrementing for every thread that got a
new message, regardless of whether the user was a member.
2023-05-25 12:54:50 +02:00
Loïc Guitaut 0733dda1cb DEV: Add policy objects to services
This patch introduces policy objects to chat services. It allows putting
more complex logic in a dedicated class, which will make services
thinner. It also allows providing a reason why the policy failed.

Some change has been made to the service runner too to use more easily
these new policy objects: when matching a failing policy (or any failing
step actually), the result object is now provided to the block. This
way, instead of having to access the reason why the policy failed by
doing `result["result.policy.policy_name"].reason` inside the block,
this one can be simply written like this:
```ruby
  on_failed_policy(:policy_name) { |policy| policy.reason }
```
2023-05-25 12:34:00 +02:00
Martin Brennan b6c5a2da08
FEATURE: Initial chat thread unread indicators (#21694)
This commit adds the thread index and individual thread
in the index list unread indicators, and wires up the message
bus events to mark the threads as read/unread when:

1. People send a new message in the thread
2. The user marks a thread as read

There are several hacky parts and TODOs to cover before
this is more functional:

1. We need to flesh out the thread scrolling and message
   visibility behaviour. Currently if you scroll to the end
   of the thread it will just mark the whole thread read
   unconditionally.
2. We need to send down the thread current user membership
   along with the last read message ID to the client and
   update that with read state.
3. We need to handle the sidebar unread dot for when threads
   are unread in the channel and clear it based on when the
   channel was last viewed.
4. We need to show some indicator of thread unreads on the
   thread indicators on original messages.
5. UI improvements to make the experience nicer and more
   like the actual design rather than just placeholders.

But, the basic premise around incrementing/decrementing the
thread overview count and showing which thread is unread
in the list is working as intended.
2023-05-25 09:56:19 +02:00
Andrei Prigorshnev d4a5b79592
FEATURE: Add user status to inline mentions in chat (#20564)
This PR adds status to mentions in chat and makes those mentions receive live updates.

There are known unfinished part in this implementation: when posting a message, status on mentions on that message appears immediately, but only if a user used autocomplete when typing the message. If user copy and paste a message with mentions into chat composer, those mentions won't have user status on them.

PRs with fixes for both problems are following soon.

Preparations for this PR that were made previously include:
- DEV: correct a relationship – a chat message may have several mentions 0dcfd7ddec
- DEV: extract the logic for extracting and expanding mentions from ChatNotifier 75b81b6854
- DEV: Always create chat mention records fa543cda06
- DEV: better split create_notification! and send_notifications logic e292c45924
- DEV: more tests for mentions when updating chat messages e7292e1682
- DEV: extract updating status on mentions into a lib function e49d338c21
- DEV: Create and update chat message mentions earlier 35a414bb38
- DEV: Create a chat_mention record when self mentioning 2703f2311a
- DEV: When deleting a chat message, do not delete mention records f4fde4e49b
2023-05-24 16:55:20 +04:00
Jan Cernik 436b68a581
FIX: Do not preview chat channels to read-only users (#21700)
We want to simplify this case as it contains a lot of rabbit holes.
2023-05-24 14:05:20 +02:00
Martin Brennan 2b4dc97551
FIX: Do not error if admin/owner checks target message (#21721)
In the ChannelViewBuilder, we introduced a check to see if
the target message exists, which errors if the message has
been trashed. However if the user is the creator of the message
or admin then they are able to see trashed messages, so
we need to take this into account.
2023-05-24 12:01:41 +02:00
Martin Brennan 177d8dfcd1
FIX: Improve chat membership update on deleted message (#21716)
Followup to c908eeacc9

Instead of using the latest message ID in the channel, which
could cause issues if you have an earlier last read message ID
that matches the deleted one, instead we use the first non-deleted
message that comes before the deleted message by ID.
2023-05-24 10:31:15 +02:00