Commit Graph

3989 Commits

Author SHA1 Message Date
5883085af3 DEV: Replace all @breakpoint with @viewport.* (#32649) 2025-05-12 12:52:45 +01:00
1fd843ced6 DEV: Deprecate boundDate and formatAge helpers (#32672) 2025-05-10 20:08:08 +02:00
52b79012e9 DEV: revert long press changes (#32668)
These changes have been made for playwright as it was hard to test a
long press even on playwright given `click` won't trigger `touchstart`
even with `isMobile:true` and `hasTouch:true`. You have to use `tap`,
but you don't have the `delay` option on tap, so you can't make it a
long tap.

Sadly this code is apparently not working correctly on Android 15. This
commit will revert the modifier to what it was before and is relying on
native JS to trigger the fake long press in specs, which seems to work
nicely.

This commit also attempts to centralize the actions on messages in page
objects to avoid code duplication.
2025-05-09 18:58:42 +02:00
58009fb0e7 DEV: Fix small issues in the Glimmer Post Stream (#32656)
- When using the Glimmer Post Stream, ensure the status wrapper is only
rendered for mentions of users with a status set.
This prevents an empty wrapper from adding a small blank space at the
end of the mention.

- Ensures the post's user field in initialized with the
`avatar_template` in the PostStream to prevent missing avatar on small
actions

- Fix an issue where the path would be incorrectly linked on small
actions

- Fix an issue where the relative timestamp would be incorrectly
displayed in wiki posts
2025-05-09 12:17:28 -03:00
0947a14284 DEV: correctly returns contract error (#32645)
If a user was using invalid values for the contract we would return
"Unexpected error", which is incorrect given we know the exact error.
The user will now get the following exception: "Page size must be less
than or equal to 50"
2025-05-08 14:30:02 +02:00
61de461412 DEV: Refactor lazy-video initialization for Glimmer compatibility (#32599)
Modernizes the renderGlimmer API to use Glimmer components, replacing
deprecated ember-cli-htmlbars templates. Adds deprecation warnings for
invalid parameters and improves compatibility with the new Glimmer Post
Stream API.
2025-05-07 10:47:02 -03:00
a80017ff6a DEV: add fallback for calling helper.widget decorating cooked content when using the Glimmer Post Stream (#32585)
This commit adds a basic fallback to prevent errors for extensions accessing
`helper.widget` when using `api.decorateCookedElement`.

The purpose of the fallback is provide access to `.widget.attrs`and
`scheduleRerender()` which are common scenarios.

Since the call to the callback happens only when rendering the auto mode
of the Glimmer Post Stream can't detect the existence of these
customizations. The PR also adds a deprecation notice in the console.
2025-05-06 14:13:45 -03:00
c411f4930d Update translations (#32595) 2025-05-06 11:29:38 -04:00
b6aad28ccf DEV: replace selenium driver with playwright (#31977)
This commit is replacing the system specs driver (selenium) by
Playwright: https://playwright.dev/

We are still using Capybara to write the specs but they will now be run
by Playwright. To achieve this we are using the non official ruby
driver: https://github.com/YusukeIwaki/capybara-playwright-driver

### Notable changes

- `CHROME_DEV_TOOLS` has been removed, it's not working well with
playwright use `pause_test` and inspect browser for now.

- `fill_in` is not generating key events in playwright, use `send_keys`
if you need this.

### New spec options

#### trace

Allows to capture a trace in a zip file which you can load at
https://trace.playwright.dev or locally through `npx playwright
show-trace /path/to/trace.zip`

_Example usage:_

```ruby
it "shows bar", trace: true do
  visit("/")

  find(".foo").click

  expect(page).to have_css(".bar")
end
```

#### video

Allows to capture a video of your spec.

_Example usage:_

```ruby
it "shows bar", video: true do
  visit("/")

  find(".foo").click

  expect(page).to have_css(".bar")
end
```

### New env variable

#### PLAYWRIGHT_SLOW_MO_MS

Allow to force playwright to wait DURATION (in ms) at each action.

_Example usage:_

```
PLAYWRIGHT_SLOW_MO_MS=1000 rspec foo_spec.rb
```

#### PLAYWRIGHT_HEADLESS

Allow to be in headless mode or not. Default will be headless.

_Example usage:_

```
PLAYWRIGHT_HEADLESS=0 rspec foo_spec.rb # will show the browser
```

### New helpers

#### with_logs

Allows to access the browser logs and check if something specific has
been logged.

_Example usage:_

```ruby
with_logs do |logger|
  # do something

  expect(logger.logs.map { |log| log[:message] }).to include("foo")
end
```

#### add_cookie

Allows to add a cookie on the browser session.

_Example usage:_

```ruby
add_cookie(name: "destination_url", value: "/new")
```

#### get_style

Get the property style value of an element.

_Example usage:_

```ruby
expect(get_style(find(".foo"), "height")).to eq("200px")
```

#### get_rgb_color

Get the rgb color of an element.

_Example usage:_

```ruby
expect(get_rgb_color(find("html"), "backgroundColor")).to eq("rgb(170, 51, 159)")
```
2025-05-06 10:44:14 +02:00
61b621630c UX: rich editor footnotes position (#32566) 2025-05-05 09:12:09 -03:00
edbd5e08f9 DEV: Refactor StartReply & StopReply services a bit
- Move some data transforming into contracts.
- Add some missing specs.
- Use the `try` step.
- Improve the `model` step a bit by allowing to catch any exception,
  and not only `ArgumentError`. We already had the mechanism to inspect
  which exception was caught.
2025-04-30 11:50:22 +02:00
Sam
067813e182 DEV: add extra safety around original post only implementation (#32521)
Instead of looking at post count that is cached, only ever look at the
post_number
which is guaranteed to be correct
2025-04-30 08:45:28 +10:00
21a7f31622 SECURITY: Enforce DM limits properly
When adding people to a DM, the ones already in the channel weren’t
taken into account when checking whether the maximum limit was reached.
2025-04-29 12:06:33 +08:00
303b4bfbae Update translations (#32216) 2025-04-28 13:41:04 +02:00
aafbde2080 DEV: Convert final hbs to gjs and enable require-strict-mode lint (#32473) 2025-04-26 10:48:43 +01:00
acc11cc9aa DEV: Remove final {{action uses and enable lint rule (#32348) 2025-04-25 21:25:06 +01:00
e41897a306 DEV: [gjs-codemod] Convert final core components/routes to gjs 2025-04-25 11:06:24 +01:00
e401d795c6 DEV: [gjs-codemod] merge js and hbs 2025-04-25 11:05:20 +01:00
2a47848453 DEV: [gjs-codemod] renamed hbs to gjs 2025-04-25 11:05:18 +01:00
a9ddbde3f6 DEV: [gjs-codemod] renamed js to gjs 2025-04-25 11:05:17 +01:00
fe12500767 UX: Do not let composer affect chat window height (#32423) 2025-04-24 09:32:28 -05:00
ed2740d0ca FIX: correctly reset panel when resizing window (#32437)
The problem is mainly that we also have a css animation made from js
which was setting a different width for the panel, so the `style.width =
"auto"` was not overriding this part. This animation happens in a parent
component after `didResizeContainer` is called, so it could be fine most
of the times, but the simpler change is to ensure, panel resize, or
window resize ends up in the same codepath so whatever the developer
decides to do in `didResizeContainer` hook will be applied in both
cases.

No test as it's fairly hard to test and would require a complex system
spec setup.

It avoids this situation where the side panel is larger than viewport
after window resize:
![Screenshot 2025-04-24 at 11 58
09](https://github.com/user-attachments/assets/8b58793a-32dc-4bc8-9989-7498e458c059)
2025-04-24 20:31:55 +10:00
4c443283cf UX: Border radius removal (#32424) 2025-04-23 16:38:59 -05:00
b888ec07cb UX: Chat more message actions adjustments (#32404) 2025-04-22 16:36:21 -05:00
1e0d773b54 DEV: duplicate scroll-top util function to lib and replace current usage with new path (#32367)
This was refactored from an actual Mixin some time back. This PR moves
the function to the lib folder and keeps the same logic/interface
otherwise.

We'll remove the mixin file once all non-core repos change to use the
new file.
2025-04-21 08:12:51 +08:00
6c4e9dfbc8 DEV: Try fix composer rich text transcript spec (#32364)
This is to try fix this error by sending the keys
on the element itself:

```
Failure/Error: page.send_keys([PLATFORM_KEY_MODIFIER, "v"])

Selenium::WebDriver::Error::StaleElementReferenceError:
  stale element reference: stale element not found in the current frame
    (Session info: chrome=135.0.7049.84); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#stale-element-reference-exception
```
2025-04-18 15:52:35 +10:00
f06175b72d UX: prosemirror rich editor nodes cleanup / slightly better UX (#32361)
We don't want "ghost" `content` within mention/hashtag, as they're
already rendering their non-editable content on `toDOM`.

`atom: true` is not necessary for content-less nodes

Re-use existing heading node spec instead of re-creating.

A UX improvement from these changes is a better Cmd-Left/Home navigation
when these nodes begin a paragraph and the caret is after them.
2025-04-18 00:20:55 -03:00
530f2f13af FIX: Make the 'Keep Message Deleted' reviewable option work (#32345)
When a flagged chat message has already been deleted, we offer an option
in the review queue to agree with the flag and keep the message deleted.
However, this option is currently broken due to a missing implementation
for the option.

Internal topic: t/152203.
2025-04-17 07:35:08 +03:00
59ec86933a DEV: DMultiSelect (#32240)
The `DMultiSelect` component provides a customizable multi-select
dropdown with support for both mouse and keyboard interactions.

![Screenshot 2025-04-10 at 15 40
26](https://github.com/user-attachments/assets/277619db-6e56-4beb-8eda-f76360cd2ad8)

### Parameters

#### `@loadFn` (required)
An async function that returns the data to populate the dropdown
options.

```javascript
const loadFn = async () => {
  return [
    { id: 1, name: "Option 1" },
    { id: 2, name: "Option 2" },
  ];
};
```

#### `@compareFn`

A function used to determine equality between items. This is
particularly useful when working with complex objects. By default, `id`
will be used.

```javascript
const compareFn = (a, b) => {
  return a.name === b.name;
};
```

#### `@selection`
An array of pre-selected items that will be displayed as selected when
the component renders.

```javascript
const selection = [
  { id: 1, name: "Option 1" },
  { id: 2, name: "Option 2" },
];
```

#### `@label`
Text label displayed in the trigger element when no items are selected.

```javascript
@label="Select options"
```

### Named Blocks

#### :selection
Block for customizing how selected items appear in the trigger.

```javascript
<:selection as |result|>{{result.name}}</:selection>
```

#### :result
Block for customizing how items appear in the dropdown list.

```javascript
<:result as |result|>{{result.name}}</:result>
```

#### :result
Block for customizing how errors appear in the component.

```javascript
<:error as |error|>{{error}}</:error>
```

### Example Usage

```javascript
<DMultiSelect
  @loadFn={{this.loadOptions}}
  @selection={{this.selectedItems}}
  @compareFn={{this.compareItems}}
  @label="Select options">
  <:selection as |result|>{{result.name}}</:selection>
  <:result as |result|>{{result.name}}</:result>
  <:error as |error|>{{error}}</:error>
</DMultiSelect>
```

Co-Authored-By: Jordan Vidrine
<30537603+jordanvidrine@users.noreply.github.com>

---------

Co-authored-by: Jordan Vidrine <30537603+jordanvidrine@users.noreply.github.com>
2025-04-15 14:56:57 +02:00
c78a79bbf5 UX: keep content on rich editor footnote inputrule (#32296)
Instead of using the matched string, this PR uses the actual sliced
content from the ProseMirror document range as the content when creating
the footnote node.
2025-04-14 19:36:18 -03:00
29ca0ae0b1 FEATURE: add footnote (plugin) rich editor extension (#31719)
Continues the work done on
https://github.com/discourse/discourse/pull/30815.

Adds a `footnote` node, parser, `^[inline]` input rule, toolbar button
item, and serializer.

Also adds a NodeView with an internal ProseMirror editor to edit the
footnote content.
2025-04-14 14:25:36 -03:00
381f6e64e8 FIX: click handler position on rich editor details node (#32268)
`pos` is the exact position of the click in the entire document

`nodePos` is the position of the clicked node itself

The idea is that we want the click to be the first position **within the
node**.

The previous code was checking for the first 2 positions of the entire
document.

I'd love to add a test for this, but it's very tricky.
2025-04-14 14:06:54 -03:00
f03a6f3557 UX: Onebox & quote border radius (#32242) 2025-04-14 10:55:51 -05:00
7b2b08cf89 DEV: [gjs-codemod] Convert automation/styleguide/other to gjs
Co-authored-by: Jarek Radosz <jarek@cvx.dev>
2025-04-14 15:36:16 +01:00
3462113bd4 DEV: [gjs-codemod] merge js and hbs 2025-04-14 15:27:52 +01:00
1eb953ca57 DEV: [gjs-codemod] renamed hbs to gjs 2025-04-14 15:27:47 +01:00
3ca507e008 DEV: [gjs-codemod] renamed js to gjs 2025-04-14 15:27:45 +01:00
b3f0c85d82 UX: avoid leading space when serializing some nodes from rich editor (#32270)
On some cases during serialization (like with headings), the previous
node is still "open" when it's the "turn" of the node we're serializing.

In this case, checking the boundaries before writing was getting the
wrong state, because the `write` call uses `flushClose()`, which makes
sure we have the newlines from closing the previous node.

This would create scenarios like (notice the space before each node
below the heading)

```markdown
# Heading

 🎉

# Heading

 @mention

# Heading

  #hashtag
```

This PR makes sure we call flushClose() before checking boundaries, and
adds tests for that.
2025-04-14 10:57:34 -03:00
f0057c7353 DEV: Drop legacy topic-list and raw-handlebars compilation system (#32081) 2025-04-14 10:42:40 +01:00
fdb805d131 UX: only toggle rich editor details on caret click (#32267) 2025-04-12 09:01:20 -03:00
6e654bc596 FIX: relax automation restrictions (#32238)
Relaxed restrictions:
- Automation posts are not validated for similarity. This was causing
error when PMs were created by regular user with same content and sent
to different users.
- Don't create warning logs when PM target does not exist anymore. When
for example spammer was deleted, delayed PM is not sent, but it is
correct behaviour;
- Allow tags to be applied even if an automation user is not allowed to
tag;
- Restricted category tags should be visible in configuration UI. Still,
they will be applied only when specific topic belongs to correct
category.
2025-04-11 07:27:43 +08:00
01ce003b8e FIX: logs time even when automation raises (#32254)
The previous code could attempt to log a `nil` `run_time` if the block
would raise an exception. This commit adds two safeguards:

- rescue any exception to still compute `run_time`
- defaults to `0` if we still don't have any `run_time`
2025-04-10 11:05:53 +02:00
fff1ae60f1 DEV: ensures chat can work without discourse-presence
discourse presence can be disabled, given it's a plugin the `composerPresenceManager` service couldn't be present anymore and would cause an error.

No test as it's testing imbrication of multiple plugins and hard to test reliably.
2025-04-09 17:00:31 -04:00
4c8420833e FEATURE: One-click chat reaction settings (#32150)
Adds a one-click chat reactions setting to the chat preferences page
where members can determine what one-click reactions are shown in chat.

- Frequent: This will be the default setting. (Automatically set based
on most used chat reactions)
- Custom: Members can choose up to three reactions they want to see in
their one-click chat/DM reactions menu. Defaults are `❤️`, `👍` ,
and `😄`.


![image](https://github.com/user-attachments/assets/8913db0e-d6ec-4347-ad91-2329206b127c)

This pull request is essentially the work of @dsims in
https://github.com/discourse/discourse/pull/31761

---------

Co-authored-by: dsims <1041068+dsims@users.noreply.github.com>
2025-04-04 09:15:13 +02:00
3d6b7e2574 FEATURE: Copy thread messages when copying thread OP (#32139)
This introduces functionality to chat transcripts. If
you select _only_ a thread's OP and press the Copy button,
we will now copy the OP plus all of the thread's replies
into the transcript.

This is being done to make it easier to copy all the context
of a thread easily. The old way of selecting only some messages
inside a thread still works too.

This commit also unskips and refactors some transcript specs.
2025-04-04 13:45:37 +10:00
564edc52eb UX: add flex to mentions mixin + update units (#32145)
Fixing hashtag text glued to the icon, and updated some related properties to using better units.

---------

Co-authored-by: Martin Brennan <martin@discourse.org>
2025-04-04 12:20:35 +10:00
abeb8de7b5 UX: Button fixes (#32152) 2025-04-03 16:13:34 -05:00
9be51b616b DEV: Handle the missing d-lazy-video case (#32148)
aka: lazy load lazy video

---------

Co-authored-by: David Taylor <david@taylorhq.com>
2025-04-03 18:09:02 +02:00
999ae73c78 DEV: [gjs-codemod] apply codemod
Co-authored-by: Jarek Radosz <jarek@cvx.dev>
2025-04-02 13:44:15 +01:00
dac398d6ab DEV: [gjs-codemod] merge js and hbs 2025-04-02 13:43:33 +01:00