The category drop was rerendered after every category async change
because it updated the categories list. This is not necessary and
categories can be referenced indirectly by ID instead.
This value is included when generating static asset URLs. Updating the value will allow site operators to invalidate all asset urls to recover from configuration issues which may have been cached by CDNs/browsers.
When sending SMTP for group SMTP functionality, we
are running into timeouts for both read and open
when sending mail occassionally, which can cause issues
like the email only being sent to _some_ of the recipients
or to fail altogether.
The defaults of 5s are too low, so bumping them up to
the defaults of the `net-smtp` gem.
When we check upload security, one of the checks is to
run `access_control_post.with_secure_uploads?`. The problem
here is that the `topic` for the post could be deleted,
which would make the check return `nil` sometimes instead
of false because of safe navigation. We just need to be
more explicit.
Admin can add tag description up to 1000 characters.
Full description is displayed on tag page, however on topic list it is truncated to 80 characters.
This commit introduces the scaffolding for us to easily switch between Ember 3.28 and Ember 5 on the `main` branch of Discourse. Unfortunately, there is no built-in system to apply this kind of flagging within yarn / ember-cli. There are projects like `ember-try` which are designed for running against multiple version of a dependency, but they do not allow us to 'lock' dependency/sub-dependency versions, and are therefore unsuitable for our use in production.
Instead, we will be maintaining two root `package.json` files, and two `yarn.lock` files. For ember-3, they remain as-is. For ember5, we use a yarn 'resolution' to override the version for ember-source across the entire yarn workspace.
To allow for easy switching with minimal diff against the repository, `package.json` and `yarn.lock` are symlinks which point to `package-ember3.json` and `yarn-ember3.lock` by default. To switch to Ember 5, we can run `script/switch ember version 5` to update the symlinks to point to `package-ember5.json` and `package-ember3.json` respectively. In production, and when using `bin/ember-cli` for development, the ember version can also be upgraded using the `EMBER_VERSION=5` environment variable.
When making changes to dependencies, these should be made against the default `ember3` versions, and then `script/regen_ember_5_lockfile` should be used to regenerate `yarn-ember5.lock` accordingly. A new 'Ember Version Lockfiles' GitHub workflow will automate this process on Dependabot PRs.
When running a local environment against Ember 5, the two symlink changes will show up as git diffs. To avoid us accidentally committing/pushing that change, another GitHub workflow is introduced which checks the default Ember version and raises an error if it is greater than v3.
Supporting two ember versions simultaneously obviously carries significant overhead, so our aim will be to get themes/plugins updated as quickly as possible, and then drop this flag.
- Update optional-features to tie the `jquery-integration` flag to the current ember version
- Wrap ember-4-specific logic in ember-cli-build with a version check
- Update global-compat.js to add the jquery global if it doesn't exist (i.e. if we're on a modern ember version)
Extracted from https://github.com/discourse/discourse/pull/21720. This is a no-op under our current Ember 3.28 version.
- Skip rendering DModalLegacy when running Ember 5
- Move named outlet inside the DModalLegacy component file
- Exclude that DModalLegacy template from the build when running Ember 5
- Skip LegacySupport version of modal service when running Ember 5
- Add error popup for legacy modals when running Ember 5
Extracted from https://github.com/discourse/discourse/pull/21720. This is a no-op under our current Ember 3.28 version.
In modern versions of Ember, `this.parentView` is called internally during component init. We don't want our deprecation message to be triggered by that internal call, so we need an additional check.
Extracted from https://github.com/discourse/discourse/pull/21720
This hook is `cancel()`'d in a willTransition hook, but that isn't always enough. It might still be scheduled if there is a scroll event between `willTransition`, and the transition actually completing. Following c2d94be06e, this kind of scroll event happens when the loading indicator is set to 'spinner'. This would put the router in a weird state and cause navigation issues.
Also takes the opportunity to remove JQuery from this code path
https://meta.discourse.org/t/286463/15
Followup to 2443446e62
We introduced video placeholders which prevent preloading
metadata for videos in posts. The structure looks like this
in HTML when the post is cooked:
```
<div class="video-placeholder-container" data-video-src="http://some-url.com/video.mp4" dir="ltr" style="cursor: pointer;">
<div class="video-placeholder-wrapper">
<div class="video-placeholder-overlay">
<svg class="fa d-icon d-icon-play svg-icon svg-string" xmlns="http://www.w3.org/2000/svg">
<use href="#play"></use>
</svg>
</div>
</div>
</div>
```
However, we did not update the code that links post uploads
to the post via UploadReference, so any videos uploaded since
this change are essentially dangling and liable to be deleted.
This also causes some uploads to be marked secure when they
shouldn't be, because they are not picked up and analysed in the
CookedPostProcessor flow.
If a group is < 5 members, the mention warning doesn't need to
be so harsh. This commit changes the copy for the existing warning
and adds a new one for groups that are >= 5 members.
When going 'back', default browser behavior is to restore the scroll position. Unfortunately sites are given no control over the timing of this restoration, which means it can happen halfway through an Ember transition. Therefore we disable it, and re-implement the functionality in our scroll-manager service.
We inadvertently dropped this configuration in 7c9cf666da, which led to issues like https://meta.discourse.org/t/286463
Making the icons available generally in tests is tricky because they're generated dynamically by the rails server. However, if we restrict it to dev-mode (`/tests` in a browser) then it's possible to load them from the running rails server. This is purely a visual thing to make debugging easier - it should not affect test behavior.
Reverts
- DEV: maxmind license checking failing tests #24534
- UX: Show if MaxMind key is missing on IP lookup #18993
These changes are leading to surprising results, our logs are now filling up with warnings on dev environments
We need the change to be redone
The parent category needs to be serialized before the child category
because they are parsed in order. Otherwise the client will not build
the parent-child relationship correctly.
+ native classes
+ tracked properties
- Ember.Object
- Ember.Evented
- observers
- mixins
- computed/discourseComputed
Also removes unused wizard infrastructure for warnings. It appears
that once upon on time, either the server can generate warnings,
or some client code can generate them, which requires an extra
confirmation from the user before they can continue to the next step.
This code is not tested and appears unused and defunct. Nothing
generates such warning and the server does not serialize them.
Extracted from https://github.com/discourse/discourse/pull/23678
Followup to e37fb3042d
Some plugins like discourse-ai and discourse-saml do not
nicely change from kebab-case to Title Case (e.g. Ai, Saml),
and anyway this method of getting the plugin name is not
translated either.
Better to use the plugin setting category if it exists,
since that is written by a human and is translated.
* DEV: Convert approve_new_topics_unless_trust_level to groups
This change converts the `approve_new_topics_unless_trust_level` site
setting to `approve_new_topics_unless_allowed_groups`.
See: https://meta.discourse.org/t/283408
- Hides the old setting
- Adds the new site setting
- Add a deprecation warning
- Updates to use the new setting
- Adds a migration to fill in the new setting if the old setting was
changed
- Adds an entry to the site_setting.keywords section
- Updates tests to account for the new change
After a couple of months we will remove the
`approve_new_topics_unless_trust_level` setting entirely.
Internal ref: /t/115696
* add missing translation
* Add keyword entry
* Add migration
This commit extracts the storage part of the route-scroll-manager into a dedicated service. This provides a key/value store which will reset for each navigation, and restore previous values when the user uses the back/forward buttons in their browser.
This gives us a reliable replacement for the old `DiscourseRoute.isPoppedState` function, which would not work under all situations.
Previously reverted in e6370decfd. This version has been significantly refactored, and includes an additional system spec for the issue we identified.
Operate a key at a time, to make it clearer what's going on.
This also fixes a bug where array integer fields would get re-written
even when there wasn't a change.
This change converts the `approve_unless_trust_level` site setting to
`approve_unless_allowed_groups`.
See: https://meta.discourse.org/t/283408
- Adds the new site setting
- Adds a deprecation warning
- Updates core to use the new settings.
- Adds a migration to fill in the new setting of the old setting was
changed
- Adds an entry to the site_setting.keywords section
- Updates many tests to account for the new change
After a couple of months we will remove the `approve_unless_trust_level`
setting entirely.
Internal ref: /t/115696
Array custom fields use separate rows for each value, but whenever we
update an array, we have always destroy the existing rows and create new
ones. Therefore, there's no benefit over using the json type.
In the past, our loading spinner implementation used Ember's loading substate. That meant that, when the site setting was toggled, there would be fundamental changes in the routing behavior.
This commit simplifies things so that the (non-default) loading spinner implementation is purely a styling thing, and behaves exactly the same as the spinner which appears under the 'slider' configuration when loading takes too long.
This does involve a slight UX change. Now, the entire page will be replaced by a loading spinner instead of just the relevant `{{outlet}}`. We strongly recommend sites use the new default 'slider' behavior.
* Remove checkmark for official plugins
* Add author for plugin, which is By Discourse for all discourse
and discourse-org github plugins
* Link to meta topic instead of github repo
* Add experimental flag for plugin metadata and show this as a
badge on the plugin list if present
---------
Co-authored-by: chapoi <101828855+chapoi@users.noreply.github.com>
This commit makes it so the fullscreen code modal grows
to fit its content, and doesn't show horizontal scrollbars
unless the entire screen is filled by the modal already.
The code syntax highlighting and copy buttons were also
broken in fullscreen because of modal changes over time.
This reverts commit 20e562bd99, 161256eef8 and a8292d25f8.
It looks like this affected cache-restoration of topic lists in some circumstances. It also looks like routing behavior may vary when toggling the loading indicator between spinner and slider.
More investigation and testing required.
For transitions to nested routes (e.g. /u/blah/activity), where each layer has an async model hook, the `loading` event will be fired twice within the same transition. This was causing the loading slider to jump backwards halfway through loading. This commit fixes things to handle nested loading events with a single animation.
The old heuristic was 'a transition to a URL (i.e. not a named route) which was not triggered by DiscourseURL'. That logic is flawed now that we're increasingly using Ember's routing methods.
This commit extracts the storage part of the route-scroll-manager into a dedicated service. This provides a key/value store which will reset for each navigation, and restore previous values when the user uses the back/forward buttons in their browser.
Should fix https://meta.discourse.org/t/-/285768.
Appending without cloning was causing the item to be removed from the
DOM but on a 1-item grid we skip the rest of the grid's rendering,
hence the item was never re-inserted. Cloning ensures we don't remove
the item during processing (it does get removed later on when rendering
the grid's columns).
Moves the patch from ember-source to ember-cli so that it's easier for us to feature-flag an ember-source upgrade without fighting with patch-package. We'll be able to remove this patch once we're fully on Ember 5.x.
(ref https://github.com/discourse/discourse/pull/21720)
Having async cleanup on a modifier is problematic because it means it might persist beyond the end of a test, leading to flaky 'Test is not isolated' errors.
Discourse already includes version information in a `<meta` tag on the page. This commit surfaces it to the console on boot for easier access, and also adds the Ember version (which will be particularly useful as we start rolling out the upgrade to Ember 5)
This was accidentally selecting the close button on `<DModalLegacy />`, which is present in the DOM with `display: none`. The close button logic would close any active modal, so the test would pass. However, it will stop passing when we remove the legacy modal system.
In the long term we should aim to modernize these places, but for now this change will make them compatible with Ember 5.x (while maintaining compatibility with Ember 3.28)
This commit adds a new `search_default_sort_order` site setting,
set to "relevance" by default, that controls the default sort order
for the full page /search route.
If the user changes the order in the dropdown on that page, we remember
their preference automatically, and it takes precedence over the site
setting as a default from then on. This way people who prefer e.g.
Latest Post as their default can make it so.
Recently, we disabled the option to reorder links directly from the sidebar. Instead, user has to go to edit modal.
https://github.com/discourse/discourse/pull/24188
However, move cursor was left, which is misleading.
en is the only fallback locale we use, so there's no need to invalidate everything when other languages change. Limiting this also helps to prevent circular dependent_field relations which could cause issues in some situations.
Followup to eda79186ee
Currently to use a limit in the notifications index, you have to also pass recent: true as a param.
This PR:
Adds optional limit param to be used in the notifications query, regardless of the presence of recent
Raises the max limit of the response with recent present from 50 -> 60. It is super weird we have a hard-limit of 50 before with recent param, and 60 without the param.
Why this change?
The test has been flaky on CI with the following assertion failing:
```
not ok 302 Firefox 115.0 - [899 ms] - Browser Id 5 - Acceptance: Fast Edit: Works with keyboard shortcut
---
actual: >
Element #fast-edit-input does not exist
expected: >
Element #fast-edit-input exists
```
The hypothesis here is that we are triggering the `E` keypress event
before the `.quote-button` menu has appeared. When that happens, we will
end up opening the composer instead of triggering the fast edit editor.
Why this change?
As the number of themes which the Discourse team supports officially
grows, we want to ensure that changes made to Discourse core do not
break the plugins. As such, we are adding a step to our Github actions
test job to run the QUnit tests for all official themes.
What does this change do?
This change adds a new job to our tests Github actions workflow to run the QUnit
tests for all official plugins. This is achieved with the following
changes:
1. Update `testem.js` to rely on the `THEME_TEST_PAGES` env variable to set the
`test_page` option when running theme QUnit tests with testem. The
`test_page` option [allows an array to be specified](https://github.com/testem/testem#multiple-test-pages) such that tests for
multiple pages can be run at the same time. We are relying on a ENV variable
because the `testem` CLI does not support passing a list of pages
to the `--test_page` option.
2. Support a `/testem-theme-qunit/:testem_id/theme-qunit` Rails route in the development environment. This
is done because testem prefixes the path with a unique ID to the configured `test_page` URL.
This is problematic for us because we proxy all testem requests to the
Rails server and testem's proxy configuration option does not allow us
to easily rewrite the URL to remove the prefix. Therefore, we configure a proxy in testem to prefix `theme-qunit` requests with
`/testem-theme-qunit` which can then be easily identified by the Rails server and routed accordingly.
3. Update `qunit:test` to support a `THEME_IDS` environment variable
which will allow it to run QUnit tests for multiple themes at the
same time.
4. Support `bin/rake themes:qunit[ids,"<theme_id>|<theme_id>"]` to run
the QUnit tests for multiple themes at the same time.
5. Adds a `themes:qunit_all_official` Rake task which runs the QUnit
tests for all the official themes.
Move external login logic from the **Login Modal** -> **Login Service**. This is advantageous as we can utilize the external login logic from both within and outside of the login modal.
A downside of having the external login logic within the login modal is that there is a brief "flash" of the login modal being rendered and then us automatically redirecting to the external login method. This PR will clean up the visual side affects.
This change means that the `/my` redirects will be handled by the ember 'unknown' route, and will therefore function correctly when using pure-ember transition methods like `router.transitionTo`
We want / to display one of our discovery routes/controllers, but we don't want to register it as `discovery.index` because that would break themes/plugins which check the route name. Previously, this was handled using a variety of approaches throughout the codebase (in discourse-location, discourse-url and mapping-router). But even then, it didn't work consistently. For example, if you used an Ember method like `router.transitionTo("/")`, an empty `discovery.index` page would be rendered.
This commit switches up the approach. `discovery.index` is now defined as a real route, and redirects to the desired homepage. To preserve the `/` as a 'vanity url', we patch the method on the router responsible for persisting URLs to the Ember Router and the browser. The patch identifies a relevant transition by looking for a magic query parameter.
In an ideal world, we wouldn't be patching the router at all. But at least with this commit, the workaround is all in one place, and works consistently for all navigation methods. The new strategy is also much better tested.
When we started using NumberField for integer site settings
in e113eff663, we did not end up
passing down a min/max value for the integer to the field, which
meant that for some fields where negative numbers were allowed
we were not accepting that as valid input.
This commit passes down the min/max options from the server for
integer settings then in turn passes them down to NumberField.
c.f. https://meta.discourse.org/t/delete-user-self-max-post-count-not-accepting-1-to-disable/285162
Why this change?
This test has been flaky on CI: https://github.com/discourse/discourse/actions/runs/6880353258/job/18714366795
However, the way the current assertions are written does not really
allow us to easily figure out what went wrong since we only know that
`#post_4` was not selected. It will be useful to know what was selected
instead of `#post_4` when the test fails.
What does this change do?
This change updates the assertion of the flaky test to reveal which post
was selected should the test fail.
This discourse-common decorator was dependent on the core app, hence creating a circular reference that was breaking the embroider upgrade. (see: #24391)
Raised in https://meta.discourse.org/t/keyboard-navigation-messes-up-the-search-menu/285405
We were incorrectly accessing the highlighted search result target's href which caused issues when navigating the topic list (eg /latest) with **j / k** and then immediately after accessing the search menu and navigating to and selecting a search result with the keyboard.
### Current Behavior
Hitting enter on a search result redirects to the href of the topic in the topic list that was previously highlighted.
### Expected Behavior
Hitting enter on a search result redirects to the href of the highlighted search result.
The default for webpack is to keep cached values indefinitely. In discourse, this unbound memory usage causes node to raise an OOM error after 50-100 rebuilds in development mode (with source maps enabled). Setting maxGenerations=1 means that the cache will be cleaned up regularly. With this change, I see no discernible increase in memory after 150+ rebuilds.
Previously, the discourse-hbr plugin took the entire app tree as its input, and the result would then be merged into the app. This is wasteful and more likely to cause problems in the build pipeline.
See also https://github.com/discourse/discourse/pull/24376
Ember-cli has built-in error pages when there is a build error. Previously these were not being used in Discourse because our custom proxy middleware was too early in the stack. This commit reorders things so that the "broccoli-watcher" middleware runs before our custom proxy. It also disables the `historySupportMiddleware`, which doesn't make sense in our 'always proxy' setup.
This PR refactors the following:
* leaving all the CSS applied to the old `modal-body` classes in their respective files
* made new clean styling for `.d-modal` and refactored the template to use the new BEM classes
* `inner-`, `middle-`, `outer-` container classes are gone and replaced with simplified `wrapper` and `container` classes
* use standardised max-sizes with modifiers `-large` and `-max`
* lighter backdrop,
* min-width to prevent puny modals
* other styling changes regarding padding, close button,…
* pulled out all modal overrides into a general `modal-overrides` file + cleanup of outdated CSS
* pulled out login and create account modal styling into their own file, cause it's such a big override
* removed old general login.scss file for mobile & desktop
* only kept some remainders I don't want to touch in `app/assets/stylesheets/common/base/login.scss`
Previously this was being handled in two places:
1. As a monkey-patch to the Ember router. This would 'trick' the router into rendering a different route, but would leave the browser URL bar unchanged. Many possible bugs can come from this state
2. In the DiscourseURL.routeTo function. This functioned fine as a redirect, but wouldn't have any effect when the transition is handled by Ember
This commit refactors things so that the DiscourseURL redirects are handled the same as our permalinks. When the Ember 'unknown' route is hit, we check for a possible rewrite and redirect there. This is a supported way of doing things, and should be more robust going forwards.
Previously we would only recompile a theme locale when its own data changes. However, the output also includes fallback data from other locales, so we need to invalidate all locales when fallback locale data is changed. Building a list of dependent locales is tricky, so let's just invalidate them all.
Previously we had similar logic in two places:
1. A DiscourseURL rewrite, based on a site setting
2. Some logic in the user-index route
This commit moves everything into (2) to make things clearer and more consistent
We ask users to confirm their session if they are making a sensitive
action, such as adding/updating second factors or passkeys. This
commit adds the ability to confirm sessions with passkeys as an option
to the password confirmation.
This allows outlets for the post-text-selection-toolbar to
get just the raw markdown of the selected text for a quote,
rather than opening the composer.
This commit changes some plugin outlets in `<Discovery::Layout>`, `<Discovery::Navigation>` and `Discovery::Topics` to improve compatibility with existing customization, simplifying the migration process to the new discovery routes.
In these components, the standard plugin outlets will receive by default at least the arguments: `category` and `tag`.
Furthermore, two new wrapping plugin outlets were added to enable the conversion of existing template overrides to the new pattern: `discovery-list-area` and `topic-list-bottom`. The new template overrides will receive a `model` argument containing the full model handled by the route.
---------
Co-authored-by: David Taylor <david@taylorhq.com>
Follow-up to #24278 that is slightly less trivial.
* Some were "trivial" usages that were missed in the previous PR because the same file that had at least one other non-trivial usage.
* These involve extra arguments or inheritance but I have checked that they seem correct.
- Remove vendored copy
- Update Rails implementation to look for language definitions in node_modules
- Use webpack-based dynamic import for hljs core
- Use browser-native dynamic import for site-specific language bundle (and fallback to webpack-based dynamic import in tests)
- Simplify markdown implementation to allow all languages into the `lang-{blah}` className
- Now that all languages are passed through, resolve aliases at runtime to avoid the need for the pre-built `highlightjs-aliases` index
Previously, the app HTML served by the Ember-CLI proxy was generated based on a 'bootstrap json' payload generated by Rails. This inevitably leads to differences between the Rails HTML and the Ember-CLI HTML.
This commit overhauls our proxying strategy. Now, we totally ignore the ember-cli `index.html` file. Instead, we take the full HTML from Rails and surgically replace script URLs based on a `data-discourse-entrypoint` attribute. This should be faster (only one request to Rails), more robust, and less confusing for developers.
This updates the behaviour to match ember-cli-htmlbars, and should take care of the handful of themes which were relying on runtime compilation in tests (see 4425e99bf9)
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
Followup to fe05fdae24
For consistency with other S3 settings, make the global setting
the same name as the site setting and use SiteSetting.Upload
too so it reads from the correct place.
This adds the ability to collect stats without exposing them
among other stats via API.
The most important thing I wanted to achieve is to provide
an API where stats are not exposed by default, and a developer
has to explicitly specify that they should be
exposed (`expose_via_api: true`). Implementing an opposite
solution would be simpler, but that's less safe in terms of
potential security issues.
When working on this, I had to refactor the current solution.
I would go even further with the refactoring, but the next steps
seem to be going too far in changing the solution we have,
and that would also take more time. Two things that can be
improved in the future:
1. Data structures for holding stats can be further improved
2. Core stats are hard-coded in the About template (it's hard
to fix it without correcting data structures first, see point 1):
63a0700d45/app/views/about/index.html.erb (L61-L101)
The most significant refactorings are:
1. Introducing the `Stat` model
2. Aligning the way the core and the plugin stats' are registered
There was a registry for preloaded site categories and a new one has
been introduced recently for categories serialized through a
CategoryList.
Having two registries created a lot of friction for developers and this
commit merges them into a single one, providing a unified API.
There is an edge case where the following occurs:
1. The user sets a bookmark reminder on a post/topic
2. The post/topic is changed to a PM before or after the reminder
fires, and the notification remains unread by the user
3. The user opens their bookmark reminder notification list
and they can still see the notification even though they cannot
access the topic anymore
There is a very low chance for information leaking here, since
the only thing that could be exposed is the topic title if it
changes to something sensitive.
This commit filters the bookmark unread notifications by using
the bookmarkable can_see? methods and also prevents sending
reminder notifications for bookmarks the user can no longer see.
When quoting a chat message in a post, if that message contains a mention,
that mention should be ignored. But we've been detecting them and sending
notifications to users. This PR fixes the problem. Since this fix is for
the chat plugin, I had to introduce a new API for plugins:
# We strip posts before detecting mentions, oneboxes, attachments etc.
# We strip those elements that shouldn't be detected. For example,
# a mention inside a quote should be ignored, so we strip it off.
# Using this API plugins can register their own post strippers.
def register_post_stripper(&block)
end
* UX: separate invite-signup styling
* UX: invite page centering
* remove old invites-show css
* UX: invite signup page – mobile
* remove class references in general file
* add styling for instructions
This removes all trivial usages of the `{{action}}` keyword (the helper form, not the modifier form), where trivial means:
1. It's a co-located component (`.hbs` next to `.js`)
2. The JS file has a default export that is native class
3. `{{action "foo"}}` or `(action "foo")` with no extra arguments
4. There is a corresponding `foo()` method defined on the class (not inherited, etc)
There are more usages that is slightly more involved (with arguments, etc) that we can deal with, but this PR seems big enough so I just included the easiest cases here.
To aid review, each file is converted in an individual commit, and the matching method is temporary annotated with `@__action__` instead of the normal `@action`. This forces a git diff when it is already annotated as `@action`.
* DEV: {{action}} -> @action admin-penalty-post-action.hbs
* DEV: {{action}} -> @action admin-report.hbs
* DEV: {{action}} -> @action admin-watched-word.hbs
* DEV: {{action}} -> @action emoji-value-list.hbs
* DEV: {{action}} -> @action bool.hbs
* DEV: {{action}} -> @action category.hbs
* DEV: {{action}} -> @action secret-value-list.hbs
* DEV: {{action}} -> @action category-list.hbs
* DEV: {{action}} -> @action color.hbs
* DEV: {{action}} -> @action compact-list.hbs
* DEV: {{action}} -> @action group-list.hbs
* DEV: {{action}} -> @action host-list.hbs
* DEV: {{action}} -> @action named-list.hbs
* DEV: {{action}} -> @action simple-list.hbs
* DEV: {{action}} -> @action tag-group-list.hbs
* DEV: {{action}} -> @action tag-list.hbs
* DEV: {{action}} -> @action value-list.hbs
* DEV: {{action}} -> @action watched-word-form.hbs
* DEV: {{action}} -> @action composer-messages.hbs
* DEV: {{action}} -> @action section.hbs
* DEV: {{action}} -> @action user-status-picker.hbs
* DEV: cleanup @__action__ -> @action
Followup to 545e92039c
This commit fixes an issue where hashtags on user activity stream
items past page 1 did not get decorated. This is because of a bug
in the user stream component, where it was trying to get stream
items to decorate after the AJAX call but before they had been
rendered by Ember. This can be fixed by wrapping this decoration
logic in later() to run on the next runloop.
This commit adds an /admin/customize/theme-components route,
that opens the theme page with the components tab pre-selected,
so people can navigate to that directly.
Switches to using a dialog to confirm a session (i.e. sudo mode for
account changes where we want to be extra sure the current user is who
they say they are) to match what we do with passkeys.
https://github.com/discourse/discourse/pull/22622 accidentally introduced an `@action` decorator inside the actions hash, which does not work. This commit modernizes the component by removing the actions hash altogether.
Previously, we were parsing webpack JS chunk filenames from the HTML files which ember-cli generates. This worked ok for simple entrypoints, but falls apart once we start using async imports(), which are not included in the HTML.
This commit uses the stats plugin to generate an assets.json file, and updates Rails to parse it instead of the HTML. Caching on the Rails side is also improved to avoid reading from the filesystem multiple times per request in develoment.
Co-authored-by: Godfrey Chan <godfreykfc@gmail.com>
Followup to b53449eac9,
it was too easy to add broken routes which would break
configuration for the whole site, so now we validate ember
routes on save.
This commit fixes an issue where when some actions were done
(deleting/recovering post, moving posts) we updated the
topic_users.bookmarked column to the wrong value. This was happening
because the SyncTopicUserBookmarked job was not taking into account
Topic level bookmarks, so if there was a Topic bookmark and no
Post bookmarks for a user in the topic, they would have
topic_users.bookmarked set to false, which meant the bookmark would
no longer show in the /bookmarks list.
To reproduce before the fix:
* Bookmark a topic and don’t bookmark any posts within
* Delete or recover any post in the topic
c.f. https://meta.discourse.org/t/disappearing-bookmarks-and-expected-behavior-of-bookmarks/264670/36
In some browsers, 2FA login was failing with a "request is already
pending" error. This only applied when `experimental_passkeys` was
enabled and on Chrome only. This was due to the fact that the webauthn
API only supports one auth attempt at a time, so the security key call
needs to abort the passkey's conditional UI request before starting.
I am not sure we can test this. We have system specs that simulate
webauthn credentials and they didn't catch this (probably because the
simulation covers the whole flow).
With Embroider, we can rely on async `import()` to do the splitting
for us.
This commit extracts from `pretty-text` all the parts that are
meant to be loaded async into a new `discourse-markdown-it` package
that is also a V2 addon (meaning that all files are presumed unused
until they are imported, aka "static").
Mostly I tried to keep the very discourse specific stuff (accessing
site settings and loading plugin features) inside discourse proper,
while the new package aims to have some resembalance of a general
purpose library, a MarkdownIt++ if you will. It is far from perfect
because of how all the "options" stuff work but I think it's a good
start for more refactorings (clearing up the interfaces) to happen
later.
With this, pretty-text and app/lib/text are mostly a kitchen sink
of loosely related text processing utilities.
After the refactor, a lot more code related to setting up the
engine are now loaded lazily, which should be a pretty nice win. I
also noticed that we are currently pulling in the `xss` library at
initial load to power the "sanitize" stuff, but I suspect with a
similar refactoring effort those usages can be removed too. (See
also #23790).
This PR does not attempt to fix the sanitize issue, but I think it
sets things up on the right trajectory for that to happen later.
Co-authored-by: David Taylor <david@taylorhq.com>
We have identified some third-party analytics scripts which do things like `window.I18n = window.I18n` 🤦♂️. This leads to the window object having a null I18n property, but `"I18n" in globalThis` returns true.
This commit checks whether `window.I18n` is a truthy value.
When Discourse first introduced brotli support, reverse-proxy/CDN support for passing through the accept-encoding header to our NGINX server was very poor. Therefore, a separate `/brotli_assets/...` path was introduced to serve the brotli assets. This worked well, but introduces additional complexity and inconsistencies.
Nowadays, Brotli encoding is well supported, so we don't need the separate paths any more. Requests can be routed to the asset `.js` URLs, and NGINX will serve the brotli/gzip version of the asset automatically.
Nowadays, themes/plugins have their templates compiled at build-time, so there is no need for us to carry the template compiler on the frontend during tests
The motivation of this PR is to remove our dependence on Ember's 'named outlets', which are removed in Ember 4+.
At a high-level, the changes can be summarized as:
- The top-level `discovery` route is totally emptied of all logic. The HTML structure of the template is moved into the `<Discovery::Layout />` component for use by child routes.
- `AbstractTopicRoute` and `AbstractCategoryRoute` routes now both lean on the `DiscoverySortableController` and associated template. This controller is where most of the logic from the old top-level `discovery` controller has ended up.
- All navigation controllers/templates have been replaced with components. `navigation/categories`, `navigation/category` and `navigation/default` were very similar, and so they've all been combined into `<Navigation::Default>`. `navigation/filter` gets its own component.
- The `discovery/topics` controller/template have been moved into a new `<Discovery::Topics>` component.
Various other parts of the app have been tweaked to support these changes, but I've tried to keep that to a minimum.
Anything from `<TopicList>` down is untouched, which should hopefully mean that a large proportion of topic-list-customizing themes are unaffected.
For more information, see https://meta.discourse.org/t/282816
We updated scheduled admin checks to run concurrently in their own jobs. The main reason for this was so that we can implement re-check functionality for especially flaky checks (e.g. group e-mail credentials check.)
This works in the following way:
1. The check declares its retry policy using class methods.
2. A block can be yielded to if there are problems, but before they are committed to Redis.
3. The job uses this block to either a) schedule a retry if there are any remaining or b) do nothing and let the check commit.
When submitting files through the form template upload field, we were having an issue where, although a validation error message was being presented to the user, the upload was still coming through, because `PickFilesButton`'s validation happens **after** the Uppy mixin finished the upload and hit `uploadDone`.
This PR adds a new overridable method to the Uppy mixin and overrides it with the custom validation, which now happens before the file is sent.
Additionally, we're now also using `uploadingOrProcessing` as the source of truth to show the upload/uploading label, which seems more reliable.
This work includes the following updates for the new lightbox:
- Show carousel by default if there are more than 1 image in a post
- Removes toggling of carousel on mobile - now always open if there are more than 1 image
- Updates swipe down gesture on mobile to close lightbox (previously used to toggle carousel)
- Removes swipe up gesture on mobile (was previously used to close lightbox)
This change removes the background image (which is the small version of the uploaded image) from the lightbox backdrop.
Now a solid color (dark grey) is used for the backdrop so we can distinguish between the lightbox's head, body and footer.
This PR does some preparatory refactoring of scheduled admin checks in order for us to be able to do custom retry strategies for some of them.
Instead of running all checks in sequence inside a single, scheduled job, the scheduled job spawns one new job per check.
In order to be concurrency-safe, we need to change the existing Redis data structure from a string (of serialized JSON) to a list of strings (of serialized JSON).
This aims to help admins and developers identify the cause of loading issues on routes.
As with other theme/plugin errors, the UI banner is only shown to administrators. For non-admins, the information is only written to the browser console.
When uploading images, they are assigned a dominant color which gets used in various places, such as Discourse Hub and the new lightbox. Previously in chat we didn't assign this attribute, so it was defaulting to a null value. We did however use it as an inline CSS style for the image background (which is visible while the image is downloaded).
This change adds data-dominant-color to the uploaded image in chat and uses it correctly within lightbox.
This commit introduces a new feature that allows theme developers to manage the transformation of theme settings over time. Similar to Rails migrations, the theme settings migration system enables developers to write and execute migrations for theme settings, ensuring a smooth transition when changes are required in the format or structure of setting values.
Example use cases for the theme settings migration system:
1. Renaming a theme setting.
2. Changing the data type of a theme setting (e.g., transforming a string setting containing comma-separated values into a proper list setting).
3. Altering the format of data stored in a theme setting.
All of these use cases and more are now possible while preserving theme setting values for sites that have already modified their theme settings.
Usage:
1. Create a top-level directory called `migrations` in your theme/component, and then within the `migrations` directory create another directory called `settings`.
2. Inside the `migrations/settings` directory, create a JavaScript file using the format `XXXX-some-name.js`, where `XXXX` is a unique 4-digit number, and `some-name` is a descriptor of your choice that describes the migration.
3. Within the JavaScript file, define and export (as the default) a function called `migrate`. This function will receive a `Map` object and must also return a `Map` object (it's acceptable to return the same `Map` object that the function received).
4. The `Map` object received by the `migrate` function will include settings that have been overridden or changed by site administrators. Settings that have never been changed from the default will not be included.
5. The keys and values contained in the `Map` object that the `migrate` function returns will replace all the currently changed settings of the theme.
6. Migrations are executed in numerical order based on the XXXX segment in the migration filenames. For instance, `0001-some-migration.js` will be executed before `0002-another-migration.js`.
Here's a complete example migration script that renames a setting from `setting_with_old_name` to `setting_with_new_name`:
```js
// File name: 0001-rename-setting.js
export default function migrate(settings) {
if (settings.has("setting_with_old_name")) {
settings.set("setting_with_new_name", settings.get("setting_with_old_name"));
}
return settings;
}
```
Internal topic: t/109980
Followup to b53449eac9, we cannot
generate the links to plugin admin pages in this way because it
depends on which plugins are installed; we would need to somehow
do it at runtime. Leaving it out for now, for people who need to
find these admin routes the Ember Inspector extension for Chrome
can be used in the meantime.
Since we don't have icons or access to the JS that transforms
hashtag icon placeholders into their proper icons and colours
on embed and publish pages, we need to at least show _something_
and make sure the hashtags are not totally broken on these pages.
NOTE: Most of this is experimental and will be removed at a later
time, which is why things like translations have not been added.
The new /admin-revamp UI uses a sidebar for admin nav. This initial
step adds a script to generate a map of all the current admin nav
into a format the sidebar to read. Then, people can experiment
with different changes to this structure.
The structure can then be edited from `/admin-revamp/config/sidebar-experiment`,
and it is saved to local storage so people can visually experiment with different ways
of showing the admin sidebar links.
Two changes were introduced:
1. Reorder links on sidebar section is removed. Clicking and holding the mouse for 250ms was unintuitive;
2. Fixed bugs when reorder is done in edit modal.
This fixes an edge case where the layout of a onebox with a gif avatar
was broken. Oneboxes have specific styling attached to avatar images and
the pausable animated image treatment was breaking that styling.
Files in `/assets/*` are given digests by sprockets, and we don't have any infrastructure for accessing those URLs in SCSS files. Instead, we should put this image with other similar images in the `public/images` directory, and then use the `absolute-image-url` helper so that it correctly uses the CDN where available.
- Add prefixes to Ember deprecations (previously was just Discourse deprecations)
- Allow logic to work in tests (where window.Discourse is not defined)
- Detect `{plugin}_tests.js` files
- Optimise dev/test regex logic out of the production build using `if(DEBUG)`
As part of #23816, which sought to strip out thousand separators, we also accidentally strip out signs. This is making it impossible to disable some settings which require a -1 to disable. Instead of stripping non-digits, strip anything that isn't a sign or a digit.
* UX: add discourseLater call to add breathing room for animation
Allow for smoother animations on lower end devices.
Create time between render and animations.
extend panel width targets by 20 px to account for shadows as well