6558 Commits

Author SHA1 Message Date
Penar Musaraj
6aaddcf381
FEATURE: enable full page login by default (#31771)
This switches the signup/login UI to the full page experience by
default. This has been in use by many sites for multiple months and we
have ironed out many fixes in the meantime.

The `full_page_login` setting is also marked for removal in about
1.5mths, by the end of April 2025.
2025-03-25 13:43:51 -04:00
Roman Rizzi
9bc394191c
DEV: TopicListItemSerializer tells if topic is among the top 100 hottest topics (#31935) 2025-03-24 11:55:14 -05:00
Natalie Tay
af03873d37
DEV: Allow loading topic associations on /categories (#31954)
`/categories` sometimes returns accompanying topics under certain site
settings. The `CategoryList` currently allows preloading for topic
custom fields via `preloaded_topic_custom_fields`, but not for topics
themselves.

This addition is required for
https://github.com/discourse/discourse-solved/pull/342.
2025-03-24 17:40:15 +08:00
Krzysztof Kotlarek
9db89c20f7
FEATURE: send email to deleted user (#31947)
When a user post is flag as spam and the moderator deletes the user, we
should send email to the affected user.
2025-03-24 14:45:25 +08:00
Gary Pendergast
b77d0f7589
FEATURE: Sync Reviewable Status (#31901)
When multiple admins are working in the review queue, it's quite easy for two people to try and handle the same reviewable at the same time. This change addresses the two major situations where this can occur.

The `ReviewableClaimedTopic` model has been extended to allow the system to mark a reviewable as claimed as soon as the first moderator starts handling the reviewable, even when the `reviewable_claiming` setting is disabled. This ensures that reviewable actions with client-site activity (for example, `agree_and_suspend`) will lock the reviewable before another moderator starts working on it.

When someone handles handles a reviewable, we now use `MessageBus` to inform other moderators that it's changed. If any of the other moderator have that reviewable open (either individually, or on the list screen), it will automatically refresh that data.
2025-03-24 14:27:18 +11:00
Ted Johansson
b4085c7b50
DEV: Support target in problem check problem constructor (#31922)
We didn't have support in the #problem constructor for multiple targets, forcing developers to manually construct a Problem instance. This involves a lot of details and is error prone.

This PR supports passing an optional target argument to the constructor. This will be passed on to the translation_data method to generate the correct message as well.
2025-03-24 10:10:41 +08:00
Osama Sayegh
f7f7642ae0
UX: Improve naming for anonymous mode settings (#31832)
This PR renames a couple of settings related to anonymous mode:

1. `allow_anonymous_posting` → `allow_anonymous_mode`. This setting is
used as a switch for the entire anonymous mode feature, so it makes
sense to give it a generic name that better reflects what the setting
does.
2. `allow_anonymous_likes` → `allow_likes_in_anonymous_mode`. The new
name is clearer and will match a new setting that we'll add to allow
anonymous users to post in chat.

Internal topic: t/148088.
2025-03-21 04:54:06 +03:00
Kevin Hwang
0cdbd40866
FIX: Increase uploads.origin column length to 2000 to accommodate longer S3 pre-signed URLs for user uploads. (#31803)
The current limit is too small for the way Discourse currently stores a
pre-signed S3 URL for each upload in the form of:

```
https://{bucketname}.s3.dualstack.{region}.amazonaws.com/original/1X/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXXXXXXXXXXXXXXXXX%2FYYYYMMDD%2F{region}%2Fs3%2Faws4_request&X-Amz-Date=YYYYMMDDTHHMMSSZ&X-Amz-Expires=xxxxxx&X-Amz-SignedHeaders=host&X-Amz-Security-Token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

The problem here is that this URL, without the S3 bucket name and AWS
region portion of the URL, is already nearly 1000 chars long.

If you have an even slightly longer bucket name or region, it will
easily go over 1000.

---

The more proper fix would be not to store these "template" S3 pre-signed
URLs in the `origin` column to begin with.

S3 pre-signed URLs aren't meant to be persisted (they're by nature
"one-time" use, scoped to a short window), and they have to be
re-generated for each user request anyway, because they have a maximum
validity of 7d (in practice Discourse generates them with a lifetime of
300s), so the value stored in the `origin` column is more of a
"template" that gets discarded and a real pre-signed URL generated
on-the-fly each time a user comes anyway. So the value in the `origin`
column isn't even doing anything.

The proper way would be to store the S3 bucket name, region, and object
key, which is compact, and the three pieces of info from which it is
sufficient to generate pre-signed URLs each time a user requests.
2025-03-20 09:05:35 +08:00
Bianca Nenciu
bdc30ca3a0
FIX: Force pagination only if more than 1000 subcategories (#31507)
Commit f1700ca58929bcbfad23565861d1d3084ae1b3f8 ensures that categories
are loaded lazily, in pages, if the number of visible categories is over
1000. This affected the list of subcategories on the category page too.

The logic has been changed to only paginate if the number of categories
that would have been returned is grater than 1000. For example, if there
is a parent category filter, pagination will only be enforced if the
number of subcategories is over 1000.
2025-03-20 00:12:14 +02:00
Loïc Guitaut
2ed31fea64 DEV: Upgrade the Redis gem to v5.4 2025-03-19 14:34:00 +01:00
Ted Johansson
c0630dbee4
DEV: Make group auto e-mail domain limit configurable (#31873)
We currently limit the number of characters in the bar-separated list of auto-membership e-mail domains. We want to make this configurable through site settings.

After this change, we limit the length of each individual domain, and enable the number of domains to be configured through a hidden site setting.

The original limit is there to prevent DoS, since a TEXT column can take up to 1Gb. With this new limit we're still at a maximum of around 10kb.
2025-03-19 14:33:50 +08:00
Krzysztof Kotlarek
622d681f96
FIX: twitter_summary_large_image is renamed to x (#31870)
In this PR x_summary_large_image was introduced but now updated in all
places.

Also `min_first_post_typing_time` deprecation should not be removed.
2025-03-19 11:55:11 +11:00
Gary Pendergast
6cd282eeb3
FEATURE: Display a toast popup after completing a review action. (#31786)
When performing an action in the review queue, this change makes two improvements:

- The buttons on the reviewable item are disabled, so you can't accidentally multi-click.
- A toast is displayed when the action is complete, as a success indication.
2025-03-18 11:26:59 +11:00
Martin Brennan
327375abee
FIX: Use theme screenshot names in theme fields (#31852)
Currently we allow for 2 theme screenshots to be specified,
with a lightweight spec to allow both a light and dark
version of the screenshot. However, we were not storing this
screenshot name anywhere, so we would not be able to use it
for light/dark switching.

This commit fixes that issue, and also does some general refactoring
around theme screenshots, and adds more tests.
2025-03-17 15:56:19 +10:00
Kevin Hwang
e080712c24
DEV: Support connecting to Redis with a username. (#31710)
Redis / Valkey over TLS requires authentication involving both a
username and a password.

On most instances, the default username is `default`, but this allows
Discourse to provide its own.
2025-03-13 10:39:50 +08:00
Martin Brennan
38920724a0
DEV: Refactor reports index into service (#31667)
This list of all reports is needed in the admin search
controller as well, so this commit refactors it into
a service, adds specs, and also updates the admin
search code to use this new service & avoid a second
AJAX call to the server.
2025-03-11 14:36:06 +10:00
Krzysztof Kotlarek
54771b5949
FIX: remove admin_sidebar_enabled_groups setting (#31693)
Old no sidebar admin panel is deprecated and admin sidebar is not
experimental anymore. Therefore, old setting should be deleted.
2025-03-11 11:41:38 +11:00
Joffrey JAFFEUX
9dd26a3954
DEV: discourse-emojis 1.0.32 (#31669)
This gems bring a whole improved fluentui emoji set. Each image has been
recomputed to optimise the size of the emoji and remove useless margins.

For this reason the version has been bumped.

Other changes:
- not loading rake task dependencies in production
- renamed yo_yo/yo-yo to yoyo
2025-03-06 10:35:04 +01:00
Jarek Radosz
bbc1c2726c
Revert "DEV: discourse-emojis 1.0.31 (#31655)" (#31662)
This reverts commit 7e65cdbc9aa86677a2f6f7a8d4f1b8e87da07ff1.

It broke the production build, as it's trying to load
`selenium-webdriver` (a dev dep) in the production env.
2025-03-06 00:40:01 +01:00
Joffrey JAFFEUX
7e65cdbc9a
DEV: discourse-emojis 1.0.31 (#31655)
This gems bring a whole improved fluentui emoji set. Each image has been
recomputed to optimize the size of the emoji and remove useless margins.

For this reason the version has been bumped.

Other notable change: the emoji yo-yo can now be called "yoyo".
2025-03-05 21:49:18 +01:00
Martin Brennan
223b40de1c
FEATURE: Store composer version and device info on post stat (#31600)
We are developing our new composer, and it would be useful
if we could know how posts are being created by members.

To this end, we are going to start storing the following
on post_stats, which are created at the same time as a post
is created:

* writing_device - Based on `BrowserDetection.device`, which in
  turn is based on user agent. Will store .e.g iphone, android,
  mac, windows etc.
* writing_user_agent - Stores the full user agent (truncated at
  400 chars) of the device/browser the member used to write the post.
* composer_version - Either `1` for our old composer, or
  `2` if the new rich composer is enabled in site settings and
  the user has toggled it on
2025-03-05 12:48:32 +10:00
Guhyoun Nam
2ab00c5b37
DEV: Add apply_modifier on group's mentionable scope (#31565)
This PR adds DiscoursePluginRegistry.apply_modifier on group's
mentionable scope.
2025-03-04 15:36:55 -06:00
Ted Johansson
06a0108a52
DEV: Store selected API key scope mode in the database table (#31601)
Currently, after creating an API key, there is no way in the UI to see what scope the key has. To do this we need to first store the selected scope mode when creating a new key.

In this PR we:

- Convert scope_mode from a transient attribute to a database backed enum.
- Ship the possible values through the javascript:update_constants rake task instead of hard coding in front-end.

In follow-up PRs we will:

- Backfill existing API keys based on their associated api_key_scopes records.
- Start showing the scope mode in the UI.
2025-03-04 16:41:43 +08:00
Gary Pendergast
9abeff460c
FEATURE: Display the Watched Words that caused a post to be flagged. (#31435)
When a post is flagged due to matching watched words, it can be difficult to know what you're looking for, particularly if you have a lot of watched words built up over a long period of time.

This change stores the list of matched words, and later displays them in the review queue, listing which Watched Words were responsible for the flag. Because watched words can change, this is recorded at the time the post is flagged. For posts that were flagged prior to this feature landing, it tries to guess the relevant words based on the current Watched Words set.
2025-03-04 17:22:12 +11:00
Joffrey JAFFEUX
f2bf669dc2
DEV: aliases should be considered as existing (#31589)
Before this commit doing: `Emoji.exists?(some_alias)` would return
false. The only important thing in emoji is to never remove an emoji
code which has been used by users but changing the name of an emoji and
keeping old name as an alias should not break the application in any
way, this commit should ensure this is true.
2025-03-03 20:17:49 +01:00
Joffrey JAFFEUX
d38acc5df1
DEV: discourse-emojis gem (#31408)
This commit moves most of emoji logic into the discourse-emojis gem:
https://github.com/discourse/discourse-emojis/

Most notably:
- images are now symlinked from the gem
- the gem provides path to the json files

Search aliases have also been made asynchronous and memoized. When you
will search for an emoji we will now load the aliases and store the list
for future use.

---------

Co-authored-by: David Taylor <david@taylorhq.com>
2025-03-03 13:09:08 +01:00
David Battersby
3efbd95ad8
FEATURE: add search field to header (#31447)
Adds a search field to the page header on desktop that is controlled by
a site setting (within Search).

The search field toggles back to the search icon (magnifying class) when
the header is minimized (ie. scrolling in topics) and restores to the
field again when header is no longer minimized.

On mobile the search experience is still the same.
2025-02-28 12:47:09 +04:00
Angus McLeod
fb98ced782
DEV: add scope param to user_confirmed_email event (#31394)
EmailToken.confirm is called in a number of contexts (hence the need for
the `scope`) and this is sometimes needed in `user_confirmed_email`
callbacks to distinguish those contexts.
2025-02-27 14:53:06 -05:00
Régis Hanol
26b0428837
FIX: exclude links from hidden posts in user summary (#31504)
Ref - https://meta.discourse.org/t/-/353878
2025-02-25 12:56:16 -05:00
Gary Pendergast
29a8c6ee49
DEV: Add a new type_source field to the Reviewable model. (#31325)
This change adds a new `type_source` field to the `Reviewable` model, indicating whether the Reviewable type was registered by `core`, a plugin, or an `unknown` source.

When a plugin that registered a Reviewable type is disabled, this allows us to tell the user which plugin they need to re-enable to handle any orphan reviewable items.
2025-02-20 09:09:47 +11:00
Bianca Nenciu
8be39c5bf0
FIX: Improve group name validation (#31315)
This commit improves a few aspects regarding group name validation:

- `min_username_length` and `max_username_length` are validated with the
  shortest and longest names of users and groups

- skip validation of the group name when the group is an automatic one
2025-02-19 19:33:46 +02:00
Keegan George
878514af6e
DEV: Add ability to set disabled option on report filters (#31351)
This update adds the ability to conditionally control the `disabled`
property of the input on report filters.
2025-02-14 12:13:33 -08:00
Ted Johansson
2cafd7e79b
DEV: Separate admins and moderators on about page (#31272)
This PR does some things to the about page:

- Hide the stat if there are 0 admins/moderators.
- Count admins and moderators separately, so a user who is both will add
to both counts.
- A user who is both will still show up as a moderator, even if `admins`
is hidden.
2025-02-12 09:57:53 +08:00
Ted Johansson
3d11e3ca10
DEV: Require at least one scope for API key granular mode (#31253)
Currently, if creating an API key in "granular" mode, and not selecting any scopes, a globally scoped API key is created. This can be surprising and is not ideal. Having a key with no scopes isn't useful in the first place, so this PR adds client- and server side validations to check that at least one scope is selected if using "granular" mode.
2025-02-10 13:22:08 +08:00
Martin Brennan
ec7c6b1f96
FIX: Incorrect topic per-minute invitation rate limit (#31252)
This fixes an issue where the topic invitation rate limiter
for invites for the 1 minute period was incorrectly using
1 day as the length of time the limit should be applied over.
The default for `max_topic_invitations_per_minute` is 5,
so this would be very easy to exceed, then the user gets
a very confusing warning message saying they have to wait
23 hours to send more invites.

This commit also makes other `RateLimiter` period parameters
more consistent by always using the form `N.PERIOD` instead
of things like `86_400` hardcoded seconds per day.
2025-02-10 13:12:16 +10:00
Ted Johansson
70eaa976a5
DEV: Refresh translation override status when updating (#31233)
Translation overrides can be marked as "invalid interpolation keys" or "outdated" if the original translation is changed. We run a job every hour to check for this. We also have an admin problem check for it.

The problem is we don't refresh this status when an admin updates the override. So even if the invalid keys are removed, the override will still show up under the "invalid" filter.

There's a similar situation with the "outdated" status. The admin is shown a prompt which they can dismiss, which in turn updates the status, but updating the translation should also count as "addressing" it.

This PR runs a refresh on the override status when updating.
2025-02-07 14:12:28 +08:00
Osama Sayegh
284e708e67
FEATURE: Dark/light mode selector (#31086)
This commit makes the
[color-scheme-toggle](https://github.com/discourse/discourse-color-scheme-toggle)
theme component a core feature with improvements and bug fixes. The
theme component will be updated to become a no-op if the core feature is
enabled.

Noteworthy changes:

* the color mode selector has a new "Auto" option that makes the site
render in the same color mode as the user's system preference
* the splash screen respects the color mode selected by the user
* dark/light variants of category logos and background images are now
picked correctly based on the selected color mode
* a new `interface_color_selector` site setting to disable the selector
or choose its location between the sidebar footer or header

Internal topic: t/139465.

---------

Co-authored-by: Ella <ella.estigoy@gmail.com>
2025-02-07 03:28:34 +03:00
Arpit Jalan
aa222ef7b8
FEATURE: add first post likes data serializer (#31216)
This PR adds two attributes (`op_can_like` & `op_liked`) to
`TopicListItemSerializer`.

We've also added `serialize_topic_op_likes_data` theme modifier so that
these two attributes are only added when a theme or component needs this
data.
2025-02-06 20:50:30 +05:30
Krzysztof Kotlarek
5eb7d6d9c0
FEATURE: Gracefully handle unhandled reviewables (#31118)
Plugins like for example AI or Akismet create reviewable items. When the
plugin is disabled, then we cannot properly handle those items.

In that situation, we should display warnings about unhandled types.
Instruct admin to reenable plugins. In addition, we should allow the
admin to delete all pending reviews from disabled plugins.
2025-02-05 14:38:45 +11:00
Alan Guo Xiang Tan
17e1bfe069
SECURITY: Preload data only when rendering application layout
This commit drops the `before_action :preload_json` callback in `ApplicationController` as it adds unnecessary complexity to `ApplicationController` as well as other controllers which has to skip this callback. The source of the complexity comes mainly from the following two conditionals in the `preload_json` method:

```
    # We don't preload JSON on xhr or JSON request
    return if request.xhr? || request.format.json?

    # if we are posting in makes no sense to preload
    return if request.method != "GET"
```

Basically, the conditionals solely exists for optimization purposes to ensure that we don't run the preloading code when the request is not a GET request and the response is not expected to be HTML. The key problem here is that the conditionals are trying to expect what the content type of the response will be and this has proven to be hard to get right. Instead, we can simplify this problem by running the preloading code in a more deterministic way which is to preload only when the `application` layout is being rendered and this is main change that this commit introduces.
2025-02-04 13:32:30 -03:00
David Battersby
294ed87a6f
UX: restore shared sidebar link for posts and drafts (#31159)
While introducing the new drafts dropdown menu component, we also made
some changes to how the sidebar link works for Drafts. However, after
following user feedback and internal discussions we decided to revert
back to the shared link approach that combines My Posts and My Drafts.
2025-02-04 14:40:18 +04:00
Martin Brennan
5bc7371192
FEATURE: Localization admin settings config page (#31085)
This commit adds a new Localization config page for
admins, as a basic filtered site setting page similar
to Legal and Notifications. Included settings are:

* default locale
* allow user locale
* set locale from accept langauge header
* onebox locale
* display local time in user card
* discourse local dates enabled
* support mixed text direction
* unicode usernames
* allowed unicode username characters
2025-01-31 12:55:30 +10:00
David Battersby
c64b5d6d7a
FEATURE: Multiple Draft Topics (#30790)
Allows users to save multiple topic and personal message drafts,
allowing more flexibility around content creation.

The "New Topic" button will now always start a fresh topic. Drafts can
be resumed from the drafts dropdown menu or using the "My Drafts" link
in the sidebar.

Since drafts require a unique `draft_key` and `user_id` combination, we
have updated the format of the draft key for both topics and personal
messages. They will now have a prefix like "new_topic_" or
"new_message_" with the timestamp of when the composer was first opened
appended.
2025-01-29 10:23:26 +04:00
Martin Brennan
15838aa756
DEV: Convert AdminReport component to gjs (#31011)
This commit converts the `AdminReport` component, which is quite
high complexity, to gjs. After this initial round, ideally this
component would be broken up into smaller components because it is
getting quite big now.

Also in this commit:

* Add an option to display the report description in a tooltip, which
was
   the main way the description was shown until recently. We want to use
   this on the dashboard view mostly.
* Move admin report "mode" definitions to the server-side Report model,
inside a `Report::MODES` constant, collecting the modes defined in
various
   places in the UI into one place
* Refactor report code to refer to mode definitions
* Add a `REPORT_MODES` constant in JS via javascript.rake and refactor
  JS to refer to the modes
* Delete old admin report components that are no longer used
  (trust-level-counts, counts, per-day-counts) which were replaced
  by admin-report-counters a while ago
* Add a new `registerReportModeComponent` plugin API, some plugins
   introduce their own modes (like AI's `emotion`) and components and
   we need a way to render them
2025-01-29 10:33:43 +10:00
Martin Brennan
d8102cb532
FIX: Update AdminNotice details when problem check tracker changes (#31031)
We have many problem check trackers, and some of them
like `OutOfDateThemes` can have a message which has variable
data in it shown to admins. In this case, a list of themes
that need updating. Currently if you resolve one of these
out of date themes and refresh the list of problems, you
do not see any change.

This is happening because we are only updating the `details`
of the `ProblemCheckTracker` record, not the corresponding
`AdminNotice` record which is what is displayed to the admins
on their dashboard. This commit fixes the issue by updating the
details of the notice at the same time as the problem check
tracker details.
2025-01-29 09:44:20 +10:00
Martin Brennan
08ce000647
FIX: NULL IP for similar users caused incorrect message (#30981)
When suspending a user, we check for similar users by
IP address and show a number of and a list of them.
However we were checking this if the current user had a
NULL IP address, which found all other users with a NULL
IP. This doesn't make sense, this commit fixes the issue.
2025-01-27 09:17:30 +10:00
Alan Guo Xiang Tan
62c6ee0de7
FIX: Query syntax error in UserBadge.update_featured_ranks! (#30979)
This commit fixes an SQL syntax error in
`UserBadge.update_featured_ranks!` when
the `user_ids` param is an empty array `[]`.

This was causing the `Jobs::BackfillBadge` job to raise the following
exceptions:

```
Job exception: ERROR:  syntax error at or near ")"
LINE 6:   AND user_id IN ()
```

This commit fixes the same error in
`UserState.update_distinct_badge_count` as well

Follow-up to 3e4eac0fed05daedcdea50d6275e143469d55eda
2025-01-24 14:06:39 +08:00
Alan Guo Xiang Tan
3e4eac0fed
PERF: Enqueue Job::BackfillBadge in Jobs::BadgeGrant (#30945)
This commit updates the `Jobs::BadgeGrant` scheduled job to enqueue on
`Job::BackfillBadge` regular job for each enabled badge on the site.

The rationale for this change is that we started seeing the
`Jobs::BadgeGrant` job taking hours on sites with lots of enabled badges
as well as users because the job was backfilling all enabled badges
serially within the job. This is bad as it means that a `mini_scheduler`
thread is tied up
by this job thus reducing the overall capacity of `mini_scheduler` for
hours.
2025-01-24 09:35:01 +08:00
Gary Pendergast
7fc8d74f3e
FEATURE: Allow admins to export users (#30918)
The GDPR requires all users to be able to export their data, or request an export of their data. This is fine for active users as we have a data export button on user profiles, but suspended users have no way of accessing the data export function, and the workaround for admins to export data for suspended users involves temporarily unsuspending them, then impersonating the user to export the data as them.

Since suspended users no longer have access to their account, we can safely assume that the export request will be coming via a medium outside of Discourse (eg, email). This change is built with this workflow in mind.

This change adds a new "User exports" section to the admin user page, allowing admins to start a new export, and to download the latest export file.
2025-01-24 08:13:25 +11:00
marstall
2663cb86ae
FEATURE: add new hidden site setting to show full names in user card
adds a hidden site setting, "prioritize_full_names_in_ux", whose effect is to prefer full names in user-menu notifications

Co-authored-by: Mark VanLandingham <markvanlan@gmail.com>
Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
2025-01-23 12:26:59 -05:00