This commit introduces a new property `hasNoPreferredMode` to the
chat state manager, which represents a user who has not purposely
set chat mode to drawer or full page, meaning they have no LocalStorage
value set.
This can be useful for themes to change the chat mode but only
if the user has no preference already.
c.f.
https://meta.discourse.org/t/full-screen-chat-as-default-for-collaboration-setup/369849
When uploading videos in chat using Safari the thumbnail isn't being
displayed
so we need to trick the browser to by adding the timestamp property so
that it
will fetch the metedata the html5 video tag needs to render the
thumbnail.
For empty chats, a dummy message is created with `id=null` (an
unsaved Ember model).
The timer or placeholder's display is determined by the message ID's presence now (not the `createdAt` prop).
This change polishes the emoji diversity rendering behaviour in the emoji pickers. When a user changes their diversity setting, that setting will now be applied to favourites, chat default reactions, and in the emoji picker section selectors.
If an emoji was previously stored with a skin tone in favourites or default reactions, the stored skin tone won't be overridden.
Introduces the viewport_based_mobile_mode experimental site setting.
When enabled, user-agent-based mobile/desktop detection will be replaced
with viewport-width logic. 'mobile mode' is enabled for any viewport
less than our 'sm' breakpoint (40rem, or 640px at default font size).
When this mode is enabled, mobile/desktop toggle buttons are hidden,
since they are non-functional.
Tests are also updated to use a consistent method for force-enabling the
legacy mobile mode. All state is now stored in `lib/mobile`, and the
`Site` model references that via a getter.
- When using the Glimmer Post Stream, ensure the status wrapper is only
rendered for mentions of users with a status set.
This prevents an empty wrapper from adding a small blank space at the
end of the mention.
- Ensures the post's user field in initialized with the
`avatar_template` in the PostStream to prevent missing avatar on small
actions
- Fix an issue where the path would be incorrectly linked on small
actions
- Fix an issue where the relative timestamp would be incorrectly
displayed in wiki posts
This commit allows the ProseMirror rich editor to display chat
transcripts copied from chat using the "Copy" button.
The BBCode usually looks something like this:
```
[chat quote="hunter;29856;2025-03-20T07:13:04Z" channel="design gems 🎉" channelId="95"]
haha **ok** _cool_
[/chat]
```
But there are several variations that must be accounted for:
* Single message from single user
* Multiple messages from a single and multiple users
* Messages inside chat threads
The rich transcript extension has to ignore many of the chat transcript
markdown
tokens because they simply aren't necessary -- none of the ProseMirror
nodes need
to be editable. So, we basically recreate the same HTML that the chat
transcript markdown
rule does in the `toDOM()` function. Maybe in future we want to make the
markdown rule
do less and have this HTML creation in one place, but for now we need to
mirror in both files.
---------
Co-authored-by: Renato Atilio <renato@discourse.org>
When tapping something on a touch-enabled device, `mouseMove` events are
still fired, so floatkit would still be triggered even if configured for
'hover' only. For links, this would be particularly strange, because the
tooltip would appear for a split-second, before the page navigation
occured.
To avoid this problem, we can use the more-modern 'pointerMove' event,
and check the `pointerType` to exclude 'touch'
`discourse-common` was created in the past to share logic between the
'wizard' app and the main 'discourse' app. Since then, the wizard has
been consolidated into the main app, so the separation of
`discourse-common` is no longer useful.
This commit moves `discourse-common/(lib|utils)/*` into
`discourse/lib/*`, adds shims for the imports, and updates existing
uses in core.
The chat emoji picker is renamed emoji-picker, and the old emoji-picker is removed.
This commit doesn't attempt to fully rework a new emoji-picker but instead tries to migrate everything to one picker (the chat one) and add small changes.
Other notable changes:
- all the favorite emojis code has been mixed into one service which is able to store one state per context, favorites emojis will be stored for all topics, and for each chat channel. Meaning that if you always use a specific emoji in a channel, it will only show as favorite emoji in this channel.
- a lot of static code has been removed which should improve initial load perf of discourse. Initially this code was around to improve the performance of the emoji picker rendering.
- the emojis are now stored, once the full list has been loaded, if you close and reopen the picker it won't have to load them again.
List of components:
- `<EmojiPicker />` will render a button which will open a dropdown
- `<EmojiPickerContent />` represents the content of the dropdown alone, it's useful when you want to render a picker from an action which is not the default picker button
- `<EmojiPickerDetached />` just a simple wrapper over `<EmojiPickerContent />` to make it easier to use it with `this.menu.show(...)`
---------
Co-authored-by: Renato Atilio <renatoat@gmail.com>
We were using a complex logic to make it change size based on scroll position but this was imperfect and not visually pleasing. Also the title had been made a button which was causing the ellipsis to not work correctly, and I would prefer to not mix page knowledge (thread) with title component so I made this click logic directly in the chat-thread component.
---------
Co-authored-by: Jordan Vidrine <jordan@jordanvidrine.com>
https://github.com/mainmatter/qunit-dom/blob/master/API.md#isvisible will return true if offsetWidth or offsetHeight are zero which could happen in this case as the test could run before the image has loaded. By forcing a minimum height in the test we ensure it will be consistent.
The markdown it rule "heading" will only be used when the message is done by a bot, which means an id < 0.
This commit also adds a is-bot css class on messages made by a bot, for finer control.
---------
Co-authored-by: Martin Brennan <mjrbrennan@gmail.com>
This change makes use of service workers to determine if we should play chat sounds in the current browser tab. Since users can have multiple tabs open, we currently attempt to play sound across all active tabs.
With this change we iterate over all clients and check if client.focused is true (ie. the current tab/window we have open), if so we allow playing the audio in the current tab and for all other hidden tabs/windows we return false.
---------
Co-authored-by: Bianca Nenciu <nbianca@users.noreply.github.com>
Key changes include:
- `@uppy/aws-s3-multipart` is now part of `@uppy/aws-s3`, and controlled with a boolean
- Some minor changes/renames to Uppy APIs
- Uppy has removed batch signing from their S3 multipart implementation. This commit implements a batching system outside of Uppy to avoid needing one-signing-request-per-part
- Reduces concurrent part uploads to 6, because S3 uses HTTP/1.1 and browsers limit concurrent connections to 6-per-host.
- Upstream drop-target implementation has changed slightly, so we now need `pointer-events: none` on the hover element
Makes channel_id and is_direct_message_channel consistent across desktop notifications, which also removes the need to lookup the channel from Chat Notification Manager.
This change adds full names to direct message channel titles when the following conditions are met:
- SiteSetting.enable_names = true
- SiteSetting.display_name_on_posts = true
- SiteSetting.prioritize_username_in_ux = false
If a user's full name is blank, it will fallback to their username in both 1-1 channels and Group DM channels.