Commit Graph

1829 Commits

Author SHA1 Message Date
8dc772f2a8 UX: prevent shrinking unread badge for long DM channel names (#29756)
Fixes a small UX issue where the unread badge gets squashed in long DM channel names.
2024-11-14 15:27:14 +04:00
5ce4af1aa6 FEATURE: add mention count to threads (#29739)
Previously we only counted mentions that were made within channels, however for threads this was never implemented.

This change adds a mention count to the ThreadUnreadsQuery, which is used for channel thread lists and the user thread list. We are also expanding channel mentions count to include mentions within threads.

The goal is to have a more consistent urgent badge across chat, in places such as channel lists and the chat header.
2024-11-14 14:10:12 +04:00
fea82d04ec DEV: fix chat:*:populate rake tasks (#29740) 2024-11-13 18:11:25 +01:00
b4156107df DEV: restore AutoJoinChannelBatch job as a no-op to clear queue (#29743)
The job was removed in 6dfe2fbe16a4096ff342ec8b626ac62a19eaa180 as part of a performance-related refactor.

The issue was that job was already enqueued in sidekiq and now that the file has been deleted, it's generating a lot of `uninitialized constant Jobs::Chat::AutoJoinChannelBatch` errors.

Restoring this file will help clear the sidekiq queue. We'll remove the job in a few months.

Internal ref - t/141563
2024-11-13 18:10:03 +01:00
234133bd3b UX: Split hide_profile_and_presence user option (#29632)
It splits the hide_profile_and_presence user option and the default_hide_profile_and_presence site setting for more granular control. It keeps the option to hide the profile under /u/username/preferences/interface and adds the presence toggle in the quick user menu.

Co-authored-by: Régis Hanol <regis@hanol.fr>
2024-11-12 22:22:58 -03:00
d637bd6519 DEV: Don’t replace Rails logger in specs (#29721)
Instead of replacing the Rails logger in specs, we can instead use
`#broadcast_to` which has been introduced in Rails 7.
2024-11-13 08:47:39 +08:00
d7503a6153 Update translations (#29715) 2024-11-12 14:54:38 +01:00
fb2a688b29 DEV: Bump eslint, lint-configs, and move to flat config (#29661) 2024-11-12 12:33:17 +00:00
6dfe2fbe16 PERF: auto join & leave chat channels (#29193)
Chat channels that are linked to a category can be set to automatically join users.

This is handled by subscribing to the following events

- group_destroyed
- user_seen
- user_confirmed_email
- user_added_to_group
- user_removed_from_group
- category_updated
- site_setting_changed (for `chat_allowed_groups`)

As well as a

- hourly background job (`AutoJoinUsers`)
- `CreateCategoryChannel` service
- `UpdateChannel` service

There was however two issues with the current implementation

1. We were triggering a lot of background jobs, mostly because it was decided to batch to auto join/leave into groups of 1000 users, adding a lot of stress to the system
2. We had one "class" (a service or a background job) per "event" and all of them had slightly different ways to select users to join/leave, making it hard to keep everything in sync

This PR "simply" adds two new servicesL `AutoJoinChannels` and `AutoLeaveChannels` that takes care, in an efficient way, of all the cases when users might automatically join a leave a chat channel.

Every other changes come from the fact that we're now always calling either one of those services, depending on the event that happened.

In the making of these classes, a few bugs were encountered and fixed, notably

- A user is only ever able to access chat channels if and only if they're part of a group listed in the `chat_allowed_group` site setting
- A category that has no associated "category groups" is only accessible to staff members (and not "Everyone")
- A silenced user should not be able to automatically join channels
- We should not attempt to automatically join users to deleted chat channels
- There is no need to automatically join users to chat channels that have already more than `max_chat_auto_joined_users` users

Internal - t/135259 & t/70607

* DEV: add specs for auto join/leave channels services

* DEV: less hacky specs

* DEV: no instance variables in specs
2024-11-12 15:00:59 +11:00
e68905510d DEV: Use the new hasHtml/includesHtml from qunit-dom (#29680) 2024-11-11 13:06:12 +01:00
2272b1340b DEV: Use qunit-dom instead of raw href/title comparisons (#29678) 2024-11-11 11:44:54 +01:00
c4de8565ec FIX: flakey due to 0 width/height images (#29700)
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.
2024-11-11 17:23:19 +09:00
78ed0bb711 DEV: Use selectors instead of query() where possible (#29677) 2024-11-10 13:53:12 +01:00
d67a6002eb DEV: Replace count with qunit-dom (#29674) 2024-11-10 02:06:03 +01:00
f9e58938ce DEV: Update visible/invisible uses to qunit-dom (#29672) 2024-11-10 01:41:50 +01:00
de6d575d40 DEV: Convert all uses of exists to qunit-dom (#29667) 2024-11-10 01:30:33 +01:00
c1916f7984 DEV: Convert assert.true(exists()) to qunit-dom (#29638) 2024-11-08 20:27:32 +01:00
534e8c1628 UX: update chat channel sorting to include unread threads (#29617)
Adds channels with unread threads (watching/tracking) to the sorting logic for both public and direct message channels.

Previously channels with unread threads could easily be missed as we didn't bump them to the top when new thread replies were created.

We are also adding a blue unread badge next to DM channels when there is an unread thread, as previously they weren't appearing as unread within the DMs tab (they only showed within the My Threads section).
2024-11-08 12:31:03 +04:00
467ecbabf5 FIX: supports escape sequence in chat (#29659)
Writing `\*test\*` will now correctly cook `*test*`, and not `<em>test</em>`.
2024-11-08 15:28:50 +09:00
032b1f871b DEV: cook grid bbcode in chat (#29658)
This change will only prevent a cooked message with [grid] to show [grid] instead the content will be wrapped in `div class="d-image-grid"`. This is only enabled on messages made by bot, as regular users could use grid but have no reason to use it ATM. It will also not apply the decoration which shouldn't change the behavior more than just remove grid markup from the message
2024-11-08 14:43:28 +09:00
1d9f064d83 FIX: correctly account for composer height in PWA (#29656) 2024-11-08 11:16:15 +09:00
79254c59f9 FIX: correctly render unicode in channel page title (#29653)
Before this fix we would render the emoji as text, eg: `🐱`
2024-11-08 09:41:14 +09:00
fc5c0270f7 FIX: ensures thread panel closes on escape (#29651)
`chatThreadPane.isOpened` was returning `false` when it should return `true` due to an incorrect matching on the route.

Note that visiting a thread will focus the composer and the first escape will blur the input, only the second will close the panel.
2024-11-08 09:19:24 +09:00
4840060568 DEV: fix flakey by duplicating constant (#29636)
Some checks are pending
Tests / core frontend (${{ matrix.browser }}) (Firefox ESR) (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Firefox Evergreen) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (annotations, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (backend, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (backend, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (frontend, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (frontend, themes) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, chat) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, themes) (push) Waiting to run
Licenses / run (push) Waiting to run
Linting / run (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Chrome) (push) Waiting to run
This is because rules is pointing to the same array MARKDOWN_IT_RULES, which is modified directly. Modifying rules with << changes the original MARKDOWN_IT_RULES array, so every call to something works with the altered array state from previous calls.
2024-11-07 23:51:17 +09:00
5010fced92 DEV: only supports headings in messages for bots (#29585)
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>
2024-11-07 22:27:35 +09:00
3d1571a852 UX: do not hide topic composer in mobile chat (#29633) 2024-11-07 14:49:59 +09:00
da43deb9ea DEV: Fix mismatched column types (#29477)
The primary key is usually a bigint column, but the foreign key columns
are usually of integer type. This can lead to issues when joining these
columns due to mismatched types and different value ranges.

This was using a temporary plugin / test API to make tests pass. After
more careful consideration, we concluded that it is safe to alter the
tables directly.

Even for larger communities, with about 1M chat messages, the
slowest `ALTER` query runs in about 15 seconds, which well under the 30
seconds query timeout limit. As a result, chat messages will be delayed
for a few seconds, but the system will remain operational.
2024-11-06 20:00:40 +02:00
6158a1ae29 DEV: Refactor the Chat::CreateThread service a bit
Follow best practices from our docs.
2024-11-06 15:53:43 +01:00
57f4176b57 DEV: Bump rubocop_discourse (#29608) 2024-11-06 06:27:49 +08:00
8a201c1e92 Update translations (#29595) 2024-11-05 16:55:45 +01:00
54e7dee6d7 FIX: Chat uploads over-secured in some situations (#29586)
Some checks are pending
Licenses / run (push) Waiting to run
Linting / run (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (annotations, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (backend, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (backend, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (frontend, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (frontend, themes) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, chat) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, themes) (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Chrome) (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Firefox ESR) (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Firefox Evergreen) (push) Waiting to run
In the case where:

* Secure uploads were enabled
* Allow unsecure chat uploads was enabled
* For a site with login required enabled

When a chat upload was created, it was being marked as secure. Since
there is no provision for secure uploads in chat, this would lead to
broken uploads/images shown in the channel.

We can use the "public types" functionality of secure uploads to make
sure we never mark chat uploads as secure, and we can revisit this
whenever we get around to allowing secure uploads in chat.
2024-11-05 15:56:30 +10:00
380974ce00 DEV: Use hasAttribute/hasAria/hasStyle in tests (#29568) 2024-11-04 11:30:38 +01:00
9694d2477a DEV: Convert more notOk assertions (#29556)
…to either qunit-dom or `strictEqual`
2024-11-04 10:27:30 +01:00
88eb96b315 DEV: sets an icon_upload_id on a channel (#29566)
There's no UI for it at the moment but when creating a channel or updating it, it's now possible to pass `icon_upload_id` as param. This will be available on the channel as `icon_upload_url`.
2024-11-04 17:19:44 +09:00
ce76b88eb2 DEV: start/stop reply implementation (#29542)
* DEV: join/leave presence chat-reply when streaming

This commit ensures that starting/stopping a chat message with the streaming option will automatically make the creator of the message as present in the chat-reply channel.

* implements start/stop reply

* not needed
2024-11-04 08:14:35 +11:00
279fc846db FEATURE: adds support for headings in chat (#29552)
```
```

Will now be converted into their html versions: <h1>, <h2>, <h3>, ...
2024-11-04 08:11:53 +11:00
b81055a6d4 DEV: Convert more equal assertions (#29554)
…to either qunit-dom or `strictEqual`
2024-11-03 21:04:38 +01:00
Sam
e7f62ab52b FEATURE: add custom fields to chat (channel/message/thread) (#29504)
This allows various extensions to store extra information the 3 most popular
chat entities

Useful for certain plugins and migrations
2024-11-01 09:12:19 +11:00
041ac3d8b7 DEV: Refactor header offset calculations (#29398) 2024-10-31 09:50:01 -04:00
ec480e99ef FIX: show chat thread notifications for direct message channels (#29414)
When adding threads to DM channels in #29170 we intentionally didn't add them to the My Threads section. However this makes it easy to miss notifications as we don't get the new thread badge on the sidebar and footer tabs (drawer/mobile). However they were also missing from the chat header and sidebar too, which is fixed with this PR.

When a new thread or a reply to an existing thread is created within a DM channel (either 1:1 or group), we now show the standard badges like we do for public channels.

We now also show the green dot in the sidebar for My Threads and public channels when they contain an unread watched thread.
2024-10-31 10:50:11 +04:00
2ffe413b0b FEATURE: Enable the new /about page for everyone (#29390)
This commit removes the feature flag for the new /about page, enabling it for all sites, and removes the code for old the /about page.

Internal topic: t/140413.
2024-10-29 18:40:11 +03:00
2f334964f2 DEV: Remove hash-like access from service contracts
We decided to keep only one way to access values from a contract. This
patch thus removes the hash-like access from contracts.
2024-10-29 16:02:51 +01:00
4d0ed2e146 Update translations (#29467) 2024-10-29 15:31:41 +01:00
35f441739c UX: fix emoji alignment in chat members user status (#29466)
Improves layout of channel members list with user status emojis.
2024-10-29 17:18:09 +04:00
c78211cf8d DEV: Make service contracts immutable
We decided to make contracts immutable once their validations have run.
Indeed, it doesn’t make a lot of sense to modify a contract value
outside the contract itself.

If processing is needed, then it should happen inside the contract
itself.
2024-10-29 12:23:35 +01:00
7bcd46b87d DEV: use service worker for chat sound (#29388)
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>
2024-10-29 13:15:53 +04:00
aa89acbda6 DEV: Upgrade Uppy to v4 (#29397)
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
2024-10-28 14:01:44 +00:00
584424594e DEV: Replace params by the contract object in services
This patch replaces the parameters provided to a service through
`params` by the contract object.

That way, it allows better consistency when accessing input params. For
example, if you have a service without a contract, to access a
parameter, you need to use `params[:my_parameter]`. But with a contract,
you do this through `contract.my_parameter`. Now, with this patch,
you’ll be able to access it through `params.my_parameter` or
`params[:my_parameter]`.

Some methods have been added to the contract object to better mimic a
Hash. That way, when accessing/using `params`, you don’t have to think
too much about it:
- `params.my_key` is also accessible through `params[:my_key]`.
- `params.my_key = value` can also be done through `params[:my_key] =
  value`.
- `#slice` and `#merge` are available.
- `#to_hash` has been implemented, so the contract object will be
  automatically cast as a hash by Ruby depending on the context. For
  example, with an AR model, you can do this: `user.update(**params)`.
2024-10-25 14:48:34 +02:00
41584ab40c DEV: Provide user input to services using params key
Currently in services, we don’t make a distinction between input
parameters, options and dependencies.

This can lead to user input modifying the service behavior, whereas it
was not the developer intention.

This patch addresses the issue by changing how data is provided to
services:
- `params` is now used to hold all data coming from outside (typically
  user input from a controller) and a contract will take its values from
  `params`.
- `options` is a new key to provide options to a service. This typically
  allows changing a service behavior at runtime. It is, of course,
  totally optional.
- `dependencies` is actually anything else provided to the service (like
  `guardian`) and available directly from the context object.

The `service_params` helper in controllers has been updated to reflect
those changes, so most of the existing services didn’t need specific
changes.

The options block has the same DSL as contracts, as it’s also based on
`ActiveModel`. There aren’t any validations, though. Here’s an example:
```ruby
options do
  attribute :allow_changing_hidden, :boolean, default: false
end
```
And here’s an example of how to call a service with the new keys:
```ruby
MyService.call(params: { key1: value1, … }, options: { my_option: true }, guardian:, …)
```
2024-10-25 09:57:59 +02:00
98a3e7d6e2 UX: Consistent styling for admin tables on mobile (#29360)
* UX: Apply admin table classes for consistent mobile styling on custom flags

* UX: Apply admin table classes for consistent mobile styling on custom flags

* UX: Apply admin table classes for consistent mobile styling on backups

* UX: Apply admin table classes for consistent mobile styling on plugins list

* DEV: tweaks on admin table

* UX: Apply admin table classes for consistent mobile styling on chat plugin

* apply prettier

* apply lint

* DEV: removed commented out code

* DEV: removed unnecessary div element

* scroll to the element

* remove the workaround

* revert

* add an extra assertion

* add enabled check

* improve switching

* rm

---------

Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2024-10-23 16:26:21 -06:00