Commit Graph

106 Commits

Author SHA1 Message Date
Kris
a914d3230b
DEV: remap all core icons for fontawesome 6 upgrade (#28715)
Followup to 7d8974d02f

Co-authored-by: David Taylor <david@taylorhq.com>
2024-09-13 16:50:52 +01:00
David Battersby
e991574389
UX: chat drawer increase unread channel visibility (#28731)
This change increases the visibility of unread channels to make them stand out more in drawer mode (desktop).

When a channel is unread:

- it floats to the top;
- when multiple channels are unread, they are sorted alphabetically (equal to how it’s done on mobile)
- the unread indicator blue dot moves to directly right of the channel name
2024-09-05 13:36:50 +04:00
David Battersby
fdcf4698fc
UX: Update Chat Group Name and Placeholder (#28703)
* UX: Update Chat Group Name and Placeholder

* update tests

* fix failing tests

* better checking of system user when setting dm title
2024-09-04 15:52:23 +10:00
Jarek Radosz
f14cf4f8a9
DEV: Fix random typos (#28103)
July 2024 edition
2024-07-26 23:13:12 +02:00
Jarek Radosz
038e5deb2a
DEV: Clean up imports (#28060)
* `@ember/owner` instead of `@ember/application`
* `discourse-i18n` instead of `I18n`
* `{ service } from "@ember/service"` instead of `inject as service`
2024-07-25 15:09:06 +02:00
Jarek Radosz
8d4c9523ee
DEV: Convert some tests to qunit-dom (#27577)
(and fix two test bugs)
2024-06-23 22:34:15 +02:00
Joffrey JAFFEUX
fe16633a0c
DEV: allows for multiple menus/tooltips (#26823)
menus and tooltips are now appended to their own portals. The service are the only responsible for managing the instances, prior to this commit, services could manage one instance, but the DMenu and DTooltip components could also take over which could cause unexpected states.

This change also allows nested menus/tooltips.

Other notable changes:

- few months ago core copied the CloseOnClickOutside modifier of float-kit without removing the float-kit one, this commit now only use the core one.
- the close function is now trully async
- the close function accepts an instance or an identifier as parameter
2024-05-07 23:48:44 +02:00
Joffrey JAFFEUX
278eb0a1a5
FIX: improvements to chat message streaming (#26892)
- prevents re-rendering avatars while updating messages quickly in the thread preview indicator
- ensures the cancel button is shown when you are admin OR when the streamed message is a reply to the current user
2024-05-07 15:38:24 +02:00
Joffrey JAFFEUX
2347ff7074
FIX: only show discourse-ai CTA to admins (#26895) 2024-05-07 00:43:30 +02:00
Joffrey JAFFEUX
1060e4573a
DEV: allows fabricators to use faker (#26555)
The complexity of the situation is that we don't want to load faker into production by default but fabricators and styleguide are available on production.

This is made possible through app/assets/javascripts/discourse/app/lib/load-faker.js which contains a function to ensure faker is loaded asynchronously (loadFaker) and another function to access the loaded faker (getLoadedFaker).

Note 1: this commit also refactors fabricators to have access to context and use faker where possible
Note 2: this commit moves automation to admin bundle

---------

Co-authored-by: David Taylor <david@taylorhq.com>
2024-04-08 21:00:09 +02:00
Jarek Radosz
11099434b5
DEV: Clean up mobileView/desktopView uses (#26229)
Inspired by a piece of "do not do x if it's not a mobile view" code 🙃
2024-03-18 23:29:42 +01:00
Joffrey JAFFEUX
bbb8595107
PERF: defer loading channels (#26155)
Prior to this change we would pre-load all the user channels which making initial page load slower. This change will make them be loaded right after initial load. In the past this was not possible as the channels would have to be loaded on each page transition. However since about a year, we made the channels to be cached on the frontend and no other request will be needed.

I have decided for now to not show a loading state in the sidebar as I think it would be noise, but we can reconsider this later.

Note given we don't have the channels loaded at first certain things where harder to accomplish. The biggest UX change of this commit is that we removed all the complex logic of computing the best channel to display when you load /chat. We will now store the id of the last channel you visited and will use this id to decide which channel to show.
2024-03-18 08:35:07 +01:00
David Battersby
d5b944f1de
FEATURE: add chat direct message button to user profile (#26135)
This change adds the chat direct message button to user profiles, similarly to how we use it within the user card.
2024-03-18 11:17:37 +08:00
David Battersby
88f833418f
FIX: channel member status live updates (#25925) 2024-02-29 17:49:18 +08:00
David Battersby
a423afbbb9
FEATURE: Add user status to chat members list (#25831)
This change adds the user status next to the name within the chat channel members list.
2024-02-27 12:17:15 +08:00
chapoi
292685d3de
UX: Chat browse redesign (#25698)
* UX: fix search input placeholder cutoff

* UX: use transparent button for new-channel

* UX: remove settings link

* UX: removed joined tag

* UX: increase lock icon size

* UX: use grid for channel card

* UX: chat-channel-card styling + cleanup

* UX: dont space about tabs on mobile

* specs

* PR feedback

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>

* PR feedback > translation

* Remove import

* UX: update copy

---------

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2024-02-15 18:00:22 +01:00
Joffrey JAFFEUX
7b173e883f
FEATURE: display last message on mobile (#25384)
Direct messages on mobile will now display the last message in the channels list.
2024-01-25 15:30:21 +01:00
Joffrey JAFFEUX
2014f1a0b7
FEATURE: implements dates separators for threads (#25335)
This commit creates a shared implementation of the dates computation and moves all the logic (new messages since last visit and dates separator into one single component <ChatMessageSeparator />).

The frontend tests have been removed and only a single system spec has been added for threads as everything is sharing the same implementation and the existing channel specs should catch any regression.
2024-01-19 16:21:48 +01:00
Joffrey JAFFEUX
53b96638c5
DEV: implements <Chat::Navbar /> (#24917)
This new navbar component is used for every navbar in chat, full page or drawer, and any screen.

This commit also uses this opportunity to correctly decouple drawer-routes from full page routes. This will avoid having this kind of properties in components: `@includeHeader={{false}}`. The header is now defined in the parent template using a navbar. Each route has now its own template wrapped in a div of the name of the route, eg: `<div class="c-routes-threads">..</div>`.

The navbar API:

```gjs
<Navbar as |navbar|>
 <navbar.BackButton />
 <navbar.Title @title="Foo" />
 <navbar.ChannelTitle @channel={{@channel}} />
 <navbar.Actions as |action|>
   <action.CloseThreadButton />
 </navbar.Actions>
</navbar>
```

The full list of components is listed in `plugins/chat/assets/javascripts/discourse/components/navbar/index.gjs` and `plugins/chat/assets/javascripts/discourse/components/navbar/actions.gjs`.

Visually the header is not changing much, only in drawer mode the background has been removed.

This commit also introduces a `<List />` component to facilitate rendering lists in chat plugin.
2023-12-18 17:49:58 +01:00
Jarek Radosz
41942357ed
DEV: Use class attribute instead of @class arg (#24804) 2023-12-12 13:09:05 +01:00
Joffrey JAFFEUX
09277bc543
FEATURE: my threads page (#24771)
This commit adds a new "My threads" link in sidebar and drawer. This link will open the "/chat/threads" page which contains all threads where the current user is a member. It's ordered by activity (unread and then last message created).

Moreover, the threads list of a channel page is now showing every threads of a channel, and not just the ones where you are a member.
2023-12-11 07:38:07 +01:00
Martin Brennan
ac60b9fe72
DEV: Skip chat test (#24739)
This consistently fails on core now, see
https://github.com/discourse/discourse/actions/runs/7109919490/job/19355591619?pr=24738

Error: QUnit Test Failure: Browser Id 2 - Discourse Chat | Component | chat message collapser images: escapes link
not ok 444 Chrome 120.0 - [58 ms] - Browser Id 2 - Discourse Chat | Component | chat message collapser images: escapes link
    ---
        actual: >
            false
        expected: >
            true
        stack: >

Expected value is %3Cscript%3Esomeeviltitle%3C/script%3E and actual value is
&lt;script&gt;someeviltitle&lt;/script&gt;
2023-12-06 13:58:13 +10:00
Jarek Radosz
cfa7dcaf0a
DEV: Remove unnecessary await settled() (#24584) 2023-11-28 10:45:20 +01:00
Jarek Radosz
68960b26be
DEV: Consistently use kebab-case in service lookups (#24552) 2023-11-25 18:10:10 +01:00
Jarek Radosz
8968887e24
DEV: Fix various typos (#24461)
November 2023 edition
2023-11-20 16:49:49 +01:00
Joffrey JAFFEUX
ab832cc865
FEATURE: introduces group channels (#24288)
Group channels will allow users to create channels with a name and invite people. It's possible to add people even after creation of the channel. Removing users is not yet possible but will be added in the near future.

Technically a group channel is `direct_message_channel` with a group attribute set to true on its direct message (chatable). This model might evolve in the future but offers much flexibility for now without having to rely on a complex migration.

The commit essentially consists of:
- a migration to set existing direct message channels with more than 2 users to a group
- a new message creator which allows to search, add members, and create groups
- a new `AddUsersToChannel` service
- a modified `SearchChatable` service
2023-11-10 11:29:28 +01:00
Joffrey JAFFEUX
dcaa719363
FIX: correctly handle subscriptions (#24270)
Subscriptions manager have been a pain since the beginning, one of the problem is that thread and channels behave mostly the same but with various small difference which I expect to increase over time.

Trying to use subclasses for this case has proven to be a mistake, this commit now uses a class for each case (channel, thread) which for now contains a lot of duplication, which might be reduced in the future but has the merit to make reasoning about each case very simple.

This refactor is fixing a bug introduced in 90efdd7f9d which was causing the wrong channel to be unsubscribed, this shouldn't be possible anymore. We had tests for this which were disabled due to flakeyness, I will consider re-enabling them in the future.

Other notes:
- notices had been added to the subscriptions manager service, they have been moved into their own dedicated service: `ChatChannelNoticesManager`
- the `(each model)` trick used in `<ChatChannel />` since 90efdd7f9d to ensure atomicity has been applied to `<ChatThread />` too
2023-11-07 16:37:42 +01:00
Joffrey JAFFEUX
4859340b2d
FIX: correctly display escaped thread titles (#24159)
Prior to this fix, titles with a quote `'` for example, would be rendered as: `&#x27`
2023-10-30 21:06:31 +01:00
Joffrey JAFFEUX
5fec841c19
FIX: ensures users can open channel invites (#24067)
We were incorrectly generating URLs with message id even when it was not provided, resulting in a route ending with "undefined", which was causing an error.

This commit also uses this opportunity to:
- move `invite_users` into a proper controller inside the API namespace
- refactors the code into a service: `Chat::InviteUsersToChannel`
2023-10-24 18:51:33 +02:00
Godfrey Chan
c34f8b65cb
DEV: Rename I18n imports to discourse-i18n (#23915)
As of #23867 this is now a real package, so updating the imports to
use the real package name, rather than relying on the alias. The
name change in the package name is because `I18n` is not a valid
name as NPM packages must be all lowercase.

This commit also introduces an eslint rule to prevent importing from
the old I18n path.

For themes/plugins, the old 'i18n' name remains functional.
2023-10-18 11:07:09 +01:00
Joffrey JAFFEUX
c1abf8b35c
UX: improves reminder setting text (#23918)
The setting will change from "%{count} days" to "Chat settings have been set to retain channel messages for %{count} day."

This commit also:
- migrates `chat-retention-reminder` to gjs
- adds a "type" property to `chat-retention-reminder-text` to allow use a long or short text depending on where it's used.
2023-10-13 07:55:47 +02:00
David Taylor
48193767bf DEV: Sort imports
Automatically generated by `eslint --fix` to satisfy the updated configuration
2023-10-10 21:46:54 +01:00
Joffrey JAFFEUX
a39ff830e8
UX: makes avatar non interactive in thread participants list (#23847)
It was slightly surprising to have a user card show when click on a thread item list.

More over this commit does:
- moves chat/user-avatar to chat-user-avatar and converts it to gjs
- moves chat/thread/participants to chat-thread-participants
- rewrite the `toggleCheckIfPossible` modifier to only be applied when selecting messages, it prevents the click event to collide with the click of avatars in regular messages
2023-10-09 21:12:50 +02:00
Joffrey JAFFEUX
42801c950f
UI: redesigned settings/members (#23804)
This PR is a first step towards private groups. It redesigns settings/members area of a channel and also drops the "about" page which is now mixed into settings.

This commit is also:
- introducing chat-form, a small DSL to create forms, ideally I would want something in core for this
- introducing a DToggleSwitch page object component to simplify testing toggles
- migrating various components to gjs
2023-10-09 14:11:16 +02:00
Andrei Prigorshnev
de8bb76065
DEV: Increase tests' stability by testing tooltips separately (#23516)
We noticed some of these tests were flaky, sometimes they fail on assertions 
related to testing tooltips. Tooltips are generally hard to test, and it's not 
necessary to test tooltips in every test case. This PR isolates tooltip testing 
in a dedicated test case.

Note we already did the same thing for another spec in a9dfda2 and that 
seems to worked well.
2023-10-06 16:51:31 +04:00
Joffrey JAFFEUX
2a10ea0e3f
DEV: FloatKit (#23650)
This PR introduces three new concepts to Discourse codebase through an addon called "FloatKit":

- menu
- tooltip
- toast


## Tooltips
### Component

Simple cases can be express with an API similar to DButton:

```hbs
<DTooltip 
  @Label={{i18n "foo.bar"}}
  @ICON="check"
  @content="Something"
/>
```

More complex cases can use blocks:

```hbs
<DTooltip>
  <:trigger>
   {{d-icon "check"}}
   <span>{{i18n "foo.bar"}}</span>
  </:trigger>
  <:content>
   Something
  </:content>
</DTooltip>
```

### Service

You can manually show a tooltip using the `tooltip` service:

```javascript
const tooltipInstance = await this.tooltip.show(
  document.querySelector(".my-span"),
  options
)

// and later manual close or destroy it
tooltipInstance.close();
tooltipInstance.destroy();

// you can also just close any open tooltip through the service
this.tooltip.close();
```

The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:

```javascript
const tooltipInstance = this.tooltip.register(
  document.querySelector(".my-span"),
  options
)

// when done you can destroy the instance to remove the listeners
tooltipInstance.destroy();
```

Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:

```javascript
const tooltipInstance = await this.tooltip.show(
  document.querySelector(".my-span"),
  { 
    component: MyComponent,
    data: { foo: 1 }
  }
)
```

## Menus

Menus are very similar to tooltips and provide the same kind of APIs:

### Component

```hbs
<DMenu @ICON="plus" @Label={{i18n "foo.bar"}}>
  <ul>
    <li>Foo</li>
    <li>Bat</li>
    <li>Baz</li>
  </ul>
</DMenu>
```

They also support blocks:

```hbs
<DMenu>
  <:trigger>
    {{d-icon "plus"}}
    <span>{{i18n "foo.bar"}}</span>
  </:trigger>
  <:content>
    <ul>
      <li>Foo</li>
      <li>Bat</li>
      <li>Baz</li>
    </ul>
  </:content>
</DMenu>
```

### Service

You can manually show a menu using the `menu` service:

```javascript
const menuInstance = await this.menu.show(
  document.querySelector(".my-span"),
  options
)

// and later manual close or destroy it
menuInstance.close();
menuInstance.destroy();

// you can also just close any open tooltip through the service
this.menu.close();
```

The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:

```javascript
const menuInstance = this.menu.register(
   document.querySelector(".my-span"),
   options
)

// when done you can destroy the instance to remove the listeners
menuInstance.destroy();
```

Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:

```javascript
const menuInstance = await this.menu.show(
  document.querySelector(".my-span"),
  { 
    component: MyComponent,
    data: { foo: 1 }
  }
)
```


## Toasts

Interacting with toasts is made only through the `toasts` service.

A default component is provided (DDefaultToast) and can be used through dedicated service methods:

- this.toasts.success({ ... });
- this.toasts.warning({ ... });
- this.toasts.info({ ... });
- this.toasts.error({ ... });
- this.toasts.default({ ... });

```javascript
this.toasts.success({
  data: {
    title: "Foo",
    message: "Bar",
    actions: [
      {
        label: "Ok",
        class: "btn-primary",
        action: (componentArgs) => {
          // eslint-disable-next-line no-alert
          alert("Closing toast:" + componentArgs.data.title);
          componentArgs.close();
        },
      }
    ]
  },
});
```

You can also provide your own component:

```javascript
this.toasts.show(MyComponent, {
  autoClose: false,
  class: "foo",
  data: { baz: 1 },
})
```

Co-authored-by: Martin Brennan <mjrbrennan@gmail.com>
Co-authored-by: Isaac Janzen <50783505+janzenisaac@users.noreply.github.com>
Co-authored-by: David Taylor <david@taylorhq.com>
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2023-09-26 13:39:52 +02:00
Joffrey JAFFEUX
85fddf58bc
Revert "DEV: FloatKit (#23541)" (#23549)
This reverts commits

0623ac684a
408e71e437
a32fa3b947

User tips were running into some issues.
2023-09-12 13:55:12 -04:00
Joffrey JAFFEUX
0623ac684a
DEV: FloatKit (#23541)
Second iteration of https://github.com/discourse/discourse/pull/23312 with a fix for embroider not resolving an export file using .gjs extension.

---

This PR introduces three new concepts to Discourse codebase through an addon called "FloatKit":

- menu
- tooltip
- toast


## Tooltips
### Component

Simple cases can be express with an API similar to DButton:

```hbs
<DTooltip 
  @label={{i18n "foo.bar"}}
  @icon="check"
  @content="Something"
/>
```

More complex cases can use blocks:

```hbs
<DTooltip>
  <:trigger>
   {{d-icon "check"}}
   <span>{{i18n "foo.bar"}}</span>
  </:trigger>
  <:content>
   Something
  </:content>
</DTooltip>
```

### Service

You can manually show a tooltip using the `tooltip` service:

```javascript
const tooltipInstance = await this.tooltip.show(
  document.querySelector(".my-span"),
  options
)

// and later manual close or destroy it
tooltipInstance.close();
tooltipInstance.destroy();

// you can also just close any open tooltip through the service
this.tooltip.close();
```

The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:

```javascript
const tooltipInstance = this.tooltip.register(
  document.querySelector(".my-span"),
  options
)

// when done you can destroy the instance to remove the listeners
tooltipInstance.destroy();
```

Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:

```javascript
const tooltipInstance = await this.tooltip.show(
  document.querySelector(".my-span"),
  { 
    component: MyComponent,
    data: { foo: 1 }
  }
)
```

## Menus

Menus are very similar to tooltips and provide the same kind of APIs:

### Component

```hbs
<DMenu @icon="plus" @label={{i18n "foo.bar"}}>
  <ul>
    <li>Foo</li>
    <li>Bat</li>
    <li>Baz</li>
  </ul>
</DMenu>
```

They also support blocks:

```hbs
<DMenu>
  <:trigger>
    {{d-icon "plus"}}
    <span>{{i18n "foo.bar"}}</span>
  </:trigger>
  <:content>
    <ul>
      <li>Foo</li>
      <li>Bat</li>
      <li>Baz</li>
    </ul>
  </:content>
</DMenu>
```

### Service

You can manually show a menu using the `menu` service:

```javascript
const menuInstance = await this.menu.show(
  document.querySelector(".my-span"),
  options
)

// and later manual close or destroy it
menuInstance.close();
menuInstance.destroy();

// you can also just close any open tooltip through the service
this.menu.close();
```

The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:

```javascript
const menuInstance = this.menu.register(
   document.querySelector(".my-span"),
   options
)

// when done you can destroy the instance to remove the listeners
menuInstance.destroy();
```

Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:

```javascript
const menuInstance = await this.menu.show(
  document.querySelector(".my-span"),
  { 
    component: MyComponent,
    data: { foo: 1 }
  }
)
```


## Toasts

Interacting with toasts is made only through the `toasts` service.

A default component is provided (DDefaultToast) and can be used through dedicated service methods:

- this.toasts.success({ ... });
- this.toasts.warning({ ... });
- this.toasts.info({ ... });
- this.toasts.error({ ... });
- this.toasts.default({ ... });

```javascript
this.toasts.success({
  data: {
    title: "Foo",
    message: "Bar",
    actions: [
      {
        label: "Ok",
        class: "btn-primary",
        action: (componentArgs) => {
          // eslint-disable-next-line no-alert
          alert("Closing toast:" + componentArgs.data.title);
          componentArgs.close();
        },
      }
    ]
  },
});
```

You can also provide your own component:

```javascript
this.toasts.show(MyComponent, {
  autoClose: false,
  class: "foo",
  data: { baz: 1 },
})
```

Co-authored-by: Martin Brennan <mjrbrennan@gmail.com>
Co-authored-by: Isaac Janzen <50783505+janzenisaac@users.noreply.github.com>
Co-authored-by: David Taylor <david@taylorhq.com>
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2023-09-12 15:50:26 +02:00
Joffrey JAFFEUX
b8cc1072cc
Revert "DEV: FloatKit (#23312)" (#23540)
This reverts commit abcdd8d367.
2023-09-12 15:37:16 +02:00
Joffrey JAFFEUX
abcdd8d367
DEV: FloatKit (#23312)
This PR introduces three new UI elements to Discourse codebase through an addon called "FloatKit":

- menu
- tooltip
- toast

Simple cases can be express with an API similar to DButton:

```hbs
<DTooltip
  @label={{i18n "foo.bar"}}
  @icon="check"
  @content="Something"
/>
```

More complex cases can use blocks:

```hbs
<DTooltip>
  <:trigger>
   {{d-icon "check"}}
   <span>{{i18n "foo.bar"}}</span>
  </:trigger>
  <:content>
   Something
  </:content>
</DTooltip>
```

You can manually show a tooltip using the `tooltip` service:

```javascript
const tooltipInstance = await this.tooltip.show(
  document.querySelector(".my-span"),
  options
)

// and later manually close or destroy it
tooltipInstance.close();
tooltipInstance.destroy();

// you can also just close any open tooltip through the service
this.tooltip.close();
```

The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:

```javascript
const tooltipInstance = this.tooltip.register(
  document.querySelector(".my-span"),
  options
)

// when done you can destroy the instance to remove the listeners
tooltipInstance.destroy();
```

Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:

```javascript
const tooltipInstance = await this.tooltip.show(
  document.querySelector(".my-span"),
  {
    component: MyComponent,
    data: { foo: 1 }
  }
)
```

Menus are very similar to tooltips and provide the same kind of APIs:

```hbs
<DMenu @icon="plus" @label={{i18n "foo.bar"}}>
  <ul>
    <li>Foo</li>
    <li>Bat</li>
    <li>Baz</li>
  </ul>
</DMenu>
```

They also support blocks:

```hbs
<DMenu>
  <:trigger>
    {{d-icon "plus"}}
    <span>{{i18n "foo.bar"}}</span>
  </:trigger>
  <:content>
    <ul>
      <li>Foo</li>
      <li>Bat</li>
      <li>Baz</li>
    </ul>
  </:content>
</DMenu>
```

You can manually show a menu using the `menu` service:

```javascript
const menuInstance = await this.menu.show(
  document.querySelector(".my-span"),
  options
)

// and later manually close or destroy it
menuInstance.close();
menuInstance.destroy();

// you can also just close any open tooltip through the service
this.menu.close();
```

The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:

```javascript
const menuInstance = this.menu.register(
   document.querySelector(".my-span"),
   options
)

// when done you can destroy the instance to remove the listeners
menuInstance.destroy();
```

Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:

```javascript
const menuInstance = await this.menu.show(
  document.querySelector(".my-span"),
  {
    component: MyComponent,
    data: { foo: 1 }
  }
)
```

Interacting with toasts is made only through the `toasts` service.

A default component is provided (DDefaultToast) and can be used through dedicated service methods:

- this.toasts.success({ ... });
- this.toasts.warning({ ... });
- this.toasts.info({ ... });
- this.toasts.error({ ... });
- this.toasts.default({ ... });

```javascript
this.toasts.success({
  data: {
    title: "Foo",
    message: "Bar",
    actions: [
      {
        label: "Ok",
        class: "btn-primary",
        action: (componentArgs) => {
          // eslint-disable-next-line no-alert
          alert("Closing toast:" + componentArgs.data.title);
          componentArgs.close();
        },
      }
    ]
  },
});
```

You can also provide your own component:

```javascript
this.toasts.show(MyComponent, {
  autoClose: false,
  class: "foo",
  data: { baz: 1 },
})
```

Co-authored-by: Martin Brennan <mjrbrennan@gmail.com>
Co-authored-by: Isaac Janzen <50783505+janzenisaac@users.noreply.github.com>
Co-authored-by: David Taylor <david@taylorhq.com>
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2023-09-12 15:06:51 +02:00
Joffrey JAFFEUX
4f8d52bbcb
UX: hides header's unread indicator on full page (#23370)
The unread(s) will still show in the sidebar, outside of chat and when in drawer mode. This is to prevent the confusion to show an unread count for chat on a button which is going to take the user out of chat.
2023-09-02 12:06:40 +02:00
Mark VanLandingham
9c65e2140a
DEV: Use Notice API for mention warnings (#23238)
This PR swaps out the custom pathway to publishing and rendering mention warnings after a message is sent.

ChatPublisher#publish_notice is used, and expanded. Now, instead of only accepting text_content as an argument, component and component_args are accepted and there is a renderer for these components.

Translations moved to server, as notices expect text to be passed in unless a component is rendered

The warnings are rendered at the top now, outside of the scope of the single message that sent it.

I entirely removed the jit_messages_spec b/c it's duplicate testing of other parts of the app. IMO we don't need a backend test for a feature, a component test for the feature AND a system test (that is slow and potentially even flakey due to timing issues with wait) to test the same thing. So jit_messages_spec is gone.
2023-09-01 09:07:23 -05:00
Joffrey JAFFEUX
d4322a69db
UX: hides original message user in thread participants (#23350)
Usage:

```hbs
<Chat::Thread::Participants
  @thread={{@thread}}
  @includeOriginalMessageUser={{false}}
/>
```
2023-08-31 14:46:37 +02:00
Mark VanLandingham
68eba53e09
FEATURE: Chat global mention warnings (pre-send & post-send) (#22764)
This is also fixes the issue of chat composer warnings persisting across channels. Currently if you try to mention more groups than is allowed for example, a mention warning pops up. When you change channels the mention warning will not disappear even if there is no text in the composer.

This adds a reset function to the chat-composer-warnings-tracker.js, which is called when the channel is changed and the message is empty. In the event that the message is not empty we call captureMentions to check the loaded drafts' mentions.

This PR would be nicer if the post-send notice used the new chat notices API to publish the mention warnings but we would have to change the existing ones and I thought that would be too much change for this PR. It'd be a good followup though.
2023-08-22 15:54:35 -05:00
Joffrey JAFFEUX
b03c26ebf5
FIX: correctly handles mobile and default (#23152)
This commit ensures we have correct icon and title on mobile for the chat header icon.

It also fixes a bug where the site setting was not correctly used when the user has not yet set the user option.

Both cases are now correctly tested.
2023-08-18 22:32:43 +02:00
Joffrey JAFFEUX
b2b84cc957
FEATURE: implements user based sidebar mode (#23078) 2023-08-18 20:33:07 +02:00
Joffrey JAFFEUX
2d567cee26
FEATURE: thread pagination (#22624)
Prior to this commit we were loading a large number of thread messages without any pagination. This commit attempts to fix this and also improves the following points:

- code sharing between channels and threads:
Attempts to reuse/share the code use in channels for threads. To make it possible part of this code has been extracted in dedicated helpers or has been improved to reduce the duplication needed.

Examples of extracted helpers:
- `stackingContextFix`: the ios hack for rendering bug when momentum scrolling is interrupted
- `scrollListToMessage`, `scrollListToTop`, `scrollListToBottom`:  a series of helper to correctly scroll to a specific position in the list of messages

- better general performance of listing messages:
One of the main changes which has been made is to remove the computation of visible message during scroll, it will only happen when needed (update last read for example). This constant recomputation of `message.visible` on intersection observer event while scrolling was consuming a lot of CPU time.
2023-07-27 09:57:03 +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
Joffrey JAFFEUX
10f6395545
Revert "FIX: correctly respects full name settings in channel title (#22566)" (#22569)
This reverts commit aa9c7dc924.
2023-07-12 18:46:19 +02:00
Joffrey JAFFEUX
aa9c7dc924
FIX: correctly respects full name settings in channel title (#22566) 2023-07-12 16:59:47 +02:00