## 🔍 Overview
Previously we added the ability to translate existing posts in different
languages: https://github.com/discourse/discourse/pull/32564. In this
update we add the ability to set a post language upon initially creating
a post.
Internally, we also clean-up/improve a few things, like:
- adding a `PostLanguageSelector` component
- Adding a `available_content_localization_locales` onto `SiteSetting`
so it's available in the service (without needing to parse the JSON to
access it)
- fix issues with the translation-editor not working due to some
regressions from here: https://github.com/discourse/discourse/pull/32869
- ensure everything works for replies/drafts/edits
## 📷 Screenshots

We will not update localization on every edit for now. To compensate,
the existing indicator will also add information if a translation might
be outdated.
Related: https://github.com/discourse/discourse-ai/pull/1422
/t/156185
We had a regression where you can no longer update an existing webhook to have a blank secret field.
The problem is the blank field will return a value of undefined, which is ignored by the store when sending the request to the back-end.
This fixes that by using the nullish coalescing operator to replace undefined with an empty string.
This commit takes the dragging behaviour of the grippie
element (the blue bar) at the top of the composer and makes
it into an ember Modifier for use in more places.
The first usage is to add a grippie resizer to the bottom of AceEditor
to followup f819b1ec4dc96e78de075e15df37d114851f785c, since
the `@resizable` option allows the user to vertically resize
the code editor.
Custom composer-related behaviour is now done via callbacks from
the modifier. The .grippie CSS class has been hoisted so the style
applies everywhere, then AceEditor modifies the appearance to blend
a bit better.
---------
Co-authored-by: chapoi <101828855+chapoi@users.noreply.github.com>
Added `topic` tracking to posts and improved quoted post handling by
linking quoted posts to their parent topic.
Introduced error handling for decorators to prevent crashes and ensure
smoother operation in case of unexpected issues.
- Fix displaying the time gap
- Do not display the counter on links with zero posts
- Adjust button padding and icon margin in the post metadata button
indicators (edit)
Changes the gear icon for the more menu to a circle-plus icon.
Changes the emoji icon to its outline version, to make it less similar
to the circle-plus icon.
Changes the styles (eg. icon sizes) of the toolbar, using a flexbox
instead of a grid, with some tweaks and animations to the toggle switch,
which occupies a smaller width now.
Removes the gray button-bar bottom border.
Moves the Insert Date/Time item to the more menu, and changes its icon
to a clock.
### Before, hovering more menu
<img width="758" alt="image"
src="https://github.com/user-attachments/assets/84d8f5aa-519e-40a2-ba44-d58d7294f6b0"
/>
### After, hovering more menu

