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.
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.
Interestingly, this missing parenthesis was silently repaired under Chrome/Firefox, but seems to have caused some issues on other browsers.
https://meta.discourse.org/t/272496
Why this change?
We're already displaying a category's description as the title attribute
on the category section link. We should do the same for tags as well.
* Why was this change necessary?
The current logic in the user.hbs template file does not render the
trust level element for the user's info panel when the user is TL0,
because 0 is treated as falsey in the `if` conditional block.
Ref: https://meta.discourse.org/t/tl0-not-displayed-on-users-profile-pages/271779/10
* How does it address the problem?
This PR adds a predicate helper method local to the user controller that
includes an additional check which returns true if the trust_level of
the user is 0 on top of the existing logic. This allows TL0 users to
have their trust level rendered correctly in their profile's info panel.
In Safari, clicking any image in a lightbox gallery results in the first image loading (instead of the clicked image).
Previously we relied on document.activeElement to determine which lightbox image was clicked. However in Chrome the active element is the lightbox selector (a.lightbox), whereas in Safari the active element defaults to the body tag.
Currently the startingIndex that is calculated within processHTML() is used by lightbox to determine which image to load first. The starting index is currently achieved by checking each lightbox element within the gallery against the active element.
To fix this issue we can use the event.target to get the clicked image, then use the closest selector and pass that into the function to do the matching and return the correct startingIndex.
1. in the test, hiding is now done with css so if element gets rerendered it won't lose the styling
2. the skipping now allows for the `<article>` element itself being hidden
This has been proposed as the new default, and is currently in-use on many large ember apps without issue. It is already the default under Embroider. Testing locally, this seems to make incremental builds in development at least 2x faster.
https://github.com/ember-cli/ember-cli/issues/8681
- Convert `admin-incoming-email` modal to component-based API
- Testing that the modal was working in local development was extremely challenging due to the need for `rejected` and `bounced` emails. Something that is not easy to stub in a local dev environment. To make this process more smooth for future developers I have added a new rake task:
```
desc "Creates sample email logs"
task "email_logs:populate" => ["db:load_config"] do |_, args|
DiscourseDev::EmailLog.populate!
end
```
That will generate fully functional email logs in development to be toyed with.
<img width="787" alt="Screenshot 2023-07-20 at 3 27 04 PM" src="https://github.com/discourse/discourse/assets/50783505/47b3fe34-cd7e-49a5-8fe6-768c0fbd1aa2">
The gjs/gts formats are a new pattern for authoring Ember components. This commit introduces support for these patterns to our build pipeline for core/plugins, and converts a handful of components to use the new format. It also introduces relevant updates to our linting config, and to our sample vscode configuration.
Co-authored-by: Godfrey Chan <godfreykfc@gmail.com>
Co-authored-by: Krystan HuffMenne <kmenne+github@gmail.com>
Since 0fa92529ed, helpers can now be implemented as plain JS functions. This makes them much easier to write/read, and also makes them usable in `<template>` gjs files.
* FEATURE: allow sidebar section api to create external links
Right now, sidebar API allows creating sections with internal links. It should be extended to allow creating links to external URLs as well.
* FIX: after rebase
pass the extra public trees to `app.toTree()` to match:
0e00f2bf15/packages/test-setup/src/index.ts (L24-L27)
The ember-cli-terser addon now takes care of minifying all additional trees, so we can remove our custom terser-related logic
This brings them more in line with an idiomatic ember app looks
like, in particular, embroider really expects the CSS file to be
there.
As far as I can tell this is fairly harmless, since in production
the actual HTML is generated and served by Rails anyway.
Down the road, this may also be a good alternative to hacking the
build pipeline to bring in styles for tests.
Recently we started giving admins a notice in the advice panel when their translations have become outdated due to changes in core. However, we didn't include any additional information.
This PR adds more information about the outdated translation inside the site text edit page, together with an option to dismiss the warning.
* UX: Disclose AI model used and add animation to placeholder
* Move text into hbs template
DTooltip (weirdly) attaches to a sibling element, so we need something else to be rendered inside the RenderGlimmer wrapper div
---------
Co-authored-by: David Taylor <david@taylorhq.com>
e.g. the modernised share-topic modal will attempt to open the `create-invite` modal. Prior to this commit, this mixing of modern/legacy would fail silently, and the create-invite modal was never shown.
Initializing an EmberObject with a null object leads to an exception. This commit stops that from happening, and introduces an acceptance test for adding/removing banner topics via message-bus.
Co-authored-by: David Taylor <david@taylorhq.com>
011ba5b9 slightly changed the way the staff-action-log route is activated. It's now possible for `deserializeQueryParam` to be called with a null value, so we need to deal with that case.
This route is currently untested - we'll follow-up with another commit to add some.
This PR migrates the publish page modal to a Glimmer component and DModal.
Most of the code is lift-and-shift. However, the component state getters were implemented using meta-programming in the original controller. They have all been inlined here for clarity, searchability, etc.
Define new concept of panels in sidebar. Panels are wrappers around sidebar sections. In the future, it allows creating full focus mode by switching between panels.
A new API method called addSidebarPanel was added. Default main panel is already registered and by default all API sections are mounted to main.
This babel plugin is intended to supress the deprecation warnings
from building plugins, however, discourse-plugins does not actually
consume this plugin at all. Currently this happens to work due to
how the babel worker processes are shared and the timing/ordering
of the build, but it will stop working with the embroider build.
This commit extracts the plugin the a shared package so that it
can be properly consumed by discourse-plugins as well as core.
Performing a `Delete User`/`Delete and Block User` reviewable actions for a
queued post reviewable from the `review.show` route results in an error
popup even if the action completes successfully.
This happens because unlike other reviewable types, a user delete action
on a queued post reviewable results in the deletion of the reviewable
itself. A subsequent attempt to reload the reviewable record results in
404. The deletion happens as part of the call to `UserDestroyer` which
includes a step for destroying reviewables created by the user being
destroyed. At the root of this is the creator of the queued post
being set as the creator of the reviewable as instead of the system
user.
This change assigns the creator of the reviewable to the system user and
uses the more approapriate `target_created_by` column for the creator of the
post being queued.
- explicitly enables the jquery-integration. This was previously enabled by default, so no change in behavior for us
- enable template-only-glimmer-components. In core, we don't have any component templates under `templates/components`, so this flag has no effect. A shim, with associated tests, is introduced to preserve the old template-only 'classic component' behavior for themes and plugins.
We'd like to get this deprecation unsilenced before the 3.1 release so that theme/plugin developers see the messages and can make the necessary changes during the 3.2 release cycle. To avoid the remaining legacy core modals from creating overwhelming noise in the logs, deprecation messages for them are skipped.
When the app boots, Ember fires a `routeWillChange` event. This was causing us to set the `_trackView` flag in our ajax library, which would cause the next request to have the `Discourse-Track-View` header, despite not being relevant to the page view. Depending on the plugins/themes installed, this could lead to 'double counting' of pageviews. (because the initial HTML request is also counted as a page view)
This commit updates the the logic to ignore the first transition (by checking `transition.from`), and also introduces an acceptance test for the behaviour.
Co-authored-by: Régis Hanol <regis@hanol.fr>
Currently the dominant color attribute is only set for post images (not chat).
As a result, clicking lightbox images in chat will load the image within lightbox but also shows a JS error.
This change ensures that the dominant color is set before attempting to update the site theme color.
What does this change do?
This commit removes the experimental label for a bunch of APIs that have
been used in production for quite some time at Discourse so that the
APIs can be released as part of Discourse 3.1
To decide to use flip behavior select-kit will check if it's located inside a modal as a modal will scroll if overflown, however, when locating the select-kit element in the footer or header this is not the case. This commit will deactivate `flip` modifier only when used inside modal body.
Fixes an issue where this.selector value was not binded at the time of adding the event listener. Therefore when someone opens a chat channel that has images, the value of selector would change. I also moved the callback to a named function (rather than the default handleEvent).
The Problem
Clicking on a large image opens lightbox, however the new lightbox currently waits for the first image to finish loading before it finishes loading the lightbox UI correctly (ie. background color). This makes the visual experience feel broken.
Because open() is waiting for the image to load, it doesn't trigger the onOpen callback, which appends a .has-lightbox class to the html tag. The lightbox background color requires that css class to be set for the styles to be applied correctly.
The Solution
This PR prevents blocking when loading loading the first image (image that was clicked) within the lightbox, and therefore allows the css class to be appended to the html tag correctly and as a result fixing the styling issues.
The #setCurrentItem function is async and awaits the loading of preloadItemImages already, so the image will load correctly when complete despite the rest of the UI loading in advance.
The primary motivation is to simplify `eagerLoadRawTemplateModules` which curently introspects the module dependencies (the `imports` at runtime). This is no longer supported in Embroider as the AMD shims do not have any dependencies (since it's managed internally with webpack).
Prior to this commit the `setSiteThemeColor` could mistakenly receive a color with a leading `#` which would cause an invalid color to be send to `postRNWebviewMessage` and would eventually cause a crash if we try to interpolate between this color and another.
Using the lastViewedTopicId indiscriminately can cause strange scrolling behavior when navigating to a **different** topic list after viewing a topic. We only want to refocus the topic when going 'back' to the same topic list which originally triggered the navigation.
Previously we had three query parameters to control which tests would be run. The default was to run all core/plugin tests together, which would almost always lead to errors and does not match the way we run tests in CI.
This commit removes the three old parameters (skip_core, skip_plugins and single_plugin), and introduces a new 'target' parameter. This can have a value of 'core', 'plugins', 'all', or a specific plugin name. The default is 'core'. Attempting to use the old parameters will raise an error.
Previously we were implementing scroll reset/memorization on a per-page basis. Many of these approaches relied on the `didInsertElement` hook, which is no longer appropriate since Discourse changed to use the 'loading slider' strategy for page transitions.
This commit rips out all of our custom scroll resetting/memorizing, and implements those things in a generic service. There are two features:
1. After every route transition, scroll to the top of the page
2. When using browser back/forward buttons, restore the last known scroll position for those routes
To opt-out of the behaviour, individual routes can add a scrollOnTransition boolean to their RouteInfo metadata using Ember's `buildRouteInfoMetadata` hook.
The new lightbox was missing the tracked property for items when it was launched earlier as experimental feature flag.
This PR should fix issues experienced when the user clicks between multiple galleries causing the carousel images not to be updated as they were previously not tracked.
Why this change?
Prior to this change, dismissing unreads posts did not publish the
changes across clients for the same user. As a result, users can end up
seeing an unread count being present but saw no topics being loaded when
visiting the `/unread` route.
Why this change?
Group mention notifications are currently placed in the "Others" tab
of the user menu which is odd considering that mentioned notifications
are in the reply tab. This commit changes it such that group mention
notifications are displayed in the reply tab as well.
* FEATURE: Inline topic summary. Cached version accessible to everyone.
Anons and non-members of the `custom_summarization_allowed_groups_map` groups can see cached summaries for any accessible topic. After the first 12 hours and if the posts to summarize have changed, allowed users clicking on the button will automatically re-generate it.
* Ensure chat summaries work and prevent model hallucinations when there are no messages.
In the past, widget implementors would have to subclass the MountWidget component and wire up `didUpdateAttrs` or an observer to trigger a re-render. If that wasn't done, then it could lead to weird behaviors, especially now that page transitions in Discourse do not de-render/re-render components by default.
This commit updates MountWidget so that it re-renders whenever any input arguments change.
Browser capabilities are inherently unconnected to the lifecycle of our app. Making them formally available outside of the service means that they can safely be used in non-app-linked functions without needing risky hacks like `helperContext()` or `discourse-common/lib/get-owner`.
One example of where the old hacks were problematic is the `translateModKey()` utility function. This is called in the root of the `discourse/components/modal/keyboard-shortcuts-help` es6 module. If anything (e.g. a theme/plugin) caused that es6 module to be `require()`d before the application was booted, a fatal error would occur.
Following this commit, `translateModKey()` can safely import and access `capabilities` without needing to worry about the app lifecycle.
The only potential downside to this approach is that the capabilities data now persists across tests. If any tests need to 'stub' capabilities, they will need to revert their changes at the end of the test (e.g. by using Sinon to stub a property).
This commit also updates some legacy references from `capabilities:main` to `service:capabilities`.
These avatar-related helper functions are used in pretty-text, which currently means we load the entire `discourse/lib/utilities` module into the mini-racer when running pretty-text on the server side. This stops us adding any logic or imports to discourse/lib/utilities which may depend on other `discourse/` namespace features.
This commit moves the avatar-related utils into a dedicated module in the `discourse-common` namespace, adds backwards-compatibility shims, and updates the pretty-text config accordingly.