Commit Graph

621 Commits

Author SHA1 Message Date
David Battersby
79ececd976
FIX: handle thread participants limit on the frontend (#23839)
Workaround for an issue we are experiencing on thread index frontend where thread loads participants correctly (up to 10), then refreshes the threads and then limits to 3 participants.

There is an issue with storing threads for the main channel view and the thread list in the same store so handling the max participants on the frontend is a workaround until channel.threadsManager is updated.

I've adjusted the tests to handle the additional data being returned from ThreadParticipantQuery.
2023-10-09 14:04:59 +08:00
chapoi
85c6914f80
UX: thread list fixes for alignment and more spacing on mobile (#23823)
* UX: fix padding on active touch
* UX: thread list header bigger + alignment
* UX: thread list alignment desktop
* UX: visual corrections to alignment
* UX: mobile alignment and padding
2023-10-07 11:06:16 +02:00
chapoi
cac5592251
UX: flat design for thread list (#23821)
* UX: thread list flat design

* UX: thread list mobile
2023-10-06 21:56:36 +02:00
chapoi
478e738bfd
UX: keep timestamp on single line (#23819) 2023-10-06 20:07:52 +02:00
chapoi
057c2012f0
UX: remove excerpt + style change to thread list item (#23776)
UX changes to thread item:

- drop "last reply" timestamp copy
- drop last reply excerpt
- show up 9+OP members

Co-authored-by: David Battersby <info@davidbattersby.com>
2023-10-06 15:11:04 +02:00
Joffrey JAFFEUX
9e5fc2e817
FIX: correctly checks user activation on use (#23793)
We can't have it computed only at start of the application as the state wouldn't most likely be false at this point in time.
2023-10-05 11:24:01 +02:00
Joffrey JAFFEUX
a1aedc9ce1
DEV: removes dead code (#23772) 2023-10-04 20:02:57 +02:00
Joffrey JAFFEUX
08df8fc1d1
UX: enhances chat copy features (#23770)
- Allows to copy quotes from mobile
- Allows to copy text of a message from mobile
- Allows to select messages by clicking on it when selection has started

Note this commit is also now using toasts to show a confirmation of copy, and refactors system specs helpers concerning secondary actions.

<!-- 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-10-04 16:14:37 +02:00
Jarek Radosz
6adc67a7a8
FIX: Broken error reporting in modals (and other places) (#23680)
1. actually call `popupAjaxError`, thanks :P
2. don't close a modal on error
3. use `extractError()` instead of manually joining error messages
4. …or passing just the error object to `this.flash`
2023-09-27 17:11:44 +02:00
Joffrey JAFFEUX
db558dc3fc
FIX: correctly sort channels with null last message (#23672)
As per 92839dc722 lastMessage won't be null when a message is deleted. This would cause sorting issues when messages from a direct message channels are deleted as we would try to sort on last message and thought it would exist when actually it would be a null message.

I might rethink this design to not return any last_message in this case soon as checking on ID feels dirty and prone to error, so only fixing the issue for now.

This commit is also using `@cached` to avoid replaying the sort logic on each access.
2023-09-26 20:36:51 +02:00
David Taylor
a673004777
DEV: Modernize chat getOwner usage (#23671)
See 8958b4f76a for motivation
2023-09-26 18:05:34 +01: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
Kris
91c94f5aa6
DEV: update a couple button classes (#23127) 2023-09-25 16:45:57 -04:00
Joffrey JAFFEUX
c8fff19b99
DEV: removes the notion of staged thread (#23612)
While very fast and powerful staged threads forces a lot of gymnastic and edge cases. This patch adds a new service `Chat::CreateThread` and uses it to create a thread unconditionally when a user replies to a message in a threading enabled channel. If the user actually doesn’t send a message we will have a thread with no messages which has no important impact and could even be periodically cleaned if necessary.

Note that this commit also moves message actions to .gjs as it was the original goal of this PR to correctly check for staged thread to show the menu or not.
2023-09-15 18:09:45 +02:00
chapoi
8823b5e504
UX: fix overflow channel row + mobile remove styling tweak (#23611)
* UX: fix missing overflow ellipsis

* cleanup double declaration

* UX: add missing border-radius

*UX: delete icon animation tweak
2023-09-15 14:06:31 +02:00
David Battersby
e6c97ffece
FIX: message date is incorrect when replying as new thread (#23608)
When creating a new thread by clicking the reply button on a chat message, it shows an invalid date on the OP timestamp.
2023-09-15 16:22:49 +08:00
chapoi
02de223da8
UX: chat-channel-row alignment (#23607) 2023-09-15 10:09:50 +02:00
Kris
98c8dcecba
A11Y: disable non-essential CSS animations for reduced-motion users (#23571) 2023-09-14 17:31:43 -04:00
Jarek Radosz
4a1621c677
DEV: Use the Store to create User records (#23584) 2023-09-14 23:26:51 +02:00
Joffrey JAFFEUX
ae27beb01a
UI: improves remove channel animation (#23585)
Co-authored-by: chapoi <101828855+chapoi@users.noreply.github.com>
2023-09-14 18:48:29 +02:00
David Taylor
8a57798419
DEV: Update discourse-local-dates to new Modal API (#23560) 2023-09-13 15:00:38 +01:00
David Battersby
7f7e7fe516
Revert "FEATURE: Add chat message notifications for personal chats (#23307)" (#23559)
This reverts commit 0a1a07fff8.
2023-09-13 19:33:22 +08:00
David Battersby
0a1a07fff8
FEATURE: Add chat message notifications for personal chats (#23307)
This feature adds notifications for chat messages that are sent within personal chats (1:1 and personal group chats).

To prevent notification spam we make use of consolidated notifications to combine updated message information in a meaningful way that allows the receiver to quickly jump into the chat to see what they missed.

This update respects muted channels, muted and blocked users. It will only create a new notification when the user has not muted the channel and the notified user is not muting or ignoring the message sender.
2023-09-13 17:15:11 +08: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
David Taylor
c3061d580c
DEV: Remove decorateCookedElement id parameters (#23544)
These are no longer required per https://github.com/discourse/discourse/pull/23543
2023-09-12 16:32:04 +01: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
Jan Cernik
d9238fb01b
FIX: chat layout shift when loading videos (#23537) 2023-09-12 15:01:17 +02:00
Jan Cernik
d9a2595e7c
FIX: Prevent chat message actions to disappear on mouseleave (#23063) 2023-09-11 16:54:01 -03:00
Joffrey JAFFEUX
898c75a05c
FIX: ensures swipe works with scroll (#23508)
- do not prevent the event (it was a violation anyways as the touchstart is passive)
- waits for at least 25px horizontal move before showing the remove action, it avoids showing the remove while scrolling and moving a little bit horizontally
2023-09-11 15:39:54 +02:00
Joffrey JAFFEUX
b8d5f951f6
UX: implements swipe on row channel (#23436)
On mobile swiping a channel row will now show a "Remove" option. Holding this to the end will now remove this row from your list of followed direct message channels.

Co-authored-by: chapoi <101828855+chapoi@users.noreply.github.com>
2023-09-11 14:51:13 +02:00
David Battersby
e771382c1c
DEV: active record validations for maxlength on text columns (#23499)
Introduce max length on text columns for description and slug fields within chat.

At a later date we will probably want to convert these text columns to string/varchar through a migration, but for now this change introduces a limit within the active record model.
2023-09-11 17:05:02 +08:00
Kris
22747e26fd
DEV: common CSS property for content backgrounds (#23467) 2023-09-08 12:07:04 -04:00
chapoi
cde5dea74f
UX: popping animation for adding users (#23459)
* UX:  popping animation for adding users

* accessibility wrapper
2023-09-07 15:42:49 +02:00
Andrei Prigorshnev
73781c8a96
FIX: Do not consider code-blocks when parsing mentions (#23280)
We have the max_mentions_per_chat_message site settings; when a user tries 
to mention more users than allowed, no one gets mentioned.

Chat messages may contain code-blocks with strings that look like mentions:

  def foo
    @bar + @baz
  end

The problem is that the parsing code considers these as real mentions and counts 
them when checking the limit. This commit fixes the problem.
2023-09-07 16:13:13 +04:00
chapoi
bf971b022d
UX: lower z-index (#23386)
* UX: lower z-index

* Update plugins/chat/assets/stylesheets/common/chat-side-panel-resizer.scss

Co-authored-by: Jarek Radosz <jradosz@gmail.com>

---------

Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2023-09-04 22:30:51 +02:00
Andrei Prigorshnev
3ee77c29a5
DEV: no need to track status of a deleted user (#22836)
It is hard to catch and debug potential bugs related to live updates of user status 
(though, we haven't seen many such bugs so far). We have a `console.warn` 
statement that should help us to catch one class of such bugs.

Recently, we noticed that this warning gets printed when a user had a chat with 
a user that was then deleted.

This is not a bug, since there is nothing to track for a deleted user, but we don't 
want this noise on the console. This PR makes sure we don't print a warning in 
such cases.
2023-09-04 17:00:09 +04: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
ed35ae4dcd
FIX: closes chat emoji picker on body scroll (#23362)
Prior to this fix we would scroll the emoji picker with the body of the page in drawer mode.

With this fix scrolling inside the drawer or the emoji picker will scroll the drawer or the emoji picker, but, scrolling body will close the chat emoji picker.
2023-09-01 09:17:48 +02:00
Jordan Vidrine
72f33d1d5d
FIX: Chat message button radius (#23358) 2023-08-31 15:00:39 -05:00
chapoi
c9c2a73441
UX: thread list design changes (#23348) 2023-08-31 18:09:41 +02: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
Jarek Radosz
1c87bb7fe9
DEV: Update DButton uses (#23333)
1. Use `this.` instead of `{{action}}` where applicable
2. Use `{{fn}}` instead of `@actionParam` where applicable
3. Use non-`@` versions of class/type/tabindex/aria-controls/aria-expanded
4. Remove `btn` class (it's added automatically to all DButtons)
5. Remove `type="button"` (it's the default)
6. Use `concat-class` helper
2023-08-31 11:49:35 +02:00
chapoi
a97dcd8564
UX: composer fixes (#23334)
* UX: fix disappearing separator

* UX: slightly smaller composer btns on non-mobile
2023-08-30 15:10:21 +02:00
Jarek Radosz
f6cd8e5968
DEV: Remove redundant braces (#23321) 2023-08-30 10:37:03 +02:00
Martin Brennan
bbd908ae09
FIX: Add hashtag placeholder when chat message sent (#23287)
This commit fixes an issue from 2ecc8291e8
where the user sees an ugly plain #hashtag when sending a chat
message. Now, we add a basic placeholder that looks like the
cooked hashtag with a grey square, which is then filled in
once the "sent" message bus event for the message comes back,
and we do decorateCooked on the message to fill in the proper
hashtag details.
2023-08-30 11:31:34 +10:00
Ted Johansson
7a4119846c
FIX: Include 'notify staff' separator in chat message flag modal (#23301)
When flagging a chat message, and options included both notifying user and notifying staff, the modal was missing the separating text. This was happening because the #staffFlagsAvailable method was based on post flags, and the model for chat flags is slightly different. This fixes that by delegating to the relevant flag target object.
2023-08-29 15:26:14 +08:00
Isaac Janzen
026cd3e532
DEV: Convert flag modal to component-based API (#23279)
# Topic Flag
<img width="587" alt="Screenshot 2023-08-28 at 10 53 12 AM" src="https://github.com/discourse/discourse/assets/50783505/6ffe4e47-05a6-406c-9d1b-899ff4d5c2c9">

# Post Flag
<img width="620" alt="Screenshot 2023-08-28 at 10 52 44 AM" src="https://github.com/discourse/discourse/assets/50783505/1f893916-b62f-4825-a337-4c0e0e4ce3af">

# Chat Flag
<img width="648" alt="Screenshot 2023-08-28 at 10 52 31 AM" src="https://github.com/discourse/discourse/assets/50783505/e79444e8-a8b1-4f05-9b47-03d425bc9085">
2023-08-28 16:51:58 -05:00