The `custom` notification type is a generic notification type that plugins can use for their own notifications, so it doesn't make sense to fallback to the implementation of `linkTitle` in the base notification type because core can't possibly come up with a title suitable for all custom notifications.
Core now has support for mobile-specific overrides of component templates, so we can now safely colocate the last batch of core components.
Followup to 524cb5211b
Long-term, we may aim to remove the ability to have mobile-specific component templates. But for now, this commit will allow us to colocate a component's template, while keeping the mobile-specific-override functionality for core, plugins and themes.
When installing themes using the "Install this theme component" button
on meta.discourse.org, we pass the repo name and URL via query params.
However, these stick. So if a user cancels the installation, on the
next navigation to the same route, they'll see the modal again.
This PR clears the query params of the controller when dismissing the
modal.
The previous `createPreviewComponent` implementation was problematic for template colocation. We can achieve the same result using normal component class inheritance.
The template is defined with dashes. Our resolver forgave this difference, and matched things up correctly. However, when we come to colocate templates, the names must match exactly.
The JS component definition is in the admin bundle, but the template was in the main bundle. This was identified while attempting to colocate component templates in the discourse/app directory
Having a template-lint-disable comment with whitespace trimming was triggering a message during build, likely due to a bug in the build process.
```
unexpectedly found "! template-lint-disable ~" when slicing source, but expected " template-lint-disable "
```
This commit avoids the problem by moving the template-lint-disable comment outside of the stripped-whitespace area.
Dynamically setting the `layoutName` is not compatible with template colocation. Instead, we can give each field type a dedicated component and make `<UserField` a wrapper which renders the correct implementation.
Dynamically setting `layoutName` is not compatible with template colocation. This commit updates `<CustomHTML` to remove the `custom-html-container.hbs` template, and instead dynamically sets the `layout` property as required. Once the deprecated 'custom hbs' feature is removed, this can be updated to be a regular colocated component template.
We often have the need to use rich HTML in dialog messages (to show lists, icons, etc.). Previously, our only option was to wrap the message in an `htmlSafe()` call. This PR adds the ability to pass a component name and model to the dialog, which means that we can write the HTML in regular Ember components.
Example, whereas previously we would do this:
```
this.dialog.deleteConfirm({
message: htmlSafe(`<li>Some text</li>`),
});
```
instead we can now do this:
```javascript
import SecondFactorConfirmPhrase from "discourse/components/dialog-messages/second-factor-confirm-phrase";
...
this.dialog.deleteConfirm({
title: I18n.t("user.second_factor.disable_confirm"),
bodyComponent: SecondFactorConfirmPhrase,
bodyComponentModel: model,
})
```
The model passed to the component is optional and will be available as `@model` in the Handlebars template.
Previously, all plugin connector templates would be rendered using the PluginConnector classic component definition. This commit introduces three key changes:
1. PluginOutlets can be passed `@defaultGlimmer={{true}}`, which will cause all connectors to be rendered as highly-performant 'template only glimmer components'. For now, to avoid breaking backwards compatibility, this is only intended for use on newly introduced PluginOutlets.
2. Connector js files can now directly export component definitions. This allows connectors on existing outlets to start using Glimmer components (template-only, or otherwise) straight away. It also makes it much more ergonomic to introduce custom logic to outlets. `shouldRender` continues to be supported (as a static class method).
3. Outlet arguments are now made available as `@outletArgs` in classic, glimmer and template-only-glimmer connectors. In glimmer and template-only-glimmer connectors, this is the only way to access the outlet's arguments. In classic connectors, the old methods still function - `@outletArgs` exists as a path for incremental migration
Previously after uploads completed post raw would drift.
If you autocompleted text after the upload stub got replaced it would
insert in the wrong position.
The `Composer - current time` test would sometimes fail due to a
1-second difference. We don't really need per-second fidelity here, the
key thing this needs to test is that the shortcut works and adds today's
date. I have updated the test to reflect that.
Ember CLI will automatically run babel transformations in parallel when the config is 'serializable', and can therefore be applied in multiple processes automatically. If any plugin is defined in an unserializable way, parallelisation will be disabled.
Our discourse-widget-hbs transformer was causing parallelisation to be disabled. This commit fixes that, and also enables the throwUnlessParallelizable flag so that we catch this kind of issue more easily in future.
This commit also refactors our deprecation silencing system into its own file, and uses a fake babel plugin to ensure deprecations are silenced in babel worker processes.
In our GitHub CI jobs, this doubles the speed of ember builds (1m30s -> 45s). It should also improve production deploy times, and cold-start dev builds.
When a user pauses a youtube video and scrolls up high enough to load
new posts, the video either rewinds or restarts depending on the browser.
The problem is solved by patching virtual-dom to handle element prepends
without reordering old elements.
Long-term, Discourse intends to move away from the vdom/widget implementation, so this is intended as a short-term solution. More context at https://meta.discourse.org/t/57692
Co-authored-by: David Taylor <david@taylorhq.com>
Remove the per user groups based site setting in favor of a global site setting as we want to roll the glimmer topic timeline out to anon users as well as site users.
- Add `enable_experimental_topic_timeline` site setting
- Remove `enable_experimental_topic_timeline_groups` site setting
Improvements for this PR: https://github.com/discourse/discourse/pull/20057
What was fixed:
- [x] Use ember transitions instead of full reload
- [x] Link was inaccurately kept active
- [x] "+ save" renamed to just "save"
- [x] Render emojis in link name
- [x] UI to set icon
- [x] Delete link is trash icon instead of "x"
- [x] Add another link to on the left and rewording
- [x] Raname "link name" -> "name", "points to" -> link
- [x] Add limits to fields
- [x] Move add section button to the bottom
This PR is a major change to Sass compilation in Discourse.
The new version of sass-ruby moves to dart-sass putting we back on the supported version of Sass. It does so while keeping compatibility with the existing method signatures, so minimal change is needed in Discourse for this change.
This moves us
From:
- sassc 2.0.1 (Feb 2019)
- libsass 3.5.2 (May 2018)
To:
- dart-sass 1.58
This update applies the following breaking changes:
>
> These breaking changes are coming soon or have recently been released:
>
> [Functions are stricter about which units they allow](https://sass-lang.com/documentation/breaking-changes/function-units) beginning in Dart Sass 1.32.0.
>
> [Selectors with invalid combinators are invalid](https://sass-lang.com/documentation/breaking-changes/bogus-combinators) beginning in Dart Sass 1.54.0.
>
> [/ is changing from a division operation to a list separator](https://sass-lang.com/documentation/breaking-changes/slash-div) beginning in Dart Sass 1.33.0.
>
> [Parsing the special syntax of @-moz-document will be invalid](https://sass-lang.com/documentation/breaking-changes/moz-document) beginning in Dart Sass 1.7.2.
>
> [Compound selectors could not be extended](https://sass-lang.com/documentation/breaking-changes/extend-compound) in Dart Sass 1.0.0 and Ruby Sass 4.0.0.
SCSS files have been migrated automatically using `sass-migrator division app/assets/stylesheets/**/*.scss`
Prior to this fix on mobile the card-cloak would not get removed if the user/group card was leading to a non existing user/group.
The fix ensures hidden class is removed each time we call show.
We recently had a bug which caused auto-bumping to "not work". The problem was that the value had been set to 0.5, which when coerced to an integer turned into 0. So the feature is "working as intended", but there's a possibility of misconfiguration.
When looking into this, I noticed that the inputs on the category settings page doesn't have any particular sanitisation in the front-end, and also one or two validations missing in the back-end.
This change:
- Takes an existing component, NumberField and enhances that by only allowing numeric input, essentially turning it into a managed input using the same approach as our PasswordField.
- Changes the numeric inputs on category settings page to use this component.
- Adds appropriate min constraints to the fields to disallow out-of-range values.
- Adds missing back-end validations to relevant fields.
This commits adds the ability to add a header to the embedded comments
view. One use case for this is to allow `postMessage` communication
between the comments iframe and the parent frame, for example, when
toggling the theme of the parent webpage.
This is an alternative way to use `RenderGlimmer` which can be more ergonomic for iterative updates of a codebase. For documentation, see `widgets/render-glimmer.js`
Fixed had been added when autocomplete was used in the discourse header. This shouldn't be needed anymore. This was causing the preventOverflow to not work correctly on Android.
This fix fix also adds an optimisation to refer top of the input when on mobile. This is done to avoid cases where the screen is actually slightly taller than the viewport with keyboard visible on Android leading popper to think there's space under the input.
- Move docking logic (intersection / dockAt / etc) from `glimmer-topic-timeline` -> `topic-timeline/container` to live alongside the `postScrolled` hook.
- Toggle `timeline-docked` and `timeline-docked-bottom` when we are at the bottom of a topic. This returns the missing animation to the glimmer-topic-timeline (pictured below).
https://user-images.githubusercontent.com/50783505/216655735-906ccd2a-b77e-45af-9a7b-c22680eca2dc.mov
Previously `helper.renderGlimmer()` would always create a new wrapper element. This is required when using `RenderGlimmer` within widgets, where there is no direct access to DOM elements. However, when using within `decorateCooked`, we have the ability to pass an existing element to `{{#in-element}}` and have the glimmer content appended with no additional wrappers.
This commit makes the `renderInto` accept an existing DOM node for this 'append' behavior. The previous 'new wrapper element' behaviour is still used when a string is passed.
# Context
The class of `widget-button` was kept in the upgraded version of the topic timeline to keep the preexisting logic of how we open / close child and parent modals.
# Problem
<img width="1242" alt="Screenshot 2023-02-02 at 3 45 53 PM" src="https://user-images.githubusercontent.com/50783505/216456778-11a3d0ce-5e33-4b85-89af-a2a32e39a1f6.png">
With the `widget-button` class removed from the topic timeline, clicking the button (highlighted in the image above) would close itself when populating the `jumpToPostPrompt` modal. This is not the behavior we want so class was kept on the button. The upgrade to ember octane entails moving away from widgets and all of its functionality... so we don't want to carry the debt of utilizing the `widget-button` class.
# Solution
Create a new class `.timeline-open-jump-to-post-prompt-btn` to be added to the `_expanded` function. When this class is present on a child or a parent of the button clicked, we do not collapse the modal. This gives us the expected behavior of maintaining both modals open at the same time.
<img width="1176" alt="Screenshot 2023-02-02 at 3 50 59 PM" src="https://user-images.githubusercontent.com/50783505/216457612-ab313758-bfa9-4913-bd29-d5224faf5187.png">
# Other
Obviously adding this as jquery is not ideal, but to prevent scope creep we will need to refactor this in a separate PR.
Allows users to configure their own custom sidebar sections with links withing Discourse instance. Links can be passed as relative path, for example "/tags" or full URL.
Only path is saved in DB, so when Discourse domain is changed, links will be still valid.
Feature is hidden behind SiteSetting.enable_custom_sidebar_sections. This hidden setting determines the group which members have access to this new feature.
- Rename `class` getter -> `classes` seeing that we are dealing with multiple classes
- Add `show` class to fullscreen topic timeline via `did-insert` to handle how CSS transitions only apply when an existing element changes its properties. We need to wait until `timeline-fullscreen` is painted to the DOM, and then add the `show` class later.
# Problem
Creating a post on a topic, where the timeline is not shown by default, does not update the visibility state dynamically. You must refresh the page to have the timeline appear.
# Solution
This PR hooks into the `post-stream:posted` app event and checks if we can now display the timeline after a post has been created. This will update the visibility state dynamically.
This PR introduces a proper `action` to the topic timeline `back-button` which will fix the button not being clickable (or functional) as well as removing a duplicate setting of `this.lastReadTop` which was causing odd positionings of the button.
This is very difficult to test due to the fact you have to manage the "read history" for a user to have the back button populate. We will have to move forward without one (as we did in the last version of the timeline 😅) for now.
`helper.renderGlimmer` will return an HTML element which can be added to a post's `cooked`
Example usage:
```
import { hbs } from "ember-cli-htmlbars";
api.decorateCookedElement((cooked, helper) => {
const glimmerElement = helper.renderGlimmer(
"div.my-wrapper-class",
hbs`<DButton @icon={{@data.param}} @translatedLabel="Hello world from Glimmer Component"/>`,
{ param: "user-plus" }
);
cooked.appendChild(glimmerElement);
}, { onlyStream: true, id: "my-id" });
```
See `widgets/render-glimmer.js` for more detailed usage information.
For a user whose username has an uppercase character, the new user menu
dropdown was not defaulting to "Inbox" because the Ember router uses
lowercased usernames which were not matching with the `username`
property. Switching to `username_lower` fixes the issue.
In a private plugin, we need to show an error message containing HTML
when the Grant Admin action fails. This change introduces a new flag
(`html_message: true`) that when used will allow the dialog to render
the HTML tags in the error message correctly.
We don't need a full glimmer component here - the class definition was empty. We can use templateOnly() for slightly improved performance.
Setting `component.name` improves how MountWidget is displayed for debugging in the Ember Inspector browser extension.
1. What is the problem here?
When a user's reviewables count changes, the changes are published via
MessageBus in a background Sidekiq job which means there is a delay before the
client receives the MessageBus message with the updated count. During
the time the reviewables count for a user has been updated and the time
when the client receives the MessageBus message with the updated count,
a user may view the reviewables list in the user menu. When that happens, the number of
reviewables in the list may be out of sync with the count shown.
2. What is the fix?
Going forward, the response for the `ReviewablesController#user_menu_list` action will include the user's reviewables count as
the `reviewables_count` attribute. This is then used by the client side
to update the user's reviewables count to ensure that the reviewables
list and count are kept in sync.
Due to the way templates work, the incorrect variable (user instead of item) was not causing any error, and just failing silently to display the avatar.
This commit is also providing a basic spec for completion of users and groups.
We've had a couple of problems with the R2 gem where it generated a broken RTL CSS bundle that caused a badly broken layout when Discourse is used in an RTL language, see a3ce93b and 5926386. For this reason, we're replacing R2 with `rtlcss` that can handle modern CSS features better than R2 does.
`rltcss` is written in JS and available as an npm package. Calling the `rltcss` from rubyland is done via the `rtlcss_wrapper` gem which contains a distributable copy of the `rtlcss` package and loads/calls it with Mini Racer. See https://github.com/discourse/rtlcss_wrapper for more details.
Internal topic: t/76263.
## Why do we need this change?
When loading the ember app, [MessageBus does not start polling immediately](f31f0b70f8/app/assets/javascripts/discourse/app/initializers/message-bus.js (L71-L81)) and instead waits for `document.readyState` to be `complete`. What this means is that if there are new messages being created while we have yet to start polling, those messages will not be received by the client.
With sidebar being the default navigation menu, the counts derived from `topic-tracking-state.js` on the client side is prominently displayed on every page. Therefore, we want to ensure that we are not dropping any messages on the channels that `topic-tracking-state.js` subscribes to.
## What does this change do?
This includes the `MessageBus.last_id`s for the MessageBus channels which `topic-tracking-state.js` subscribes to as part of the preloaded data when loading a page. The last ids are then used when we subscribe the MessageBus channels so that messages which are published before MessageBus starts polling will not be missed.
## Review Notes
1. See https://github.com/discourse/message_bus#client-support for documentation about subscribing from a given message id.
The `tagName` argument is now deprecated. This commit uses a codemod (https://github.com/discourse/discourse-ember-codemods/tree/main/transforms/extract-plugin-outlet-tagname) to automatically remove the `@tagName` from all PluginOutlet invocations, and create a matching wrapper element so that the HTML structure is unchanged. We may want to remove some/all of these wrappers entirely in future, but that would be a riskier change which we should tackle on a case-by-case basis.