---------
Co-authored-by: chapoi <101828855+chapoi@users.noreply.github.com>
This change validates mentions for `users` and `groups` when using the
rich text editor.
When the mention is valid (ie. the user or group exists) it will
visually show as a mention node, but when the user or group does not
exist then it will appear as regular text in the editor.
There are 2 parts to this:
### Existing drafts / toggling from Markdown to Rich Text
We automatically add mention nodes for all `@mentions` and then process
any invalid mentions by removing the mention node and replacing it with
text.
### When manually typing in Rich Text
We find the mention within the text and then if valid we replace it with
a mention node.
### Validation
The validation happens in a single request when loading a draft or
switching from Markdown to Rich Text. The response provides a list of
valid usernames and groups. It also provides additional context for
groups and users that are not reachable (ie. unmentionable groups or
suspended users etc) but we don't use this currently.
We then store the valid and invalid mentions to prevent unnecessary
requests later.
As new mentions are typed then they will also be validated using the
same request as above (if they are not already stored in our valid /
invalid sets).
Introduced a map to manage scheduled/debounced timers, ensuring they are
canceled when the component is destroyed. This improves memory
management and prevents potential issues with lingering timers after
destruction. Updated relevant methods to utilize this new tracking
mechanism.
Non-colocated `.hbs` files in themes and plugins should be treated as
classic components, not glimmer components.
This regressed in cb6cc8dcd339b5036fecfd8ae0301accc7df4ee1
Also adds Ember's `component-template-resolving` deprecation to our list
of deprecations which trigger admin warnings.
The moment locale files expect `this.` to be the window object. In a
type=module, `this` is `undefined`. This commit wraps the
moment-timezone definitions in an IIFE to resolve that.
Also adds a system spec to prevent future moment-timezone regressions.
Followup to a2b0c193dff40278c0a93995cc9b97b05dc8abb2
We will be moving towards `type="module"` for all of Discourse's JS
bundles in the near future. This commit makes a start by applying the
change to translation bundles.
This was previously merged, but the lack of `apply_cdn_headers` on the
locales controller led to CORS errors on sites with CDNs.
We will be moving towards `type="module"` for all of Discourse's JS
bundles in the near future. This commit makes a start by applying the
change to translation bundles.
Previously we would check the request for a matching CDN hostname before
applying the `Access-Control-Allow-Origin` header. That logic requires
the CDN to include its public-facing hostname in the `Host` header,
which is not always the case.
Since we are only running this `apply_cdn_headers` before_action on
publicly-accessible asset routes, we can simplify things so that the
`Access-Control-Allow-Origin: *` header is always included. That will
make CDN config requirements much more relaxed.
At the moment, this is primarily relevant to the HighlightJsController
routes, which are loaded using native JS `type=module`. But in the near
future, we plan to expand our use of `type=module` to more critical JS
assets like translations and themes.
Also drops the `Access-Control-Allow-Methods` header from these
responses. That isn't needed for `GET` and `HEAD` requests.
This brings the search_icon header search mode to parity with the
search_field mode. We don't want to show either of these if the welcome
banner is showing, since it has a search field, this is redundant.
If you scroll the page and the welcome banner is hidden, then we
show the header search icon.
This commit also cleans up some code related to the page-search
shortcut, which we no longer use, including limiting showing search
on topic only if there are > 20 posts.
Without this wrapper, `data` is defined in the global scope and clashes
when there are multiple themes with translations.
Followup to 033cccdf17a56b43f9f243bb549abe0a41a0de63
We can remove the wrapper once we land
https://github.com/discourse/discourse/pull/33107
Theme translations are very simple JS, and do not need to be run through
the theme transpiler. This brings their format in-line with core/plugin
translations.
Extracted from https://github.com/discourse/discourse/pull/33103
Most composer tips use the "educational" template name but similar
topics uses it's own template. We only allow showing if a tip using the
template name wasn't shown already. So therefore a welcome message (ie.
"educational") could show at the same time as a "similar topics" tip,
which isn't ideal from a UX perspective.
This change prevents overlapping composer tips by only opening the popup
if there are no popups open already. Therefore requiring the user to
close a tip before another different tip type could open.
This commit fixes displaying the post highlighted when navigating using
the keyboard.
Ember was overriding the direct DOM manipulations, causing the browser
outline to be displayed.
When we ported over the about page extra groups theme component, we used a hidden site setting to control this as per MO.
We don't need this any more. We can simply rely on the presence of any configured groups to decide.
This is fairly minor because usually SVGs aren't focusable, but this
adds `aria-hidden='true'` to all SVGs by default unless either an
`aria-label` or `label` is provided. This gets reported to us in
automated tests from time to time.
So now:
1. SVG: `aria-hidden="true"` (new behavior, safe default when no label
is provided)
2. SVG with `label` param: `aria-hidden="true"` and `sr-only` label is
provided
3. SVG with `aria-label` param: `aria-hidden="false"` and `aria-label`
is provided
When typing `:emoji:` or `:)` to create emoji nodes through ProseMirror
inputrules, this PR changes the handler to enforce the use of the
existing marks in the current caret position (if it's a link, bold, etc)
so the newly created emoji is marked with the same marks(s).
This commit removes the color palette dropdown from the theme page and replaces it with a new "Colors" tab where the theme's color palette can be edited directly in that tab on the theme page. With this change, a theme's color palette is strongly tied to its theme and can't be linked to other themes and it can't be selected by users without using the theme as well.
All of the changes are behind a feature flag. To enable it, turn on the `use_overhauled_theme_color_palette` setting.
Co-authored-by: Ella <ella.estigoy@gmail.com>