This reverts the "fix" made in 44f6b24e34 since it wasn't the correct fix and the emoji picker wasn't showing in chat 🤦♂️
The proper fix is to `stopPropagation()` on the `click` event since the click handler has been made `async`. `preventDefault()` isn't enough.
Should open the emoji picker. But it wasn't 😅
The `handleOutsideClick` event was listening too early and would catch the click on the "more..." option in the autocomplete as a click outside the emoji picker and would immediately close it 🤦
The fix was to defer registering to this event.
In AdminDashboardData we have a bunch of problem checks implemented as methods on that class. This PR absolves it of the responsibility by promoting each of those checks to a first class ProblemCheck. This way each of them can have their own priority and arbitrary functionality can be isolated in its own class.
Think "extract class" refactoring over and over. Since they were all moved we can also get rid of the @@problem_syms class variable which was basically the old version of the registry now replaced by ProblemCheck.realtime.
In addition AdminDashboardData::Problem value object has been entirely replaced with the new ProblemCheck::Problem (with compatible API).
Lastly, I added some RSpec matchers to simplify testing of problem checks and provide helpful error messages when assertions fail.
With the new admin sidebar restructure, we have a link to "Installed plugins". We would like to ensure that when the admin is searching for a plugin name like "akismet" or "automation" this link will be visible. Also when entering the plugins page, related plugins should be highlighted.
Why this change?
Prior to this change, there is no description being displayed for
objects typed theme setting because we were rendering a button instead
of the components for the various setting types which will render the
setting's description.
What does this change do?
1. Introduce `SiteSettings::Description` compoment to centralise the HTML
being rendered across all settings component.
2. Renders the `SiteSettings::Description` component after the edit
button in `site_setting.hbs`.
This commit adds new plugin show routes (`/admin/plugins/:plugin_id`) as we move
towards every plugin having a consistent UI/landing page.
As part of this, we are introducing a consistent way for plugins
to show an inner sidebar in their config page, via a new plugin
API `register_admin_config_nav_routes`
This accepts an array of links with a label/text, and an
ember route. Once this commit is merged we can start the process
of conforming other plugins to follow this pattern, as well
as supporting a single-page version of this for simpler plugins
that don't require an inner sidebar.
Part of /t/122841 internally
Avoid sending user emails if @ mentioning a staged user
Some cases, unknowingly mentioning a staged user would invite
them into topics, sending them an email about it.
* FEATURE: Use browser `dir="auto"` for support_mixed_text_direction
Previously we were using regex to parse all sorts of user input and guess the direction. All out target browsers now support this behavior out-the-box using `dir=auto`, which should be significantly faster.
https://meta.discourse.org/t/dir-auto-for-composer-and-elsewhere/276330
* test
* Update app/assets/javascripts/discourse/tests/integration/components/text-field-test.js
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
---------
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
* DEV: add toggle to switch to glimmer TopicMap and rename imported hbs-compiler
* DEV: refactor topic-map tests to use assert.dom
* DEV: add topic-map glimmer component
* DEV: remove topic-map widget and switch summary-box to use explicitly passed-in actions
---------
Co-authored-by: David Taylor <david@taylorhq.com>
`apply_transformations` is an async function, and plugins/themes using it expect their transformations to be applied before the loadMore logic continues. This should resolve issues with unencrypted topics when scrolling down topic lists in discourse-encrypt.
Previously, if the sso= payload was invalid Base64, but signed correctly, there would be no useful log or error. This commit improves things by:
- moving the base64 check before the signature checking so that it's properly surfaced
- split the ParseError exception into PayloadParseError and SignatureError
- add user-facing errors for both of those
- add/improve spec for both
**TL;DR:** Refactor autocomplete to use async markdown parsing for code block detection.
Previously, the `inCodeBlock` function in `discourse/app/lib/utilities.js` used regular expressions to determine if a given position in the text was inside a code block. This approach had some limitations and could lead to incorrect behavior in certain edge cases.
This commit refactors `inCodeBlock` to use a more robust algorithm that leverages Discourse's markdown parsing library.
The new approach works as follows:
1. Check if the text contains any code block markers using a regular expression.
If not, return `false` since the cursor can't be in a code block.
1. If potential code blocks exist, find a unique marker character that doesn't appear in the text.
1. Insert the unique marker character into the text at the cursor position.
1. Parse the modified text using Discourse's markdown parser, which converts the markdown into a tree of tokens.
1. Traverse the token tree to find the token that contains the unique marker character.
1. Check if the token's type is one of the types representing code blocks ("code_inline", "code_block", or "fence").
If so, return `true`, indicating that the cursor is inside a code block.
Otherwise, return `false`.
This algorithm provides a more accurate way to determine the cursor's position in relation to code blocks, accounting for the various ways code blocks can be represented in markdown.
To accommodate this change, the autocomplete `triggerRule` option is now an async function.
The autocomplete logic in `composer-editor.js`, `d-editor.js`, and `hashtag-autocomplete.js` has been updated to handle the async nature of `inCodeBlock`.
Additionally, many of the tests have been refactored to handle async behavior. The test helpers now simulate typing and autocomplete selection in a more realistic, step-by-step manner. This should make the tests more robust and reflective of real-world usage.
This is a significant refactor that touches multiple parts of the codebase, but it should lead to more accurate and reliable autocomplete behavior, especially when dealing with code blocks in the editor.
> Written by an 🤖 LLM. Edited by a 🧑💻 human.
Changing an `@tracked` value in a `willDestroyElement` hook will not immediately trigger a re-render. Instead, it seems to update on the next natural runloop iteration, which may be significantly later depending on what else is happening.
Instead, these kinds of 'data' changes should be made based on the lifecycle of the component instance (init / willDestroy). Making changes to tracked properties here does seem to cause immediate invalidation & re-render.
There are a couple of reasons for this.
The first one is practical, and related to eager loading. Since /lib is not eager loaded, when the application boots, ProblemCheck["identifier"] will be nil because the child classes aren't loaded.
The second one is more conceptual. There turns out to be a lot of inter-dependencies between the part of the problem check system that live in /app and the parts that live in /lib, which probably suggests it should all go in /app.
Why this change?
On the `/admin/customize/themes/<:id>` route, we allow admins to edit
all settings via a settings editor. Prior to this change, trying to edit
and save a typed objects theme settings will result in an error on the
server.
Why this change?
On a slow network, using the `AceEditor` component will result in a blob
of text being shown first before being swapped out with the `ace.js`
editor after it has completed loading.
There is also a problem when setting the theme for the editor which
would result in a "flash" as reported in
https://github.com/ajaxorg/ace/issues/3286. To avoid this, we need to
load the theme js file before displaying the editor.
What does this change do?
1. Adds a loading spinner and set the `div.ace` with a `.hidden` class.
2. Once all the relevant scripts and initialization is done, we will
then remove the loading spinner and remove `div.ace`.
This change creates a user setting that they can toggle if
they don't want to receive unread notifications when someone closes a
topic they have read and are watching/tracking it.
* A11Y: Update bulk selection keyboard shortcuts
Still a draft, but in current state this:
- adds `shift+b` as a keyboard shortcut to toggle bulk select
- adds `shift+d` as a keyboard shortcut to dismiss selected topic(s) (this
replaces `x r` and `x t` shortcuts)
- adds `x` as a keyboard shortcut to toggle selection (while in bulk select mode)
- fixes a bug with the `shift+a` shortcut, which was not working properly
Note that there is a breaking change here. Previously we had:
- `x r` to dismiss new topics
- `x t` to dismiss unread topics
However, this meant that we couldn't use `x` for selection, because the
itsatrap library does not allow the same character to be used both as a
single character shortcut and as the start of a sequence. The proposed
solution here is more consistent with other apps (Gmail, Github) that use
`x` to toggle selection.
Also, we never show both "Dismiss New" and "Dismiss Unread" in the same
screen, hence it makes sense to consolidate both actions under `shift+d`.
* Address review
Why this change?
Before this change, the new navigation item in the topic list will be
hidden when there are no new or unread topics for the user. We have
started to find this behaviour confusing UX wise so we decided to stop
hiding it.
Why this change?
This is a regression from introduced in
5c1147adf3 where dismissing unread topics
was changing the notification level of the topics instead of just
dismissing the unread posts.
What does this change do?
1. Bring back the previous implementation of the action
2. Fix the system test that was supposed to catch the problem but did
not.