Commit Graph

503 Commits

Author SHA1 Message Date
Joffrey JAFFEUX
79a260a6bb
FIX: allows selection of messages in threads (#22119)
This commit fixes the selection of message in threads and also applies various refactorings
- improves specs and especially page objects/components
- makes the channel/thread panes responsible of the state
- adds an animationend modifier
- continues to follow the logic of "state" should be displayed as data attributes on component by having a new `data-selected` attribute on chat messages
2023-06-15 11:27:31 +02: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
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
chapoi
fca6c1836c
UX: Chat unread indicator refactor (#22040)
* move the chat unread indicator to top to match the profile avatar indicator
* add white border to profile avatar indicator (badge notification) to match chat indicator and userstatus styling
* change `.urgent` to BEM
* congregate all styling into mixin
  * update chat index to use mixin
  * update thread indicator to use mixin
  * update header indicator to use mixin

---------

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
Co-authored-by: Martin Brennan <martin@discourse.org>
2023-06-12 14:33:45 +10:00
Joffrey JAFFEUX
bf07845714
PERF: drop throttling from resize node (#22046)
This is actually making things more sluggish than necessary. If any perf issue happen out of this they should be handled in the consequences of the resizing, not the resizing itself.
2023-06-09 20:30:41 +02:00
Joffrey JAFFEUX
99f0ace229
DEV: implements styleguide for chat header icon (#22033)
This commit also uses this opportunity to change component name from: `ChatHeaderIcon` to `Chat::Header::Icon`
2023-06-09 18:40:34 +02:00
Joffrey JAFFEUX
41fb88c7e0
FIX: scroll top after chat activation (#21952)
Currently navigating a long topic and then opening chat would cause the view to be scrolled to the bottom. Using `scrollTop` here ensures we correctly scroll to top.

This had been incorrectly moved into `deactivate` during another change.
2023-06-09 17:51:35 +02:00
Joffrey JAFFEUX
89d7b1861d
FIX: various mobile optimizations (#22043)
* FIX: increases resize observer throttle delay
25ms is not necessary and was sometimes causing jankyness.

* FIX: removes ios momentum fix delay
Instead of a 50ms, simply use next+schedule("afterRender") to attempt to have the shortest delay possible.

* FIX: backdrop event propagation
Prevents backdrop touch to propagate to underlying channel/thread.

* UX: adds is-active class to container of active message
This change allows to keep the background on the active message while the actions menu is displayed.

* FIX: prevents skip-link to be selected on press

* UX: allows to close actions menu instantly
The backdrop should always receive events, we don't need to wait for the menu to be fully displayed.

* UI: adds spacing between last message and composer

* UI: makes backdrop less dark

* FIX: makes events passive on long-press modifier
2023-06-09 17:37:26 +02:00
Joffrey JAFFEUX
dbf3ff1738
FIX: correctly re-conciliate message bus backlog (#22020)
We have been struggling a lot on this lately as it's almost impossible to write a decent test for this.

The important things which need to happen:
- fetch the unread/mention state and last message bus channel ids of each chat channels
- stop all subscriptions
- restart global chat subscriptions
- update channels with new state and ensure the message bus ids are updated
- restart subscriptions of each chat channel

As a followup we need to start implementing a standard way to query for a resource state. Something similar to: `/channels/tracking` and `/channels/:id/tracking`

Each of these endpoints would return a state similar to:

```json
{
  tracking: { ... },
  message_bus_ids: { ... }
}
2023-06-09 09:00:24 +02:00
Joffrey JAFFEUX
17e81018a2
FIX: prevents long press to hijack reaction event (#22021)
Removing a reaction could start a long press at the same time and put the screen in a stuck state.

This commit ensures we give an opportunity to the reaction to capture the event first and not propagate further.
2023-06-09 00:39:34 +02:00
Joffrey JAFFEUX
aa2270e4c3
FIX: disables pointer events while showing menu (#22009)
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.
2023-06-08 19:35:08 +02:00
Sérgio Saquetim
e306a521fd
DEV: Added chat api to remove secondary actions (#21982)
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>
2023-06-08 11:37:50 -03:00
Andrei Prigorshnev
c0d3cded73
DEV: refactor calls to message.cook when sending messages (#21934)
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.
2023-06-08 18:21:22 +04:00
Joffrey JAFFEUX
9cbbcdef50
FIX: prevents lightbox to close chat on escape (#22003)
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.
2023-06-08 15:32:35 +02:00
Joffrey JAFFEUX
32dd43e02c
REVERT: makes touchstart passive (#22004)
This is causing issues with scroll, I need to find a different issue for the event propagating as a click.
2023-06-08 15:31:49 +02:00
Joffrey JAFFEUX
57877fd6db
FIX: on iOS PWA prevents touch to click (#22000)
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.
2023-06-08 14:38:08 +02:00
Joffrey JAFFEUX
65d61b87c1
FIX: prevents back history loop (#22001)
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.
2023-06-08 14:35:29 +02:00
Joffrey JAFFEUX
6513ca69da
UX: improves chat message long press and touch (#21984)
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
2023-06-08 08:21:32 +02:00
Martin Brennan
e48750281e
FIX: Pasting files into chat was not working (#21995)
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.
2023-06-08 13:03:55 +10:00
Joffrey JAFFEUX
699f3e7014
FIX: correctly set value on textarea interactor (#21990)
This would mostly work without it by mutation but could cause subtle bugs.
2023-06-08 01:21:30 +02:00
Joffrey JAFFEUX
e6c6c342d9
REFACTOR: composer/thread (#21910)
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
2023-06-07 21:49:15 +02:00
Joffrey JAFFEUX
330137e7e4
FIX: Non-Interfering Backdrop Clicks (#21916)
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.
2023-06-07 11:40:43 +02:00
chapoi
9809103ed9
UX: fix number cutoff in header chat indicator (#21946)
In the chat header indicator, expand to a pill when the number reaches
N digits, and also display 99+ if the number is over 99.
2023-06-07 11:42:08 +10:00
Martin Brennan
69eecf92d0
FIX: Use a default hashtag icon color for user with no permission (#21825)
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.
2023-06-07 10:15:39 +10:00
Andrei Prigorshnev
b7a66bd6ad
DEV: Use await when sending chat messages (#21915)
This is a follow-up to d086888, I forgot to update these places in that commit.
2023-06-06 13:58:15 +04:00
Joffrey JAFFEUX
95a51b7d8a
FIX: correctly set last message bus ids on resync (#21911)
Replaces `channel.meta.message_bust_last_ids` on full resync instead of restarting the subscriptions, which was moreover not using a correct id.
2023-06-02 18:06:13 +02:00
chapoi
d40649c648
UX: chat channel header icons (#21887)
* UX: BEM fix for has-unreads

* UX: small refactor for chat channel header icons

* UX: refactor chat thread unread indicator

* UX: channel header thread icon hover styling

* DEV: Spec fixes

* UX: fix font + line-height

---------

Co-authored-by: Martin Brennan <martin@discourse.org>
2023-06-02 10:34:19 +02:00
Joffrey JAFFEUX
676b558265
FIX: correctly resubscribe after restart (#21891)
Few weeks ago we implemented `onPresenceChangeCallback` to re-sync chat channels state when going back to a long time inactive tab. This codepath however contained a bug as we were reseting all subscriptions but only restarting global subscriptions and not per channel subscriptions.

This commit should correctly ensure we correctly do so. It's sadly very hard to test time related changes in system specs.

Co-authored-by: Martin Brennan <mjrbrennan@gmail.com>
2023-06-01 19:00:54 +02:00
Andrei Prigorshnev
bb21476f68
FIX: Do not add mentioned groups as mentioned users (#21867)
When a user type a message with mentions, the autocomplete popup 
may suggest users or groups. We were adding all these object to 
the `currentMessage.mentionedUsers` collection, while we should 
have been adding only users. A group added to that collection led to 
the error later when trying to update user status on mentions.
2023-06-01 15:55:59 +04:00
Andrei Prigorshnev
d086888549
DEV: Make chatMessage.cook function async (#21829)
This will make it simpler to work with this code. This also can make this code more stable and increase stability of our test suite.

Cooked message now will be available immediately after cooking, it wasn't the case before:

    await message.cook();
    const cooked = message.cooked;


This also removes a call to `message.cook()` from message fabricator. Alternatively we may leave the call there and make the fabricator function async, but I fill it's better this way. If someone needs to test something related to cooked message, they can either pass cooked text to fabricator:

    message = fabricators.message({ cooked: "<p>cooked</p>" });

or call `message.cook()` after fabrication:

    message = fabricators.message({ message: "raw message" });
    await message.cook()
2023-06-01 13:39:32 +04:00
chapoi
1f37fe5fa5
UX: chat composer buttons refactor + emoji (#21852)
- Made the emoji btn blue when composer is focused
- Moved everything chat-composer-button to its own file and BEM-ified it and making the choice to only work with our own is-disabled definition instead of with the attribute :disabled, for consistency
2023-05-31 15:12:35 +02:00
Joffrey JAFFEUX
80c18b97b4
FIX: uses DiscourseURL.routeTo for drawer transitions (#21850)
Calling `transitionTo` directly was bypassing various custom codepaths of core.
2023-05-31 10:44:26 +02:00
Joffrey JAFFEUX
473992bd36
DEV: introduces Chat::Thread::ListItem in styleguide (#21851) 2023-05-31 10:29:38 +02:00
Joffrey JAFFEUX
7c4d229f37
FIX: applies getURL on both app and chat URLs (#21847) 2023-05-31 01:30:54 +02:00
Joffrey JAFFEUX
852086e888
FIX: correctly uses getURL to open full page (#21843) 2023-05-31 00:52:27 +02:00
Joffrey JAFFEUX
906e053f32
FIX: recover by showing drawer index on 404 (#21839)
If the drawer receives an unexpected route, attempt to show the index. This is probably a more serious issue with subfolder but should limit the effects.
2023-05-30 23:51:55 +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
Joffrey JAFFEUX
67102f7e4e
UX: deletes a message when editing to blank (#21785)
Editing a message to an empty string and sending it, will delete it.

This commit also refactors a lot of channel/thread composer shortcuts specs.

---

This commit also includes various spec fixes which have been flakey while finishing this pull request.
2023-05-30 18:15:34 +02:00
Martin Brennan
6ec6cfccf8
FEATURE: Chat thread header indicator improvements (#21807)
This changes the thread header positioning of the
unread indicator to match the designs based on the route:

1. When the channel is open, show the indicator of # unread
   threads with the icon
2. When the threads list is open, show no indicator since
   you are on the list and can see which threads are unread
3. When a single thread is open, show the unread threads
   indicator along with a left < back button, with a label
   to show that this goes back to ongoing discussions

Drawer changes to come in another PR.
2023-05-30 10:10:07 +02:00
Joffrey JAFFEUX
4ce8ea7496
DEV: adds sendChatMessage client API (#21783)
Usage:

```
api.sendChatMessage(channelId, message, { threadId: 6 });
```
2023-05-29 18:41:12 +02:00
Alan Guo Xiang Tan
7218da7510
DEV: Fix and improve chat system test for editing name and slug (#21810)
This commit introduces a couple of changes:

1. When editing a chat channel's slug, we were using `this.model.set("title", title)` when the `set`
   function does not exist. This was actually throwing the error in the
   "can edit slug" system test where the modal was not closed after
   saving and was flashing an error.

2. Introduce `PageObjects::Pages::ChatChannelAbout` and
   `PageObjects::Modals::ChatChannelEdit` page object to encapsulate
   logic better.
2023-05-29 18:00:59 +02:00
Martin Brennan
72e46b98a9
FIX: Create original message user thread membership (#21808)
When a thread is created / a new message is created in the
thread, we want to make sure that the original message user
has a membership for that thread, otherwise they will not
receive unread indicators for messages in the thread.
2023-05-29 17:37:17 +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
chapoi
5bf2dca24a
UX: add support for flagged chat message in reviewqueue (#21802)
* UX: add support for flagged chat message in reviewqueue

* correctly init a chat message object

---------

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2023-05-29 10:02:02 +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
Martin Brennan
e4d628a931
FIX: Move thread storage out of chatApi.thread() call (#21773)
In some cases activeChannel can be null so this will error,
also it is limiting to have this code in chatApi. Instead
move to the threads manager, and also lean on channelsManager.find
to get the channel from the cache instead, which will not error.
2023-05-27 09:43:29 +02:00
Joffrey JAFFEUX
d1f785e7de
UX: closes drawer on esc if input is not focused (#21772)
The current behavior is to close drawer when pressing escape inside the input.

After this change, first escape will blur the input, and second escape will close the drawer.

This commit also refactors the whole shortcuts for drawer system spec.
2023-05-26 18:48:45 +02:00
Joffrey JAFFEUX
4676524094
FIX: do not attempt to mark as read a staged message (#21764)
This has not much impact as it would just be a silent 404 server side, but this is unnecessary work.
2023-05-26 11:00:48 +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
Jarek Radosz
22a6ae7e32
DEV: Remove renderTemplate from the styleguide (#21660)
Adds plugin API:

```js
import fidget from "../components/styleguide/molecules/fidget";

api.addStyleguideSection({
  component: fidget,
  id: "fidget",
  category: "molecules",
  priority: 0,
});
```

Removes notes. You can always add `<p class="styleguide-note">` to section components to annotate them.
2023-05-25 11:22:36 +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
Joffrey JAFFEUX
eae47d82e2
FEATURE: Apply hashtag styles to autocomplete (#21731)
This commit uses improvements done in 0b3cf83 to apply these styles to the autocomplete in composer.
2023-05-25 09:38:12 +02:00
Joffrey JAFFEUX
398eaf0429
FIX: prevents saving draft in incorrect channel (#21741)
This commit regroups 3 changes
- serializes channel ID and json draft when calling the debouncer instead of inside the debounced function, it seems very unlikely to happen, but in a case where the debouncing wouldn't be canceled and the new message not set yet, we could save the draft on an invalid channel
- cancel persist draft handler when changing channel
- ensures we exit early when channel is not set
2023-05-25 09:29:31 +02:00
Joffrey JAFFEUX
082921c4c8
FIX: correctly nullifies active message (#21739)
Very fast or specific mouse moves could allow to leave a message actions menu without reseting the active message. This commit should ensure we correctly catch this event.

No test as it's hard and not reliable to reproduce these in a test.
2023-05-25 09:28:46 +02:00
Joffrey JAFFEUX
f3f841a018
DEV: implements initial messages component (#21727)
This should also make `message_notifications_with_sidebar_spec.rb` more resilient as we are now checking for `is-persisted` class instead of checking for the absence of `is-staged`.
2023-05-24 19:28:54 +02:00
Joffrey JAFFEUX
4de1d3952b
FIX: improves draft for channels (#21724)
This commit attempts to correctly change draft when the channel changes. It moves responsibility to the composer instead of the channel.

A new service `chatDraftsManager` is being introduced here to allow finer control and pave the way for future thread draft support.

These changes also now allow an editing message to be stored as a draft.
2023-05-24 15:36:46 +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
Joffrey JAFFEUX
68364461f8
FIX: ensure sidepanel size is correctly applied when showing (#21701)
We were not correctly setting the widthStyle on insert.

Note this commit also changes throttling from 24ms to 50ms. 24ms was probably overkill.
2023-05-23 20:13:58 +02:00
Martin Brennan
c908eeacc9
FIX: Update client lastReadMessageId on trashed message (#21697)
Followup ae3231e140, when a
message is trashed we already update the lastReadMessageId of
all users in the channel to the latest non-deleted message on
the server side. However we didn't propagate this to the client,
so in some cases when we did the following:

1. Delete the last message in the channel
2. Switch to another channel
3. Switch back to the original

We would get a 404 error from the target message ID being looked
up still being the old lastReadMessageId (now deleted) for the
user's channel membership.

All we need to do is send the last not-deleted message ID for
the channel (or thread) to all the member users.
2023-05-23 18:32:19 +02:00
Joffrey JAFFEUX
bce56d843c
FIX: keeps panel size when changing content (#21698)
Before this commit the following actions would have shown the issue:
- visit a thread
- changes the width of the side panel
- open threads list
- the size has reverted to previous state

This was caused by the width change to not correctly be tracked.
2023-05-23 18:29:12 +02:00
Joffrey JAFFEUX
2a7dae51fa
DEV: attempts to make deleted spec not flakey (#21695)
It easier to check for presence in this case that to check for something not present, as depending on performance of the machine running the test this could take sometime to be changed and the test would fail.
2023-05-23 17:13:12 +02:00
Joffrey JAFFEUX
0764dc3452
FIX: cancel fetching messages after channel change (#21689)
This issue was especially visible in tests. the `@debounce(100)` was not cancelled when changing channel which was causing 404s as we were trying to load messages on a channel which was deleted as the channel has been destroyed at the end of the test.

This is still not a perfect solution, as we can only cancel the start of `fetchMessages`, but we can't cancel the actual `chatApi.channel` request which result can potentially happens after channel changed, which we try to mitigate with various checks on to ensure visible channel == loaded messages channel.

This commit also tries to make handler naming and cancelling more consistent.

<!-- 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-05-23 16:01:47 +02:00
Martin Brennan
dad6b61807
DEV: Bump thread page size to 100 (#21691)
We don't have proper pagination yet so this
should help us in the interim.
2023-05-23 10:43:39 +02:00
Joffrey JAFFEUX
b8bd3b07ef
DEV: regroups composer button code (#21690)
This commit makes it easier to ensure each button have a similar behavior: hover, disabled, focus...

It also removes some dead code (__inline-button) and fixes a bug where the emoji button didnt have the right un-focused color (it was more visible than it should.
2023-05-23 10:12:03 +02:00
Martin Brennan
0b3cf83e3c
FIX: Do not cook icon with hashtags (#21676)
This commit makes some fundamental changes to how hashtag cooking and
icon generation works in the new experimental hashtag autocomplete mode.
Previously we cooked the appropriate SVG icon with the cooked hashtag,
though this has proved inflexible especially for theming purposes.

Instead, we now cook a data-ID attribute with the hashtag and add a new
span as an icon placeholder. This is replaced on the client side with an
icon (or a square span in the case of categories) on the client side via
the decorateCooked API for posts and chat messages.

This client side logic uses the generated hashtag, category, and channel
CSS classes added in a previous commit.

This is missing changes to the sidebar to use the new generated CSS
classes and also colors and the split square for categories in the
hashtag autocomplete menu -- I will tackle this in a separate PR so it
is clearer.
2023-05-23 09:33:55 +02:00
Joffrey JAFFEUX
bdfd80bfe0
UI: chat composer step 2 (#21641)
- few improved alignments
- displays emoji picker button inline on desktop
- keeps composer focused when focusing dropdown button
- align buttons to bottom when increasing height of textarea
- max-height of textarea is now linked to the height of the screen

Co-authored-by: chapoi <charlie@discourse.org>
2023-05-22 17:00:50 +02:00
Martin Brennan
5cce829901
DEV: Chat API channel#show changes for threading (#21632)
This commit moves message lookup and querying to the
/chat/api/channel/:id endpoint and adds the ability
to query the tracking state overview for threads as well
as the threads and thread tracking state for any thread
original messages found.

This will allow us to get an initial overview of thread
tracking for a user when they first enter a channel, rather
than pre-emptively loading N threads and tracking state
for those across all channels on the current user serializer,
which would be expensive.

This initial overview will be used in subsequent PRs to
flesh out the thread unread indicators in the UI.

This also moves many chunks of code that were in services
to reusable Query classes, since use of services inside
services is discouraged.
2023-05-22 13:59:46 +02:00
chapoi
4f8dbe345f
UX: add indicator for msg from currentUser (#21657)
* UX: add indicator for msg from currentUser

* move up a level
2023-05-19 11:33:56 +02:00
Jarek Radosz
f2339d2d5b
DEV: Fix random typos (#21638) 2023-05-18 15:34:46 +02:00
Joffrey JAFFEUX
c1d3a6a205
FIX: ensures message has been added before scroll (#21636)
Wrap scroll to bottom inside a next block to ensure the message has correctly been added to the array before actually attempt to scroll.

This commit also removes an unnecessary line which was essentially adding the message two times with no real consequences as we are uniq on ID.
2023-05-18 13:50:09 +02:00
Andrei Prigorshnev
20a7192b4e
DEV: Avoid infinite calling of computeDatesSeparators() (#21616) 2023-05-18 09:53:40 +02:00
Joffrey JAFFEUX
4c4401b726
FIX: various fixes to chat styleguide (#21617)
- uses current user as user for fabricators, allows for correct avatar image and presence indicator
- uses a non existing channel ID to avoid setting a draft of an existing channel
- attempts to make color toggle more reliable
2023-05-17 20:03:19 +02:00
Joffrey JAFFEUX
0c1efecddd
FIX: more resilient bottom of message check (#21613)
1.0 lenience might not be enough in rare cases and there are no real consequences to slightly increase it.
2023-05-17 18:05:18 +02:00
Joffrey JAFFEUX
60c67afba4
DEV: various improvements to devex on chat (#21612)
- Improves styleguide support
- Adds toggle color scheme to styleguide
- Adds properties mutators to styleguide
- Attempts to quit a session as soon as done with it in system specs, this should at least free resources faster
- Refactors fabricators to simplify them
- Adds more fabricators (uploads for example)
- Starts implementing components pattern in system specs
- Uses Chat::Message creator to create messages in system specs, this should help to have more real specs as the side effects should now happen
2023-05-17 17:49:52 +02:00
Martin Brennan
009006893e
FIX: Sync channel tracking state properly on presence change (#21596)
Followup from 9953a6edd9,
which broke an issue fixed in e8d6277062.

In the refactor we did not update the place where we resync
channel tracking based on onPresenceChange to use the new
tracking object we added to the serializer, and to directly
update channel.tracking
2023-05-16 21:37:51 +02:00
Joffrey JAFFEUX
f45d1e6791
UX: implements new composer design (#21588)
This is only the first steps of a redesign

- redesigns the buttons to have a larger hitzone
- generally bigger composer
- clicking near textarea focuses the input
- relies on the fact that safe-area-inset-bottom is set globally and doesn’t need to be set in sub components
2023-05-16 17:17:12 +02:00
Martin Brennan
9953a6edd9
DEV: Rearchitect chat tracking state (#21550)
This moves chat tracking state calculation for channels
and threads into a central Chat::TrackingStateManager service, that
serves a similar purpose to the TopicTrackingState model
in core.

This service calls down to these query classes:

* ThreadUnreadsQuery
* ChannelUnreadsQuery

To get the unread_count and mention_count for the appropriate
channels and threads.

As well as this, this commit refactors the client-side chat
tracking state.

Now, there is a central ChatTrackingStateManager Ember Service
so all tracking is accessible and can be counted from one place,
which can also initialize tracking from an initial payload.

The actual tracking counts are now maintained in a ChatTrackingState
class that is initialized on the `.tracking` property of both channel and
thread objects.

This removes the attributes on UserChatChannelMembership and decoration
of said membership from ChannelFetcher, preferring instead to have an additional
object for tracking in the JSON.
2023-05-16 14:51:13 +02:00
Martin Brennan
a2b12b6ace
FIX: Drawer styles for chat thread icon (#21577)
The spacing was not correct for this icon
in the drawer.
2023-05-16 12:49:19 +02:00
chapoi
7032733f10
FIX: Add new chat threads icon and move thread list button to right (#21575)
* DEV: add new thread icon

* FIX: Use new thread icon, fix typo in SVG

UX: move the thread list icon to the right of
the collapse button

---------

Co-authored-by: Martin Brennan <martin@discourse.org>
2023-05-16 11:48:01 +02:00
Joffrey JAFFEUX
a3522a5937
FIX: chat height fixes (#21561)
- Correctly resize when sending a message on android
- Do not blur active element
- Update direct message creator height following changes
2023-05-15 22:00:03 +02:00
Joffrey JAFFEUX
5ce0697348
FIX: limits max height to viewport on channel only (#21539)
Before this commit chat was applying a fixed height on everything under the `/chat` route. It's only really needed on the channel page with the composer at the bottom of the page.

This commits makes the following changes:
- moves height limitation from `#main-outlet-wrapper` to `.chat-channel`
- makes browse channel page and members list page full height and rely on main document scrollbar
- adds height computation for draft header and direct message creator block to ensure the height is correct when creating a draft channel
- makes chat index full height to rely on the browser scrollbar. As a result the <kbd> + </kbd> button used on mobile to create a direct message as been moved out of `<ChannelsList>` into the chat index template
- sidebar height was relying on chat setting a max height, as a result the height computation of sidebar has been changed to work correctly, especially with an opened keyboard on mobile or ipad
2023-05-15 11:46:33 +02:00
Joffrey JAFFEUX
c8eb1a275c
UX: opens side panel early to avoid jitter (#21516)
Hard to write a test for this behavior, this is a micro optimisation which doesn’t change the behavior but only makes it smoother by happening right before async request.
2023-05-15 08:14:50 +02:00
Joffrey JAFFEUX
3f2c16a8d7
FIX: do not set VH while zooming (#21538)
This was an optimisation I mistakenly removed from 4cfa78c3f3
2023-05-13 17:39:24 +02:00
Joffrey JAFFEUX
4cfa78c3f3
FIX: always listen on window resize (#21536)
When using `navigator.virtualKeyboard.overlaysContent = false` we can rely on using only the resize event. Also attempts to no over trigger `setProperty` when value didn't change.
2023-05-13 15:39:46 +02:00
Joffrey JAFFEUX
f20be4b092
FIX: prevents subscribing with an old id (#21509)
This issue was for example possibly causing the last visit indicator to be reset by `sent` messages events.

The following was happening:
- a user (bob) had a last message bus ID of 1 on a channel (id:1) subscription
- bob then go to another channel (id:2), unsubscribing from updates of channel (id:1)
- another user (laura) then send messages to channel (id:1)
- bob goes back to channel (id:1)

At this point we we doing in the same sequence:
- loading channel with messages, getting a new last message bus id
- subscribing to updates using the last known message bus id

Most of the times we were lucky enough for this to work (no events while away, or just got the new id in time...) but it was also very likely to do a double fetch of messages as MessageBus would think we were late.
2023-05-11 22:27:48 +02:00
Joffrey JAFFEUX
e905de66ff
FIX: close panel earlier (#21512)
deactivate was happening too late and sometimes after we did reopen for next panel causing the panel to stay effectively closed
2023-05-11 21:15:31 +02:00
Joffrey JAFFEUX
92bb845db2
FIX: messages selection with shift + click (#21506)
This commit fixes the shift+click multi selection in threads. We were not correctly using the manager of the message and would attempt to find messages in the channel instead of the thread.

The `activeThread` was also not correctly set sometimes.

Also adds tests for message selection in threads.
2023-05-11 17:52:53 +02:00
Joffrey JAFFEUX
0c27baef76
FIX: keyboard on android (#21505) 2023-05-11 16:12:48 +02:00
Joffrey JAFFEUX
5b12d23b1d
FIX: rely only on one keyboard computation solution (#21492)
We were combining both solutions which was apparently causing issues from chrome 113 on Android at least.

The commit will now use `geometrychange` (android) only when available and fallback to `visualViewport` otherwise (iOS).
2023-05-11 08:58:29 +02:00
Joffrey JAFFEUX
55c4a550c1
FEATURE: chat-replying indicator for threads (#21485)
This feature adds the replying indicator in threads, it uses the same `/chat-reply/CHANNEL_ID` prefix than the channel composer replying indicator as we don't have specific right on threads ATM (if you can access channel, you can access thread). Thread will however use a presence channel name of the following format: `/chat-reply/CHANNEL_ID/thread/THREAD_ID`

This commit also simplifies the computation of `users` to eventually avoid a race-condition leading to a leak of the indicator in another channel/thread.

<!-- 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-05-11 08:02:04 +02:00
Jan Cernik
cbbaeb55b5
FIX: Don't autojoin users when they have ready-only permissions (#20213)
After this change, in order to join a chat channel, a user needs to be in a group with at least “Reply” permission for the category. If the user only has “See” permission, they are able to preview the channel, but not join it or send messages. The auto-join function also follows this new restriction.

---------

Co-authored-by: Martin Brennan <martin@discourse.org>
2023-05-10 08:45:13 -03:00
Joffrey JAFFEUX
c6b43ce68b
FEATURE: Thread list initial UI (#21412)
This commit adds an initial thread list UI. There are several limitations
with this that will be addressed in future PRs:

* There is no MessageBus reactivity, so e.g. if someone edits the original
   message of the thread it will not be reflected in the list. However if
   the thread title is updated the original message indicator will be updated.
* There is no unread functionality for threads in the list, if new messages
   come into the thread there is no indicator in the UI.
* There is no unread indicator on the actual button to open the thread list.
* No pagination.

In saying that, this is the functionality so far:

* We show a list of the 50 threads that the user has most recently participated
   in (i.e. sent a message) for the channel in descending order.
* Each thread we show a rich excerpt, the title, and the user who is the OM creator.
* The title is editable by staff and by the OM creator.
* Thread indicators show a title. We also replace emojis in the titles.
* Thread list works in the drawer/mobile.
2023-05-10 11:42:32 +02:00
Joffrey JAFFEUX
44e650d175
FIX: prevents fast channel switching to cause an error (#21461)
`this.users` would end up being nil and `this.users.filter` would generate an exception.
2023-05-09 23:52:46 +02:00
Joffrey JAFFEUX
e935d2bddb
FIX: minor thread changes on mobile (#21457)
- do not render sidepanel resizer as it's not usable on mobile
- removes 1px to the bottom spacing, this spacing won't be necessary once we implement chat-replying-indicator for thread
2023-05-09 22:38:44 +02:00
Joffrey JAFFEUX
d1e4e7cd6f
FIX: more precise chat-replying-indicator (#21451)
- correctly subscribe/unsubscribe channel
- instantly changes users list
- adds a test for testing channel change
- rewrites tests to be less verbose
- ensures users is always an array
2023-05-09 13:25:33 +02:00
Joffrey JAFFEUX
bc847e54d4
DEV/ glimmerify chat-channel-status (#21445)
This commit also adds a component test for it and fixes a bug in `chat-channel-archive-status` `#getTopicURL` property which was incorrectly called as a function.
2023-05-09 09:22:25 +02:00
Joffrey JAFFEUX
3bc5c0ad18
FIX: makes mouse events passive (#21441) 2023-05-09 08:03:03 +02:00
Joffrey JAFFEUX
22521d3428
DEV: converts models to native classes (#21418)
- `ChatChannel`
- `UserChatChannelMembership`

Also creates a new `chat-direct-message` model used as the object for the`chatable` property of the `ChatChannel` when the `ChatChannel` is a direct message channel. When the chatable is a category a real `Category` object will now be returned.

Archive state of a `ChatChannel` is now hold in a `ChatChannelArchive` object.
2023-05-08 18:24:41 +02:00
Jarek Radosz
fdf38335ab
DEV: Correct the app-events service injections (#21413) 2023-05-08 10:48:56 +02:00
Joffrey JAFFEUX
5c9efea480
FIX: correct link on original message (#21415)
Ensures that using copy link on the the original message of a thread in a channel, copies the link to the channel and not the thread.
2023-05-08 09:10:10 +02:00
Joffrey JAFFEUX
e8d6277062
FIX: attempts to reconciliate tracking state (#21416)
After a long time with no activity or hidden browser (2.5 minutes), the app will re-sync the chat user-tracking-state to ensure unreads are synced.

We might also need to couple this later with more recovering logic.
2023-05-08 09:09:35 +02:00
Joffrey JAFFEUX
cb5e5f3e5b
UX: groups deleted messages (#21411)
Any continuous series of deleted messages will now be grouped into one single expand button.
2023-05-05 17:08:33 +02:00
Joffrey JAFFEUX
78616404ce
UX: scroll to bottom when message is staged (#21408)
Since our recent change of inverting thread scrolling direction it feels more responsive to scroll down in thread panel as soon as message is staged and not after it's actually persisted.
2023-05-05 13:14:13 +02:00
Joffrey JAFFEUX
e88b997153
Revert "UX: preloads a thread when hovering thread indicator (#21406)" (#21407)
This reverts commit 028dba144d.
2023-05-05 12:06:30 +02:00
Joffrey JAFFEUX
028dba144d
UX: preloads a thread when hovering thread indicator (#21406)
When hovering a thread indicator in a channel we will now append two `<link rel="preload" ...>` to the `<head>` of the document. Clicking on it should be significantly faster.

Co-authored-by: Martin Brennan <martin@discourse.org>
2023-05-05 11:18:03 +02:00
Joffrey JAFFEUX
187b59d376
UX: implements draft threads (#21361)
This commit implements all the necessary logic to create thread seamlessly. For this it relies on the same logic used for messages and generates a `staged-id`(using the format: `staged-thread-CHANNEL_ID-MESSAGE_ID` which is used to re-conciliate state client sides once the thread has been persisted on the backend.

Part of this change the client side is now always using real thread and channel objects instead of sometimes relying on a flat `threadId` or `channelId`.

This PR also brings three UX changes:
- thread starts from top
- number of buttons on message actions is dependent of the width of the enclosing container
- <kbd>shift + ArrowUp</kbd> will reply to the last message
2023-05-05 08:55:55 +02:00
Martin Brennan
b2a727336e
FIX: Thread mention read state and notification links (#21385)
* FIX: Link to thread for mentions inside thread

When mentioning a user in a thread, when we send the
notification and display it in the UI we want the URL
of the notification to point to the thread URL to open
the panel, rather than the main channel which is confusing.

For now, we don't have a way to highlight the linked-to message
in the thread, we can revisit this later.

* FIX: Mark mention notifications read when thread opens

Since we have no scrolling/message visibility/thread membership
for now, when a user opens the thread panel we just want to mark
all mention notifications relating to messages in the thread
for the user as read.
2023-05-04 17:28:51 +02:00
Joffrey JAFFEUX
b46899e5fa
FIX: more resilient dates separators computation (#21370)
In the past this was happening on scroll so we needed to be very conservative here. Also, if we wait too much theres a visible element flashing so this PR attempts to compute right away, and a second time 100ms later in case the first one happened too early.
2023-05-03 21:29:18 +02:00
Jan Cernik
bfd3bd5516
FIX: ChatComposerMessageDetails icon was always edit (#21340) 2023-05-02 14:31:42 -03:00
Joffrey JAFFEUX
616f4a1118
FIX: disables send btn while uploads in progress (#21298)
Before this fix you could press send while upload was in progress and lose it as it was not yet uploaded.
2023-05-02 18:11:40 +02:00
Joffrey JAFFEUX
69a72015f0
UX: resets active message when scrolling (#21305)
This will avoid the messages actions floating around while scrolling. Note it's not testing the thread counterpart yet as I have a plan in mind to tests channels and threads in a clean way in the near future.
2023-05-02 14:21:30 +02:00
Joffrey JAFFEUX
3e50a81d96
DEV: potential flakey fixes (#21309) 2023-04-29 00:15:51 +02:00
Joffrey JAFFEUX
cd24656570
DEV: potential flakey specs fixes (#21307) 2023-04-28 22:06:27 +02:00
Joffrey JAFFEUX
0239e88809
UX: cook message before sending edit (#21303)
This allows for instant feedback in the UI.
2023-04-28 20:11:57 +02:00
Joffrey JAFFEUX
290bd975c5
FIX: correctly differentiates channel/thread upload inputs (#21301)
Prior to this fix uploads event could end up in the wrong textarea. This will most importantly allow pasting an image in the thread composer.

Also fixes a minor padding issue on thread when uploads are associated to it.
2023-04-28 19:08:55 +02:00
Joffrey JAFFEUX
1403064835
FIX: correctly homogenizes panels min width (#21294)
`.chat-channel` had `300px` min width, when `.chat-drawer` was `250px`, resulting in overflowing channel when in drawer. This commits ensures the limits are always set at `250px`.
2023-04-28 13:05:00 +02:00
chapoi
f29f131387
UX: composer use BEM + small tweaks to enabled/disabled styling (#21246)
- using BEM notation
- making animation linear instead of default ease
- small tweaks to composer state (disabled/send-disabled/send-enabled)
- fixing bug with disabled composer on mobile
2023-04-28 10:24:49 +02:00
Joffrey JAFFEUX
7f803a0335
FIX: ensures thread is cleared when closing it (#21264) 2023-04-26 20:37:58 +02:00
Joffrey JAFFEUX
36db953bc6
FIX: cancels saving draft when composer is destroyed (#21260) 2023-04-26 19:42:57 +02:00
Jarek Radosz
a1b35601fc
FIX: Improve chat route cleanup (#20557)
1. `this.chat.activeChannel = null` was being done in twice
2. using `willTransition()` and checking transition.to.name prefix for route cleanup rather than using `deactivate()` was unnecessarily verbose and could be premature (if something aborted the transition you'd end up in a broken state)
3. `activeChannel` on Chat service can be null, check for that before accessing
2023-04-26 18:18:23 +02:00
Joffrey JAFFEUX
6487c8ef24
FIX: properly respects chat_minimum_message_length (#21256)
Before this fix we were only considering `>` and not `>=`, this also adds two tests.
2023-04-26 17:35:35 +02:00
Joffrey JAFFEUX
731282c2ec
FIX: attempts to make cooking less order dependent (#21253)
It's very hard to repro but under specific circumstances I suspect it was possible for this sequence to happen:

- set message TEXT
- cooking starts
- set message COOKED through another mean (like a message bus)
- the cooking started sooner finished and erases the cooked set at the step before causing the message to have the incorrect cooked
2023-04-26 16:50:38 +02:00
Joffrey JAFFEUX
427fa36edd
FIX: generates markdown from pasting link (#21241)
After removing `TextareaTextManipulation` from `ChatComposer` and using `TextareaInteractor` as a proxy, one function has been forgotten: `paste(event)` which is not available in glimmer components anymore, and even less avaiable now that the mixin is not tied to a component anymore but a real DOM node. As a solution we now add a manual paste event listener which will call `paste(event)`.
2023-04-26 10:05:48 +02:00
Joffrey JAFFEUX
6ea4854c51
UX: displays channel title in document title (#21242) 2023-04-26 09:09:07 +02:00
Joffrey JAFFEUX
a052ecee62
FIX: safeguard in case the message is active during transition (#21235)
Prior to this fix, we could sometimes still have an active message while the DOM node was already removed.
2023-04-25 13:16:55 +02:00
Joffrey JAFFEUX
bf886662df
UX: improves composer and thread panel (#21210)
This pull request is a full overhaul of the chat-composer and contains various improvements to the thread panel. They have been grouped in the same PR as lots of improvements/fixes to the thread panel needed an improved composer. This is meant as a first step.

### New features included in this PR

- A resizable side panel
- A clear dropzone area for uploads
- A simplified design for image uploads, this is only a first step towards more redesign of this area in the future

### Notable fixes in this PR

- Correct placeholder in thread panel
- Allows to edit the last message of a thread with arrow up
- Correctly focus composer when replying to a message
- The reply indicator is added instantly in the channel when starting a thread
- Prevents a large variety of bug where the composer could bug and prevent sending message or would clear your input while it has content

### Technical notes

To achieve this PR, three important changes have been made:

- `<ChatComposer>` has been fully rewritten and is now a glimmer component
- The chat composer now takes a `ChatMessage` as input which can directly be used in other operations, it simplifies a lot of logic as we are always working a with a `ChatMessage`
- `TextareaInteractor` has been created to wrap the existing `TextareaTextManipulation` mixin, it will make future migrations easier and allow us to have a less polluted `<ChatComposer>`

Note ".chat-live-pane" has been renamed ".chat-channel"

Design for upload dropzone is from @chapoi
2023-04-25 10:23:03 +02:00
Martin Brennan
24ec06ff85
FEATURE: Reintroduce better thread reply counter cache (#21197)
This was reverted in 38cebd3ed5.
The issue was that I was using Discourse.redis.delete_prefixed
which does a slow redis KEYS lookup, which is not advised in
production. This commit removes that, and also ensures the periodical
thread count update only happens if threading is enabled.

I changed to use a redis INCR/DECR for reply count
cache. This avoids a round trip to redis to GET the current
count, and also avoids multi-process issues, where
if there's two processes trying to increment at the
same time, they may both receive the same value, add one
to it, then both write the same value back.
Then, it's only n+1 instead of n+2.

This also prevents almost all chat scheduled jobs from
running if chat is disabled, the only one remaining is
the message retention job.
2023-04-24 09:32:04 +10:00
Martin Brennan
21f93731a3
DEV: Move channel creation for category into service (#21167)
This commit moves the category channel creation out
of the Chat::Api::Channel controller and into a
dedicated CreateCategoryChannel service. A follow up
commit will move the DM channel creation out of
the old DirectMessageChannelCreator service.

Also includes a new on_model_errors helper
for chat service class usage, that collects model
validation errors to present in a nice way.

---------

Co-authored-by: Loïc Guitaut <loic@discourse.org>
2023-04-24 09:15:16 +10:00
Daniel Waterworth
38cebd3ed5
Revert "FEATURE: Better thread reply counter cache (#21108)" (#21192)
This reverts commit 180e3e11d1.

Per internal discussions, this is a temporary revert, to investigate if this is causing a performance regression.
2023-04-20 15:09:47 -05:00
chapoi
c57f423083
UX: remove new message element from chatpane (#21143)
* UX: remove new message element

* Update chat-scroll-to-bottom-arrow.hbs

* Linting

---------

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2023-04-19 01:54:15 +02:00
Martin Brennan
5b3420d854
FIX: Chat composer shortcuts should respect context (#21130)
This commit fixes an issue where if you pressed a format
shortcut (e.g. bold, italic, code) for the composer and
you had the thread panel open as well, the shortcut would
trigger in both composers, not just the one that was focused.
2023-04-19 09:07:52 +10:00
Martin Brennan
a8cf8e57b4
FIX: Do not count thread messages for channel unreads (#21126)
We currently don't have a nice UI to show unread messages for the thread,
and it will take some time to create one. For now, this commit makes it so
new messages inside a thread do not count towards a chat channel's unread
counts, and new messages sent in a thread do not update a user's `last_read_message_id`
for a channel.

In addition, this PR refactors the `Chat::ChannelFetcher` to use the `Chat::ChannelUnreadsQuery`
query class for consistency, and made said class able to return zeroed-out records
for channels the user is not a member of.

Finally, a small bug is fixed here where if a user's `last_read_message_id` for
a channel was a thread's OM ID, then the thread OM would not show in the
main channel stream for them until another reply to the channel was posted.
2023-04-19 08:53:51 +10:00
chapoi
0f7eeb5500
FIX: apply clear-transition class to correct wrapper for chat drawer (#21129) 2023-04-18 08:37:13 +02:00
Martin Brennan
180e3e11d1
FEATURE: Better thread reply counter cache (#21108)
This commit introduces a redis cache over the top of the thread
replies_count DB cache, so that we can quickly and accurately
increment/decrement the reply count for all users and not have
to constantly update the database-level count. This is done so
the UI can have a count that is displayed to the users on each
thread indicator, that appears to live update on each chat
message create/trash/recover inside the thread.

This commit also introduces the `Chat::RestoreMessage` service
and moves the restore endpoint into the `Api::ChannelMessages`
controller as part of incremental migrations to move things out
of ChatController.

Finally, this commit refactors `Chat::Publisher` to be less repetitive
with its `MessageBus` sending code.
2023-04-18 14:01:01 +10:00
Martin Brennan
1e85de36e2
FEATURE: Hook up chat bulk delete for threads (#21109)
Followup to bd5c5c4b5f,
this commit hooks up the bulk delete events for chat
messages inside the thread panel, by fanning out the
deleted message IDs based on whether they belong to
a thread or not.

Also adds a system spec to cover this case, as previously
the bulk delete event would have been broken with an incorrect
`typ` rather than `type` hash key.
2023-04-18 08:28:20 +10:00
Joffrey JAFFEUX
5b187ad25e
FIX: error when quoting message into topic (#21114)
This error was only happening on mobile, note we also already have a (mobile) test (plugins/chat/spec/system/transcript_spec.rb:184) for this which was passing as it's only happening at a specific speed. I don't want to complicate the test too much for this case, will reconsider if it regresses again.
2023-04-17 17:14:51 +02:00
Joffrey JAFFEUX
274820d247
FIX: prevents exception when publishing processed (#21104)
This regression happened in bd5c5c4b5f and is due to `message_bus_targets = calculate_publish_targets(chat_channel, chat_message)` expecting a `chat_channel` which was only defined after.

Example exception in logs:

```
Job exception: undefined local variable or method `chat_channel' for Chat::Publisher:Module

/var/www/discourse/plugins/chat/app/services/chat/publisher.rb:91:in `publish_processed!' 
/var/www/discourse/plugins/chat/app/jobs/regular/chat/process_message.rb:21:in `block in execute' 
/var/www/discourse/lib/distributed_mutex.rb:53:in `block in synchronize' 
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize' 
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize' 
/var/www/discourse/lib/distributed_mutex.rb:34:in `synchronize' 
/var/www/discourse/plugins/chat/app/jobs/regular/chat/process_message.rb:7:in `execute' 
/var/www/discourse/app/jobs/base.rb:249:in `block (2 levels) in perform' 
```

This commit also:
- adds a spec to ensure oneboxing is not regressing anymore
- increment the version on message processed to ensure callbacks are correctly ran

Note we should also have more tests in `Chat::Publisher`, this will be done when we move it to a proper service.

<!-- 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-04-16 10:30:33 +02:00
Joffrey JAFFEUX
9b3408223b
FIX: relies on native focus behavior in chat emoji picker (#21092)
This codepath was responsible to scroll to the first emoji of a section, however `scrollIntoView` was not super reliable and was also causing the whole page to scroll with drawer. This is also simply not necessary code as native focus behavior will scroll to the element.
2023-04-13 20:35:13 +02:00
Martin Brennan
bd5c5c4b5f
FEATURE: Reacting to MessageBus in chat thread panel (#21070)
This commit introduces a ChatChannelPaneSubscriptionsManager
and a ChatChannelThreadPaneSubscriptionsManager that inherits
from the first service that handle MessageBus subscriptions
for the main channel and the thread panel respectively.

This necessitated a change to Chat::Publisher to be able to
send MessageBus messages to multiple channels based on whether
a message was an OM for a thread, a thread reply, or a regular
channel message.

An initial change to update the thread indicator with new replies
has been done too, but that will be improved in future as we have
more data to update on the indicators.

Still remaining is to fully move over the handleSentMessage
functionality which includes scrolling and new message indicator
things.

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2023-04-13 14:45:50 +02:00
Joffrey JAFFEUX
18c81958e5
UX: various tweaks on thread (#21083)
- Back button in drawer will bring you back to channel
- Larger font for thread indicator
- Prevents screen flashing due to clearing messages when they were already loaded
- Fixes a bug where did-update params were inverted causing an error when expanding/collapsing drawer
2023-04-13 10:08:12 +02:00
David Battersby
967010e545
FEATURE: Add an emoji deny list site setting (#20929)
This feature will allow sites to define which emoji are not allowed. Emoji in this list should be excluded from the set we show in the core emoji picker used in the composer for posts when emoji are enabled. And they should not be allowed to be chosen to be added to messages or as reactions in chat.

This feature prevents denied emoji from appearing in the following scenarios:
- topic title and page title
- private messages (topic title and body)
- inserting emojis into a chat
- reacting to chat messages
- using the emoji picker (composer, user status etc)
- using search within emoji picker

It also takes into account the various ways that emojis can be accessed, such as:
- emoji autocomplete suggestions
- emoji favourites (auto populates when adding to emoji deny list for example)
- emoji inline translations
- emoji skintones (ie. for certain hand gestures)
2023-04-13 15:38:54 +08:00
Martin Brennan
584a17c948
FEATURE: Initial chat thread indicator and disabling echo mode in channels (#21047)
This commit introduces a new thread indicator for channels with `threading_enabled`
set to true and the `enable_exp` site setting set to true. In addition, in the main channel
stream we now hide all messages that are linked to threads except for the original message,
disabling the concept of an "echo mode" for now, we may revisit this in future. We also
remove the jigsaw puzzle "Open Thread" button for message actions, since the thread
indicator can just be used instead.

This also stops the `Chat::Publisher` from sending any messages related to chat
messages that are linked to a thread, unless that chat message is the OM of the
thread. A subsequent PR will link up all MessageBus events within the thread panel,
and for the message indicators.

Another subsequent PR will add the excerpt of the latest message in each thread,
as well as the avatars of the users messaging in the thread.

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2023-04-12 11:09:06 +10:00
Joffrey JAFFEUX
f55266e1ca
UX: chat mobile tweaks (#21041)
- rounded active style for messages
- better active state on chat message actions rows
- ensures long press on a message is not selecting text
- slightly improved messages actions animation and background fading
- ensures chat emoji picker is not cutoff on right side
- removes old legacy code related to hovered message
2023-04-11 09:03:12 +02:00
Martin Brennan
7ae716fa69
FIX: Multiple channels marked active in sidebar (#21045)
Followup to c1dc6a2db4,
this commit just missed removing one of the @computed
decorators which was causing multiple active channels
to show in the sidebar. Fix the issue and introduce a
system spec to catch this.
2023-04-11 12:31:17 +10:00
Joffrey JAFFEUX
c1dc6a2db4
FIX: ensures activeMessage is reset with channel (#21031) 2023-04-10 08:10:01 +02:00
Joffrey JAFFEUX
c7b49a14c7
Chat/drawer ux tweaks (#21032)
- clicking empty area on the header will toggle collapse/expand it
- applies a background on hover of the channel title
- active state for small buttons
- the back button now has the correct icon color when hovered
- adds missing focus state for heade buttons icons
2023-04-10 07:43:11 +02:00
Joffrey JAFFEUX
3176d4cb5a
FIX: ensures message actions are bounded (#21027) 2023-04-07 20:54:41 +02:00
Joffrey JAFFEUX
720cf24659
FIX: shows a message as hovered when hovering actions (#21026)
When hovering the chat message actions we are technically not hovering the message anymore, which was removing the background and is slightly unexpected. This commit ensures we keep this background until closing the message actions.
2023-04-07 20:29:33 +02:00
Joffrey JAFFEUX
6d99e6408f
FIX: correctly show user info (#21023)
This PR primarily fixes this case:

- USER A message
- USER B message
- USER B reply to USER A message <-- not showing user info when it should

Moreover, this commit also improves the spec to correctly test more cases.
2023-04-07 20:08:31 +02:00
Joffrey JAFFEUX
9117ea0e3f
FIX: scroll when clicking first emoji of section (#21020)
This bug was also happening when tabbing through sections
2023-04-07 14:11:25 +02:00
Joffrey JAFFEUX
79cacba948
FIX: cancel editing should clear the composer (#21011) 2023-04-07 09:55:55 +02:00
Joffrey JAFFEUX
fef279acd5
FIX: do not display the message content when it errors (#21008) 2023-04-06 19:32:21 +02:00
Daniel Waterworth
0ff86feb96
DEV: Rely on helpers for ajax error handling to reduce repetition (#20988) 2023-04-06 11:25:24 -05:00
Martin Brennan
ea548292bc
DEV: Refactoring chat message actions for ChatMessage component usage in thread panel (#20756)
This commit is a major overhaul of how chat message actions work, to make it so they are reusable between the main chat channel and the chat thread panel, as well as many improvements and fixes for the thread panel.

There are now several new classes and concepts:

* ChatMessageInteractor -  This is initialized from the ChatMessage, ChatMessageActionsDesktop, and ChatMessageActionsMobile components. This handles permissions about what actions can be done for each
message based on the context (thread or channel), handles the actions themselves (e.g. copyLink, delete, edit),
and interacts with the pane of the current context to modify the UI
* ChatChannelThreadPane and ChatChannelPane services - This represents the UI context which contains the
messages, and are mostly used for state management for things like message selection.
* ChatChannelThreadComposer and ChatChannelComposer - This handles interaction between the pane, the
message actions, and the composer, dealing with reply and edit message state.
* Scrolling logic for the messages has now been moved to a helper so it can be shared between the main channel pane and the thread pane
* Various improvements with the emoji picker on both mobile and desktop. The DOM node of each component is now located outside of the message which prevents a large range of issues.

The thread panel now also works in the chat drawer, and the thread messages have less
actions than the main panel, since some do not make sense there (e.g. moving messages to
a different channel). The thread panel title, excerpt, and message sender have also been removed
for now to save space.

This gives us a solid base to keep expanding on and fixing up threads. Subsequent PRs will
make the thread MessageBus subscriptions work and disable echo mode
for the initial release of threads.

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2023-04-06 15:19:52 +02:00
Joffrey JAFFEUX
838fb37019
FIX: accounts for hide_profile_and_presence core user option (#20991)
Chat will now correctly use this core setting and will not show the presence of the user in this case.
2023-04-06 09:29:54 +10:00
Martin Brennan
6ad9e4ad06
FEATURE: Add CSS class generation for category colors and hashtags (#20951)
This commit adds a system to generate CSS variables and classes for categories
and hashtags, which will be used in an effort to remove baked icons for hashtags
and add color to those icons.

This is in two parts. First I added an initializer generate a category color CSS
variable style tag in the head tag that looks like this:

```css
:root {
--category-1-color: #0088CC;
--category-2-color: #808281;
--category-3-color: #E45735;
--category-4-color: #A461EF;
--category-5-color: #ee56c9;
--category-6-color: #da28c2;
--category-7-color: #ab8b0a;
--category-8-color: #45da37;
...
}
```

The number is the category ID. This only generates CSS variables for categories
the user can access based on `site.categories`. If you need the parent color variable
you can just use the `category.parentCategory.id` to get it.

Then, I added an initializer to generate a hashtag CSS style tag using these variables.
Only the category and channel hashtags need this, the category one generates the
background-gradient needed for the swatch, and the channel just generates a color
for the icon. This is done in an extendable way using the new `api.registerHashtagType`
JS plugin API:

```css
hashtag-color--category-1 {
  background: linear-gradient(90deg, var(--category-1-color) 50%, var(--category-1-color) 50%);
}
hashtag-color--category-2 {
  background: linear-gradient(90deg, var(--category-2-color) 50%, var(--category-2-color) 50%);
}
hashtag-color--category-5 {
  background: linear-gradient(90deg, var(--category-5-color) 50%, var(--category-4-color) 50%);
}
...
.hashtag-color--channel-4 {
  color: var(--category-12-color);
}
.hashtag-color--channel-92 {
  color: var(--category-24-color);
}
```

Note if a category has a parent, its color is used in the gradient correctly. The numbers
here are again IDs (e.g. channel ID, category ID) and the channel’s chatable ID is used
to find the category color variable.
2023-04-05 13:02:35 +10:00
chapoi
6e2fd7a451
UX: Chat channel title overflow ellipsis fixes (#20956)
* UX: add correct class

* UX: prioritise name over user messages when truncating

* UX: add missing overflows to enable ellipsis
2023-04-04 12:44:36 +02:00
Martin Brennan
894586afa9
FIX: Trashing message should reset last read (#20912)
When a chat message is trashed and the message is used
for someone's UserChatChannelMembership#last_read_message_id,
the user would end up with some read state issues until
someone posted a new message in the channel, since we didn't
clear it like we did on bulk message delete.

This commit fixes the issue, and also takes the opportunity
to start a MessagesController in the API namespace, and move
the trash message functionality into the new service format.
2023-04-04 09:30:38 +10:00
Jarek Radosz
29e2e3ff3b
DEV: Fix random typos (#20937) 2023-04-03 19:27:32 +02:00
Joffrey JAFFEUX
1219f41c68
UX: multiple minor improvements (#20917)
- Raises the scroll distance to 250px instead of 100px to show the arrow down button
- Always have a margin on drawer when showing channel list, removes this margin when the scrollbar is apparent
- Makes all scrollbar used in chat look the same through the chat-scrollbar mixin
- Ensures hover state is not persistent on channel row in mobile
- Makes the channel row full width on mobile
2023-04-03 10:46:38 +02:00
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Jarek Radosz
3c4bfb6a9f
UX: Tweak last-visit/date separators (#20601)
1. Restore the left margin on both (which reflects the right margin of the scroll bar space)
2. Fix the center alignment of scroll-to-bottom icon
3. Fix the spacing of the `-` character between a date label and "last visit" label
4. Fix the incorrect display the border on date label when at the bottom of viewport
2023-03-09 13:44:02 +01:00
Martin Brennan
ba1b95c9f4
FIX: Uploading multiple files to chat could cause canellations (#20605)
When we introduced `existingUploads` as an arg to the
ChatComposerUploads component, we also introduced a bug where
if multiple uploads were being done at once, and the draft
was saved, then because of didReceiveAttrs we would cancel
the currently uploading files because the draft uploads became
the existingUploads.

To work around this, since we do want to keep this on didReceiveAttrs
for cases when the user opens a draft or edits another message,
the easiest thing to do is to just not save uploads into the chat
draft if there are still uploads in progress. That way only when
all uploads are complete do we make them a part of the draft.

There is a small risk that the user could do something to lose
their uploads in the draft, but it's a better gamble to have
that happen rather than in progress uploads to be cancelled
while the user is waiting for them to be done because of the
draft.

Also changes the uploads system spec back to the old way of
attaching multiple files since that is why it was failing.
2023-03-09 09:17:54 +01:00
Martin Brennan
931eedeb66
Revert "FIX: more precise unread message detection (#20588)" (#20604)
This reverts commit d78fed7dc6.

Causing some issues with clearing unreads.
2023-03-09 11:03:33 +10:00
Joffrey JAFFEUX
d78fed7dc6
FIX: more precise unread message detection (#20588) 2023-03-08 17:28:54 +01:00
Joffrey JAFFEUX
4f2dfd3857
FIX: correctly syncs current user message in multiple sessions (#20584) 2023-03-08 17:28:39 +01:00
Joffrey JAFFEUX
7f486cbc9b
FIX: do not show infinite loading state on draft with new users (#20582) 2023-03-08 15:21:20 +01:00
Joffrey JAFFEUX
2781264711
PERF: various perf improvements of chat-live-pane (#20563) 2023-03-07 18:55:05 +01:00
Joffrey JAFFEUX
e27c045f75
PERF: reduce height of the load more past message area (#20545)
On fast networks it could end up in infinite loop until all messages had been loaded.
2023-03-06 17:23:32 +01:00
Joffrey JAFFEUX
b5e736504a
PERF: applies optimisations on chat-live pane (#20532)
- group writes when computing separators positions
- shows skeleton only on initial load
- forces date separator to be pinned when first message to prevent a pinned - not pinned - pinned sequence when loading more in past
- relies on `message.visible` property instead of checking `isElementInViewport`
- attempts to load next/prev messages earlier
- do not scroll to on fetch more
- hides `last visit` text while pinned
2023-03-06 16:42:11 +01:00
Joffrey JAFFEUX
9e49abc0b9
FIX: do not refresh when accessing loaded reply (#20526)
Note this test my prove to be flakey, so I might have to remove it or find a different solution. It's extremely complicated to test for something which shouldn't appear in a period of time and is not a present at T=0
2023-03-06 10:09:21 +01:00
Joffrey JAFFEUX
cdcd20fe1e
FIX: prevents duplicate reactions (#20527)
This was possible due to specific events which are hard to represent in a test. The provided test is as close as possible to what was happening in production: a message bus event was played on a channel which has just loaded its state with the existing reaction.
2023-03-03 20:29:24 +01:00
Joffrey JAFFEUX
0dc9c6c96d
FIX: prevents exception on required login sites with chat (#20525)
On require login sites, the `site` is not setup and as a result `hashtag_configurations` was blank and causing an error when attempting to access `["chat-composer"]` on it.
2023-03-03 17:40:23 +01:00