FEATURE: Add user preference to disable smart lists (#29434)
Some checks are pending
Licenses / run (push) Waiting to run
Linting / run (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (annotations, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (backend, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (backend, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (frontend, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (frontend, themes) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, chat) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, themes) (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Chrome) (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Firefox ESR) (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Firefox Evergreen) (push) Waiting to run

Followup 30fdd7738e

Adds a new site setting and corresponding user preference
to disable smart lists. By default they are enabled, because
this is a better experience for most users. A small number of
users would prefer to not have this enabled.

Smart lists automatically append new items to each
list started in the composer when enter is pressed. If
enter is pressed on an empty list item, it is cleared.

This setting will be removed when the new composer is complete.
This commit is contained in:
Martin Brennan 2024-10-28 14:18:15 +10:00 committed by GitHub
parent 456fbb1dbf
commit 27bdfb6437
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 100 additions and 24 deletions

View File

@ -57,6 +57,7 @@ const DEFAULT_USER_PREFERENCES = [
"default_other_notification_level_when_replying",
"default_other_external_links_in_new_tab",
"default_other_enable_quoting",
"default_other_enable_smart_lists",
"default_other_enable_defer",
"default_other_dynamic_favicon",
"default_other_like_notification_frequency",

View File

@ -374,11 +374,13 @@ export default class DEditor extends Component {
//
// c.f. https://developer.mozilla.org/en-US/docs/Web/API/Element/beforeinput_event
if (this._textarea) {
this._textarea.addEventListener(
"beforeinput",
this.onBeforeInputSmartList
);
this._textarea.addEventListener("input", this.onInputSmartList);
if (this.currentUser.user_option.enable_smart_lists) {
this._textarea.addEventListener(
"beforeinput",
this.onBeforeInputSmartList
);
this._textarea.addEventListener("input", this.onInputSmartList);
}
this.element.addEventListener("paste", this.textManipulation.paste);
}
@ -483,11 +485,13 @@ export default class DEditor extends Component {
}
if (this._textarea) {
this._textarea.removeEventListener(
"beforeinput",
this.onBeforeInputSmartList
);
this._textarea.removeEventListener("input", this.onInputSmartList);
if (this.currentUser.user_option.enable_smart_lists) {
this._textarea.removeEventListener(
"beforeinput",
this.onBeforeInputSmartList
);
this._textarea.removeEventListener("input", this.onInputSmartList);
}
}
this._itsatrap?.destroy();

View File

@ -68,6 +68,7 @@ export default class InterfaceController extends Controller {
"external_links_in_new_tab",
"dynamic_favicon",
"enable_quoting",
"enable_smart_lists",
"enable_defer",
"automatically_unpin_topics",
"allow_private_messages",

View File

@ -108,6 +108,7 @@ let userOptionFields = [
"dark_scheme_id",
"dynamic_favicon",
"enable_quoting",
"enable_smart_lists",
"enable_defer",
"automatically_unpin_topics",
"digest_after_minutes",
@ -182,6 +183,7 @@ export default class User extends RestModel.extend(Evented) {
@userOption("mailing_list_mode") mailing_list_mode;
@userOption("external_links_in_new_tab") external_links_in_new_tab;
@userOption("enable_quoting") enable_quoting;
@userOption("enable_smart_lists") enable_smart_lists;
@userOption("dynamic_favicon") dynamic_favicon;
@userOption("automatically_unpin_topics") automatically_unpin_topics;
@userOption("likes_notifications_disabled") likes_notifications_disabled;

View File

@ -177,6 +177,12 @@
data-setting-name="user-enable-quoting"
class="pref-enable-quoting"
/>
<PreferenceCheckbox
@labelKey="user.enable_smart_lists"
@checked={{this.model.user_option.enable_smart_lists}}
data-setting-name="user-enable-smart-lists"
class="pref-enable-smart-lists"
/>
<PreferenceCheckbox
@labelKey="user.enable_defer"
@checked={{this.model.user_option.enable_defer}}

View File

@ -1,7 +1,5 @@
import { deepFreeze } from "discourse-common/lib/object";
import {
AUTO_GROUPS,
} from "discourse/lib/constants";
import { AUTO_GROUPS } from "discourse/lib/constants";
export default {
"/session/current.json": deepFreeze({
@ -45,6 +43,7 @@ export default {
user_option: {
external_links_in_new_tab: false,
enable_quoting: true,
enable_smart_lists: true,
dynamic_favicon: true,
title_count_mode: "notifications",
timezone: "Australia/Brisbane",
@ -132,7 +131,7 @@ export default {
},
],
},
]
],
},
}),
};

View File

@ -118,6 +118,7 @@ export default {
dynamic_favicon: true,
skip_new_user_tips: false,
enable_quoting: true,
enable_smart_lists: true,
timezone: "Australia/Brisbane",
},
id: 19,
@ -2706,6 +2707,7 @@ export default {
dynamic_favicon: false,
skip_new_user_tips: false,
enable_quoting: true,
enable_smart_lists: true,
digest_after_minutes: 10080,
automatically_unpin_topics: true,
auto_track_topics_after_msecs: 240000,
@ -3108,6 +3110,7 @@ export default {
dynamic_favicon: false,
skip_new_user_tips: false,
enable_quoting: true,
enable_smart_lists: true,
enable_defer: false,
digest_after_minutes: 1440,
automatically_unpin_topics: true,
@ -3272,6 +3275,7 @@ export default {
dynamic_favicon: true,
skip_new_user_tips: false,
enable_quoting: true,
enable_smart_lists: true,
timezone: "Australia/Brisbane",
},
id: 4432,
@ -3489,6 +3493,7 @@ export default {
dynamic_favicon: true,
skip_new_user_tips: false,
enable_quoting: true,
enable_smart_lists: true,
timezone: "Australia/Brisbane",
},
id: 20,

View File

@ -72,8 +72,13 @@ module("Integration | Component | d-editor", function (hooks) {
return textarea;
}
function testCase(title, testFunc) {
function testCase(title, testFunc, userOptions = {}) {
test(title, async function (assert) {
this.currentUser.user_option = Object.assign(
{},
this.currentUser.user_option,
userOptions
);
this.set("value", "hello world.");
await render(hbs`<DEditor @value={{this.value}} />`);
@ -1017,6 +1022,23 @@ third line`
});
}
testCase(
"smart lists - when enable_smart_lists is false pressing enter on a line with a list item starting with *",
async function (assert, textarea) {
const initialValue = "* first item in list\n";
this.set("value", initialValue);
setCaretPosition(textarea, initialValue.length);
await triggerEnter(textarea);
assert.strictEqual(
this.value,
initialValue,
"it does not create an empty list item on the next line"
);
},
{ enable_smart_lists: false }
);
testCase(
"smart lists - pressing enter on a line with a list item starting with *",
async function (assert, textarea) {
@ -1030,7 +1052,8 @@ third line`
initialValue + "* ",
"it creates a list item on the next line"
);
}
},
{ enable_smart_lists: true }
);
testCase(
@ -1046,7 +1069,8 @@ third line`
initialValue + "",
"it doesnt continue the list"
);
}
},
{ enable_smart_lists: true }
);
testCase(
@ -1062,7 +1086,8 @@ third line`
initialValue + "* ",
"it continues the list"
);
}
},
{ enable_smart_lists: true }
);
testCase(
@ -1073,7 +1098,8 @@ third line`
setCaretPosition(textarea, initialValue.length);
await triggerEnter(textarea);
assert.strictEqual(this.value, initialValue + "- ");
}
},
{ enable_smart_lists: true }
);
testCase(
@ -1088,7 +1114,8 @@ third line`
initialValue + "2. ",
"it creates a list item on the next line with an auto-incremented number"
);
}
},
{ enable_smart_lists: true }
);
testCase(
@ -1103,7 +1130,8 @@ third line`
"* first item in list\n* \n* second item in list",
"it inserts a new list item on the next line"
);
}
},
{ enable_smart_lists: true }
);
testCase(
@ -1118,7 +1146,8 @@ third line`
"1. first item in list\n2. \n3. second item in list",
"it inserts a new list item on the next line and renumbers the rest of the list"
);
}
},
{ enable_smart_lists: true }
);
testCase(
@ -1133,7 +1162,8 @@ third line`
"* first item in list with empty line\n",
"it removes the list item"
);
}
},
{ enable_smart_lists: true }
);
(() => {

View File

@ -73,6 +73,7 @@ class UserOption < ActiveRecord::Base
self.email_in_reply_to = SiteSetting.default_email_in_reply_to
self.enable_quoting = SiteSetting.default_other_enable_quoting
self.enable_smart_lists = SiteSetting.default_other_enable_smart_lists
self.enable_defer = SiteSetting.default_other_enable_defer
self.external_links_in_new_tab = SiteSetting.default_other_external_links_in_new_tab
self.dynamic_favicon = SiteSetting.default_other_dynamic_favicon
@ -284,6 +285,7 @@ end
# chat_separate_sidebar_mode :integer default(0), not null
# topics_unread_when_closed :boolean default(TRUE), not null
# show_thread_title_prompts :boolean default(TRUE), not null
# enable_smart_lists :boolean default(TRUE), not null
#
# Indexes
#

View File

@ -4,6 +4,7 @@ class CurrentUserOptionSerializer < ApplicationSerializer
attributes :mailing_list_mode,
:external_links_in_new_tab,
:enable_quoting,
:enable_smart_lists,
:dynamic_favicon,
:automatically_unpin_topics,
:likes_notifications_disabled,

View File

@ -12,6 +12,7 @@ class UserOptionSerializer < ApplicationSerializer
:dark_scheme_id,
:dynamic_favicon,
:enable_quoting,
:enable_smart_lists,
:enable_defer,
:digest_after_minutes,
:automatically_unpin_topics,

View File

@ -113,6 +113,7 @@ class SiteSettingUpdateExistingUsers
default_email_previous_replies: "email_previous_replies",
default_email_in_reply_to: "email_in_reply_to",
default_other_enable_quoting: "enable_quoting",
default_other_enable_smart_lists: "enable_smart_lists",
default_other_enable_defer: "enable_defer",
default_other_external_links_in_new_tab: "external_links_in_new_tab",
default_other_dynamic_favicon: "dynamic_favicon",

View File

@ -24,6 +24,7 @@ class UserUpdater
email_messages_level
external_links_in_new_tab
enable_quoting
enable_smart_lists
enable_defer
color_scheme_id
dark_scheme_id

View File

@ -1358,6 +1358,7 @@ en:
allow_private_messages: "Allow other users to send me personal messages"
external_links_in_new_tab: "Open all external links in a new tab"
enable_quoting: "Enable quote reply for highlighted text"
enable_smart_lists: "Enable smart lists when writing in the composer"
enable_defer: "Enable mark topics as unread"
experimental_sidebar:
enable: "Enable sidebar"
@ -1427,7 +1428,7 @@ en:
ignored_users: "Ignored"
ignored_users_instructions: "Suppress all posts, notifications, and PMs from these users."
tracked_topics_link: "Show"
automatically_unpin_topics: "Automatically unpin topics when I reach the bottom."
automatically_unpin_topics: "Automatically unpin topics when I reach the bottom"
apps: "Apps"
revoke_access: "Revoke Access"
undo_revoke_access: "Undo Revoke Access"

View File

@ -2602,6 +2602,7 @@ en:
default_other_notification_level_when_replying: "Global default notification level when the user replies to a topic."
default_other_external_links_in_new_tab: "Open external links in a new tab by default."
default_other_enable_quoting: "Enable quote reply for highlighted text by default."
default_other_enable_smart_lists: "Enable smart lists when typing in the composer by default."
default_other_enable_defer: "Enable defer topic functionality by default."
default_other_dynamic_favicon: "Show new/updated topic count on browser icon by default."
default_other_skip_new_user_tips: "Skip new user onboarding tips and badges."

View File

@ -3059,6 +3059,7 @@ user_preferences:
default_other_external_links_in_new_tab: false
default_other_enable_quoting: true
default_other_enable_defer: false
default_other_enable_smart_lists: true
default_other_dynamic_favicon: false
default_other_skip_new_user_tips: false
default_other_like_notification_frequency:

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddSmartListUserPreference < ActiveRecord::Migration[7.1]
def change
add_column :user_options, :enable_smart_lists, :boolean, default: true, null: false
end
end

View File

@ -164,6 +164,7 @@ def insert_user_options
include_tl0_in_digests,
automatically_unpin_topics,
enable_quoting,
enable_smart_lists,
external_links_in_new_tab,
dynamic_favicon,
new_topic_duration_minutes,
@ -187,6 +188,7 @@ def insert_user_options
, #{SiteSetting.default_include_tl0_in_digests}
, #{SiteSetting.default_topics_automatic_unpin}
, #{SiteSetting.default_other_enable_quoting}
, #{SiteSetting.default_other_enable_smart_lists}
, #{SiteSetting.default_other_external_links_in_new_tab}
, #{SiteSetting.default_other_dynamic_favicon}
, #{SiteSetting.default_other_new_topic_duration_minutes}

View File

@ -577,6 +577,7 @@ class BulkImport::Base
include_tl0_in_digests
automatically_unpin_topics
enable_quoting
enable_smart_lists
external_links_in_new_tab
dynamic_favicon
new_topic_duration_minutes
@ -1306,6 +1307,7 @@ class BulkImport::Base
include_tl0_in_digests: SiteSetting.default_include_tl0_in_digests,
automatically_unpin_topics: SiteSetting.default_topics_automatic_unpin,
enable_quoting: SiteSetting.default_other_enable_quoting,
enable_smart_lists: SiteSetting.default_other_enable_smart_lists,
external_links_in_new_tab: SiteSetting.default_other_external_links_in_new_tab,
dynamic_favicon: SiteSetting.default_other_dynamic_favicon,
new_topic_duration_minutes: SiteSetting.default_other_new_topic_duration_minutes,

View File

@ -73,6 +73,7 @@ RSpec.describe UserOption do
describe "site settings" do
it "should apply defaults from site settings" do
SiteSetting.default_other_enable_quoting = false
SiteSetting.default_other_enable_smart_lists = false
SiteSetting.default_other_enable_defer = true
SiteSetting.default_other_external_links_in_new_tab = true
SiteSetting.default_other_dynamic_favicon = true
@ -81,6 +82,7 @@ RSpec.describe UserOption do
user = Fabricate(:user)
expect(user.user_option.enable_quoting).to eq(false)
expect(user.user_option.enable_smart_lists).to eq(false)
expect(user.user_option.enable_defer).to eq(true)
expect(user.user_option.external_links_in_new_tab).to eq(true)
expect(user.user_option.dynamic_favicon).to eq(true)

View File

@ -2163,6 +2163,7 @@ RSpec.describe User do
SiteSetting.default_other_notification_level_when_replying = 3 # immediately
SiteSetting.default_other_external_links_in_new_tab = true
SiteSetting.default_other_enable_quoting = false
SiteSetting.default_other_enable_smart_lists = false
SiteSetting.default_other_dynamic_favicon = true
SiteSetting.default_other_skip_new_user_tips = true
@ -2185,6 +2186,7 @@ RSpec.describe User do
expect(options.email_messages_level).to eq(UserOption.email_level_types[:never])
expect(options.external_links_in_new_tab).to eq(true)
expect(options.enable_quoting).to eq(false)
expect(options.enable_smart_lists).to eq(false)
expect(options.dynamic_favicon).to eq(true)
expect(options.skip_new_user_tips).to eq(true)
expect(options.hide_profile_and_presence).to eq(true)

View File

@ -714,6 +714,9 @@
"enable_quoting": {
"type": "boolean"
},
"enable_smart_lists": {
"type": "boolean"
},
"enable_defer": {
"type": "boolean"
},
@ -820,6 +823,7 @@
"dark_scheme_id",
"dynamic_favicon",
"enable_quoting",
"enable_smart_lists",
"enable_defer",
"digest_after_minutes",
"automatically_unpin_topics",