Transpiling to `/raw-templates` is important so that they are detected by the `eager-load-raw-templates` initializer. Prior to 16c6ab86 this wasn't a problem because all connector modules were being eager-loaded. Now that connectors are lazily loaded, it's critical that `eager-load-raw-templates` does the eager loading. This problem doesn't affect themes because they compile raw templates into an iife instead of a `define()` module.
Unfortunately we don't have any way to introduce automated testing for this part of our compilation pipeline. However, discourse-calendar will begin depending on this functionality imminently, so its tests will warn us of future regressions.
This commit introduces a 'shortcut' when rendering PluginOutlets which have no registered connectors. On my machine, this improves rendering performance of empty PluginOutlets by around 30-40% (tested by running tachometer on a `/latest` route with 600 plugin outlets).
* Minor style adjustments
* Removes "all" count because it's redundant to the count on New
* Updates generic class names with -- modifier to follow BEM and help avoid class name collisions
* Hides the toggle when bulk select is enabled (the UI ends up being too busy)
Previously we were discovering plugin outlets by checking first for dedicated template files, and then looking for classes to match them. This doesn't work for components which are entirely defined in JS (e.g. those authored with gjs, or those which are re-exports of a colocated component).
This commit refactors our detection logic to look for both class and template modules in a single pass. It also refactors things so that the modules themselves are required lazily when needd, rather than all being loaded during app boot.
This PR adds a new toggle to switch the (new) /new list between showing topics with new replies (a.k.a unread topics), new topics, or everything mixed together.
Prior to this fix we would always re-set `this.attrs` with `this.attrs` when defined, which is both wasteful but also dangerous as `this.attrs` can possibly error when mutated.
Previously, we had a `showFooter` boolean on the application controller which would be set true/false in various routes by different routes/controllers. A global `routeWillChange` hook would set it `false` before every route transition, and the destination route/controller would have to set it `true` for the footer to show correctly.
This commit replaces that with a new 'declarative' system. Instead of having to set the value true/false manually, UIs which need the footer to be hidden can simply include the `{{hide-application-footer}}` helper in their template when needed. The helper/service will automatically keep track of all the current invocations of that helper, and only show the footer when there are 0 invocations.
This significantly simplifies things, and removes the need for many observers and controller injections, both of which are considered 'code smells' in modern Ember applications.
What is the problem here?
When transiting between `/filter` routes with different `q` query
params, the input field is not updating to include the values in the `q`
query param. This was because we were setting the value of the input
field in the constructor of the controller but controllers are actually
singletons in Ember so setting the value of the input field is only done
once when the controller is initialised.
What is the fix here?
Instead of setting the value of the input field in the controller, we
set the value in the `setupController` hook in the route file.
* scrub non-a html tags from tag descriptions on create, strips all tags from tag description when displayed in tag hover
* test for tag description links
* UX: basic render-tag test
* UX: fix linting
* UX: fix linting
* fix broken tests
* Update spec/models/tag_spec.rb
Co-authored-by: Penar Musaraj <pmusaraj@gmail.com>
* UX: use has_sanitizable_fields instead of has_scrubbable_fields to ensafen tag.description
---------
Co-authored-by: Penar Musaraj <pmusaraj@gmail.com>
104baab5 fixed double-counted pageviews for the initial page load. Under the default 'loading slider' implementation, that resolved all the known problems.
However, under the 'loading spinner', there is an additional problem. In 'spinner' mode, each navigation within the JS app involves transitioning to an intermediate 'loading' route. Previously, this intermediate state was being treated as a separate page by the app, and so any ajax requests fired during it would be counted as a distinct pageview. One known case of this is the `/presence/get` request which is made when logged-in users visit a topic.
This commit updates the logic to ignore 'intermediate' transitions, and introduces regression tests for both the 'spinner' and 'slider' modes.
In this commit 2.5 years ago, variables for showOnUserCard and showOnProfile were removed, but we still used them in the component. e29605b
This corrects the variable names and adds a test to confirm the text is now shown.
* DEV: allow `formTemplateIds` to be explicitly set via the composer service
* DEV: allow to skip the configured form template via the composer service
This resolves the issue in #23064.
This issue arises because we need to produce the trees for the
auxilary bundles in `ember-cli-build.js` to pass these trees as
argument to `app.toTree()`. In order to produce these trees, the
code internally need to set up babel, which deep-clones the addons'
babel configs.
When using `@embroider/macros`, the addon's babel config includes a
`MacrosConfig` object which is not supposed to be touched until the
configs are "finalized". In a classic build, the finalization step
happens when `app.toTree()` is called. In Embroider, this happens
somewhere deeper inside `CompatApp`.
We need to produce these auxilary bundle trees before we call
`app.toTree()` or before constructing `CompatApp` because they
need to be passed as arguments to these functions. So this poses a
tricky chicken-and-egg timing issue. It was difficult to find a
workaround for this that works for both the classic and Embroider
build pipeline.
Of all the internal addons that uses the auxilary bundle pattern,
this only affets `pretty-text` as it is (for now, at least) the
only addon that uses `@embroider/macros`.
Taking a step back, the only reason (for now, at least) it was
introduced was for the loader shim for the `xss` package. This
package is actually used inside the lazily loaded markdown-it
bundle. However, we didn't have a better way to include the dep
into the lazy bundle directly, so it ends up going into the main
addon tree, and, inturns, the discourse core bundle.
In core's main loader shim manifest, we already have an entry for
`xss`. This was perhaps a mistake at the time, but it doesn't make
a difference – as mentioned above, `xss` needs to be included into
the main bundle anyway.
So, for now, the simpliest solution is to avoid `@embroider/macros`
in these internal addons for the time being. Ideally we would soon
absorb these back into core as lazily loaded (`import()`-ed) code
managed by Webpack when we fully switch over to Embroider.
The new modal API removed the `#discourse-modal` id from the wrapper element, which meant that select-kit couldn't properly detect when it was inside a modal. This commit updates the detection to use `.fixed-modal` which will match both legacy and modern modals.
When we receive the stream parameter, we'll queue a job that periodically publishes partial updates, and after the summarization finishes, a final one with the completed version, plus metadata.
`summary-box` listens to these updates via MessageBus, and updates state accordingly.
The OpenComposer mixin comes from a time before we had a composer service. As well as being a general cleanup/refactor, this commit aims to removes interlinking between composer APIs and the discovery-related controllers which are being removed as part of #22622.
In summary, this commit:
- Removes OpenComposer mixin
- Adds and updates composer service APIs to support everything that `openComposer` did
- Updates consumers to call the composer service directly, instead of relying on the mixin (either directly, or via a route-action which bubbled up to some parent)
- Deprecates composer-related methods on `DiscourseRoute` and on the application route
Prior to this fix the user tip was rendered with panels and interfering with widget code. I suspect it was causing the widget node (revamped-hamburger-menu-wrapper) to not be removed, as a result clickOutside would be called two times, negating the effect of the click.
This fix is just rendering the tip in a different node, preventing the interference, it shouldn't impact behavior as the positioning is absolute.
This commit moves the calendar date and time picker shown in
the local dates modal into a core component that can be reused
in other places. Also add system specs to make sure there isn't
any breakages with this feature, and a section to the styleguide.
The original motivation for this change was to avoid mutating imported modules (by stubbing imported functions in tests)
Other than that it's a good practice to place code like this in services, especially (although not the case here) if it requires access to other services or controller.
The previous version of ember-on-resize-modifier depended on
ember-modifier@^3.2.7 while discourse had ember-modifier@^4.1.0.
As far as Yarn is concerned, it can accomplish this with:
node_modules
...
ember-modifier 4.1.0
...
ember-on-resize-modifier 1.1.0
...
ember-modifier 3.2.7
...
...
This does NOT work!
In a classic build everything is compiled down to AMD modules and
at runtime there can only be one uniquely named "ember-modifier"
module. When we have duplicates, depending on activation ordering,
one of them will randomly win.
In practice, it seems like ember-modifier 3.2.7 had "won" in the
current build, and we are shipping it to production, you can find
these modules in vendor.js like:
```js
;define("ember-modifier/-private/class/modifier", /* ... */, function(/* ... */) {
/* the 3.2.7 version with deprecations, etc */
})
/* ... */
;define("ember-modifier/index", /* ... */)
```
However, ember-auto-import also "found" the 4.1.0 version and in
one of the chunk.app.js:
```js
d('ember-modifier', /* ... */, function() { return __webpack_require__(/*! ember-modifier */ 227); });
```
...and in one of the chunk.vendors.js...
```js
/* 227 */
/*!****************************************************!*\
!*** ../node_modules/ember-modifier/dist/index.js ***!
\****************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* ...the 4.1.0 version... */
}),
```
So, in practice:
* We are brining both copies into the production build
* The 3.2.7 modules are available in the AMD loader as "ember-modifier/..."
* But 4.1.0 modules are available in the AMD loader as "ember-modifier"
* Because mostly it's consumed as `import ... from "ember-modifier";`, the
latter end up actually winning
* Because the newer code is compatible enough, and the deprecated features
are unused, it seems to work ok..?
But in the Embroider build, ember-auto-import doesn't emit those shims
anymore. It does process most of the core modules through Webpack so the
imports get correctly wired up to the 4.1.0 as expected, as they no longer
go through/need the runtime AMD loader.js.
The older 3.2.7 copy is _still_ shipped in the vendor bundle and registered
the same, but not "stomped over" by the EAI shims anymore. Our manual shims
(#22703, merged yesterday) are more "polite" and check `require.has(...)`
before defining the module, and since `require.has(...)` check for the
`/index` alias and returns `true`, our shim does not stomp the 3.2.7 modules
either.
So then, when our "auxilary bundles" (admin, plugins, etc) tries to import
`"ember-modifier", they get the 3.2.7 version.
There is a case when developer would like to go to separated mode but not show switch panel buttons. We need additional functions to show/add buttons to support this case.
* REFACTOR: Glimerify topic summarization widgets.
Simplifies all the logic for generating/regenerating summaries and expanding/collapsing the summary box. It makes streaming easier to implement since now we can subscribe to message bus directly from the component.
* Update app/assets/javascripts/discourse/app/components/summary-box.hbs
Co-authored-by: David Taylor <david@taylorhq.com>
* Update app/assets/javascripts/discourse/app/components/summary-box.hbs
Co-authored-by: David Taylor <david@taylorhq.com>
* Update app/assets/javascripts/discourse/app/components/summary-box.hbs
Co-authored-by: David Taylor <david@taylorhq.com>
---------
Co-authored-by: David Taylor <david@taylorhq.com>
This adds a new `loaderShim()` function to ensure certain modules
are present in the `loader.js` registry and therefore runtime
`require()`-able.
Currently, the classic build pipeline puts a lot of things in the
runtime `loader.js` registry automatically. For example, all of
the ember-auto-import packages are in there.
Going forward, and especially as we switch to the Embroider build
pipeline, this will not be guarenteed. We need to keep an eye on
what modules (packages) our "external" bundles (admin, wizard,
markdown-it, plugins, etc) are expecting to be present and put
them into the registry proactively.
There is no decorateCooked equivalent for small action posts,
so we need to manually call decorateHashtags when there is a custom
message for small action posts in order for the hashtags to get
their coloured icon/square.
Bug when you click fast on the switch panel button. It is happening because we are not waiting for the transition to finish before update state.
In addition, unused currentPanel property was removed.
This commit removes any logic in the app and in specs around
enable_experimental_hashtag_autocomplete and deletes some
old category hashtag code that is no longer necessary.
It also adds a `slug_ref` category instance method, which
will generate a reference like `parent:child` for a category,
with an optional depth, which hashtags use. Also refactors
PostRevisor which was using CategoryHashtagDataSource directly
which is a no-no.
Deletes the old hashtag markdown rule as well.
This fixes:
- a regression from 30c152c, where navigating to a topic's last reply
via keyboard would lose track of the topic when returning to the topic
list
- an issue where if a topic's last post is a small post, navigating to it
via keyboard would not focus the post
Co-authored-by: David Taylor <david@taylorhq.com>
Adds a padding-bottom to the wrapper to avoid cutting the message on the mobile app and sets a max-width to align with the timeline on the desktop.
Fixes a bug on mobile where we updated the preference, but the user had a single list.
When Ember rendering fails for some reason, `this.header` will be undefined. This causes site-header to raise an error, which often gets printed to the console more obviously than the actual root cause.
This commit makes site-header fail more gracefully in this situation, to avoid it being a red-herring during development/debugging.
This function was previously expecting multiple services to be injected on any class that uses it. This kind of hidden requirement leads to some very difficult-to-debug situations, so this commit updates the function to lookup all its required services inline.
The filter-mode mixin was previously serving two distinct purposes via a complex arrangement of getters/setters:
1. To calculate a filterMode, given values for category, filterType and noSubcategories
2. To calculate a filterType, given a filterMode
This commit splits the mixin into two functions, and updates all call sites to use them instead of the mixin.
This makes more sense (and is likely faster) than redefining the entire route for every call to `buildTopicRoute`. Also moves the top-specific logic into the route rather than injecting it via an initializer.
Similar to d5107d1aba
This brings the theme development experience (via the discourse_theme cli) closer to the experience of making javascript changes in Discourse core/plugins via Ember CLI. Whenever a change is made to a non-css theme field, all clients will be instructed to immediately refresh via message-bus.
In #20135 we prevented invalid inputs from being accepted in category setting form fields on the front-end. We didn't do anything on the back-end at that time, because we were still discussing which path we wanted to take. Eventually we decided we want to move this to a new CategorySetting model.
This PR moves the num_auto_bump_daily from custom fields to the new CategorySetting model.
In addition it sets the default value to 0, which exhibits the same behaviour as when the value is NULL.
This commit makes some visual tweaks to the admin panel plugin list, and introduces functional 'toggle switches' for admins to enable/disable plugins more easily.
Co-authored-by: Jordan Vidrine <jordan@jordanvidrine.com>
We need these Ember framework class overrides to be applied before anything attempts to extend them. An initializer is too late, because initializer files may `import` a module which defines classes which extend the framework classes.
In the past this rarely mattered because Ember's legacy `SomeObject.extend` is quite forgiving - it will respect changes made to `SomeObject` right up until the first `.create()` call. However, the native class syntax (`class extends SomeObject`) will 'freeze' `SomeObject` as soon as the class is defined.
Edit community section button is hidden in secondary/more section. However, when there are no secondary links, then more section is not shown. In that case, we should still display an edit button for admins, so they can edit the section.
Should fix an iOS regression in f5e8e73. iOS does not pull up the keyboard if the `.focus()` call is delayed by a rendering timeout or an asynchronous ajax call. This PR adds earlier `.focus()` calls if the input element is present.
This was forgotten during the work in 22991bba44
This revealed two differences we were depending on: the merged `actions` hash (re-implemented on the service), and a couple of calls to `composer.send` (now removed)
1. recent css regression related to modal upgrade
2. autofocus and on-enter regressions
3. array related linting issue (reliance on Ember's firstObject/lastObject)
This change prevents event bubbling for the Escape key on all modals. Currently when we close the modal using the Escape key, all other event listeners attached will also be triggered (such as closing the chat drawer if it's open).
When we use the escape key to exit lightbox for images within a chat channel, it also closes the chat drawer due to event bubbling (since both lightbox and chat use an event listener on the escape key).
This change prevents event bubbling when using the escape key within lightbox, which means that it will close the lightbox but won't close the chat drawer.
The escape key is used as a shortcut to escape the Discourse Lightbox. However, some browsers also use the escape key to exit fullscreen mode.
This change is to allow escaping the lightbox when browser is in fullscreen mode, while preventing any behavior associated with the Escape key (such as exiting fullscreen). This has to be done on the keydown event, as this means we can handle our logic and then preventDefault before the browser tries to exit fullscreen.
We only want to scroll to the top for successful transitions. If a transition is aborted (e.g. when clicking a chat link when chat is in drawer mode) then we should maintain the existing scroll location.
We were proxying all `/assets/*` requests through to the origin. In local development that was fine, because Rails was able to serve files from the `dist/` directory. But when proxying to a remote origin, we want the local ember-cli to serve its own JS assets
We never propagated the preference change because of the early return, meaning lists listening to it never got to decide if they had to remain hidden.
Also, we don't want to track the preference when there's a single list, as the user didn't choose to see it.
This PR updates how we display related and suggested topics on mobile and desktop. It adds a new `PluginOutlet` specifically designed for adding new topic lists, which automatically work if following the same conventions as the ones inside `<MoreTopics />`.
While we display lists side by side on desktop, we only display one in mobile. You can switch to another one by clicking on the nav pills, and we'll automatically save your preference for next time.
FEATURE: Only approved flags for post counters
* Why was this change necessary?
The counters for flagged posts in the user's profile and user index from
the admin view include flags that were rejected, ignored or pending
review. This introduces unnecessary noise. Also the flagged posts
counter in the user's profile includes custom flags which add further
noise to this signal.
* How does it address the problem?
* Modifying User#flags_received_count to return posts with only approved
standard flags
* Refactoring User#number_of_flagged_posts to alias to
User#flags_received_count
* Updating the flagged post staff counter hyperlink to navigate to a
filtered view of that user's approved flagged posts to maintain
consistency with the counter
* Adding system tests for the profile page to cover the flagged posts
staff counter
We already handled 429 rate limit errors correctly. This commit adds backoff logic to other types of error to avoid requests being retried every second.
The store expects values for property names ending with `_id` to be a resource id
and `_ids` to be an array of resource ids.
This change ensures the store gracefully handles situations where an
embedded field with incompliant data structure sneaks its way to production.
By default, only 10 members are highlighted on group cards. However,
joining/leaving a big group via the buttons on the group card results in
up to 50 members being highlighted. For large groups, this causes the card
to move off-screen.
This happens because, while the initial render explicitly fetches only 10
members, we don't seem to apply the same limit as part of the member
reload performed when a user leaves/joins via the buttons on the card.
This PR fixes that by only making the first 10 users available for
highlight regardless of the number of members loaded in the store.
Using pinch-zoom on mobile devices with lightbox images can lead to scrolling of background content.
This change handles this by capturing the window.scrollY value when opening the lightbox, then when exiting we check if the scroll position has changed and reset it.
provide the ability to edit theme settings in the json editor, and also copy them as a text file so they can be pasted into another instance.
Reference: /t/65023
## Problem
History modal is flashing when changing revision versions
## Context
This was introduced in https://github.com/discourse/discourse/pull/22666
We need to have a conditional loading spinner for the initial paint of the history modal as we don't have the revision yet loaded, so this can cause some odd rendering issues. At the same time we don't want to display the loading spinner each time we toggle between the revision versions, because the loading spinner replaces the revision body causing the modal sizes to be drastically different resulting in _jumping_ or _flashing_.
## Fix
Render the loading spinner only on the first paint of the modal.
https://github.com/discourse/discourse/assets/50783505/8d19275e-86a5-4132-8a1f-af4b4f5301a6
Followup to f5e8e73.
This switches the placeholder label to the existing string "optional
tags" and only shows it if there are no items picked.
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
Change to drag move event handling. When position of mouse changed, we can assume it is not drag and drop, and we should keep default behaviour.
Otherwise, we stop propagation of the event to handle drag and drop correctly. s
New API to change sidebar mode. We defined two:
Separated - only sections belonging to specific panel are displayed, and buttons to switch the panel are available as well.
Combined - all sections are displayed together and switch panel buttons are not visible.
In addition, as a part of refactoring, a new service called SidebarState was introduced.
The `/u` route was broken when there were no directory columns because
its order parameter relied on the first column's name. This commit adds
a `likes_received` as the default order when there are no columns, which
results in a list of users being output without any additional columns.
For this very edge case, that's better than a JS error.
Fixes issue with scrolling background when lightbox is opened on mobile.
Since we rely on swiping for navigating lightbox galleries on mobile, we want to disable document scrolling.
Why this change?
We were verifying that a url for a section link in a custom sidebar
section is valid by passing the url string to `Router#recognize`.
If a `rootURL` has been set on the router, the url string that is passed
to `Router#recognize` has to start with the `rootURL`.
This commit fixes the problem by ensuring that `RouteInfoHelper` adds
the application subfolder path before calling `Router#recognize` on the
url string.
Why this change?
When setting up the `IntersectionObserver`, we did not account for the
top margin and padding causing no intersection event to fire when the
last tag is load into view. This commits fixes the problem by setting a
bottom margin using the `rootMargin` option when setting up the
`IntersectionObserver`.
This commit also improves the test coverage surrounding the loading of
more tags.
We recently replaced another ignore user modal with a Glimmer and DModal based component. This change makes use of that same component in the user card ignore modal by adding an enableSelection flag.