feat(#4676): gate per-project quick-create buttons behind opt-in setting
Add a default-OFF 'project_quick_create_buttons' setting that gates the per-project '+' quick-create buttons on sidebar project chips. The chip render site only calls _attachProjectQuickCreateButton when the new window._projectQuickCreate runtime flag is enabled, so the buttons do not appear unless the user opts in via Settings. Mirrors the large_text_paste_as_attachment opt-in plumbing (defaults, allowlist, settings collect/restore/save, window hydration at both sites, checkbox row, i18n across all locales).
This commit is contained in:
1 parent
66fc8722c1
commit
b098e5c658
6 files changed
+60
-1
No files matched your search
@@ -7815,6 +7815,7 @@ _SETTINGS_DEFAULTS = {
|
||||
"session_jump_buttons": False, # show Start/End transcript jump pills
|
||||
"render_user_markdown": False, # opt-in: render full markdown in user messages (#3870)
|
||||
"large_text_paste_as_attachment": True, # convert very large composer text pastes into .md attachments by default
|
||||
"project_quick_create_buttons": False, # opt-in: show per-project "+" quick-create buttons on sidebar project chips (#4676)
|
||||
"structured_code_default_view": "auto", # JSON/YAML fenced-block default render: auto | on | off (#484 follow-up). auto => Tree when line count >= structured_code_auto_tree_lines, else Raw.
|
||||
"structured_code_auto_tree_lines": 10, # in 'auto' mode, minimum line count to default a JSON/YAML block to Tree view (preserves the original hardcoded >=10 behavior)
|
||||
"session_endless_scroll": False, # auto-load older transcript pages while scrolling upward
|
||||
@@ -8065,6 +8066,7 @@ _SETTINGS_BOOL_KEYS = {
|
||||
"session_jump_buttons",
|
||||
"render_user_markdown",
|
||||
"large_text_paste_as_attachment",
|
||||
"project_quick_create_buttons",
|
||||
"session_endless_scroll",
|
||||
"auto_scroll_follow",
|
||||
"worklog_details_expanded_default",
|
||||
|
||||
@@ -621,6 +621,8 @@ const LOCALES = {
|
||||
settings_desc_render_user_markdown: 'When enabled, bold, italic, links, and other markdown in your own messages are rendered. Off by default; fenced code blocks and math always render regardless of this setting.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_structured_code: 'JSON/YAML code blocks',
|
||||
settings_option_structured_code_auto: 'Auto: Tree for long blocks',
|
||||
settings_option_structured_code_on: 'Tree by default',
|
||||
@@ -2269,6 +2271,8 @@ const LOCALES = {
|
||||
settings_desc_render_user_markdown: 'When enabled, bold, italic, links, and other markdown in your own messages are rendered. Off by default; fenced code blocks and math always render regardless of this setting.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_structured_code: 'JSON/YAML code blocks',
|
||||
settings_option_structured_code_auto: 'Auto: Tree for long blocks',
|
||||
settings_option_structured_code_on: 'Tree by default',
|
||||
@@ -3908,6 +3912,8 @@ const LOCALES = {
|
||||
settings_desc_render_user_markdown: 'When enabled, bold, italic, links, and other markdown in your own messages are rendered. Off by default; fenced code blocks and math always render regardless of this setting.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_structured_code: 'JSON/YAML code blocks',
|
||||
settings_option_structured_code_auto: 'Auto: Tree for long blocks',
|
||||
settings_option_structured_code_on: 'Tree by default',
|
||||
@@ -6261,6 +6267,8 @@ const LOCALES = {
|
||||
settings_desc_render_user_markdown: 'When enabled, bold, italic, links, and other markdown in your own messages are rendered. Off by default; fenced code blocks and math always render regardless of this setting.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_structured_code: 'JSON/YAML code blocks',
|
||||
settings_option_structured_code_auto: 'Auto: Tree for long blocks',
|
||||
settings_option_structured_code_on: 'Tree by default',
|
||||
@@ -7825,6 +7833,8 @@ const LOCALES = {
|
||||
settings_desc_render_user_markdown: 'When enabled, bold, italic, links, and other markdown in your own messages are rendered. Off by default; fenced code blocks and math always render regardless of this setting.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_structured_code: 'JSON/YAML code blocks',
|
||||
settings_option_structured_code_auto: 'Auto: Tree for long blocks',
|
||||
settings_option_structured_code_on: 'Tree by default',
|
||||
@@ -9070,6 +9080,8 @@ const LOCALES = {
|
||||
settings_desc_render_user_markdown: 'When enabled, bold, italic, links, and other markdown in your own messages are rendered. Off by default; fenced code blocks and math always render regardless of this setting.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_structured_code: 'JSON/YAML code blocks',
|
||||
settings_option_structured_code_auto: 'Auto: Tree for long blocks',
|
||||
settings_option_structured_code_on: 'Tree by default',
|
||||
@@ -10988,6 +11000,8 @@ const LOCALES = {
|
||||
settings_desc_render_user_markdown: 'When enabled, bold, italic, links, and other markdown in your own messages are rendered. Off by default; fenced code blocks and math always render regardless of this setting.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_structured_code: 'JSON/YAML code blocks',
|
||||
settings_option_structured_code_auto: 'Auto: Tree for long blocks',
|
||||
settings_option_structured_code_on: 'Tree by default',
|
||||
@@ -11852,6 +11866,8 @@ const LOCALES = {
|
||||
settings_desc_render_user_markdown: 'When enabled, bold, italic, links, and other markdown in your own messages are rendered. Off by default; fenced code blocks and math always render regardless of this setting.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_structured_code: 'JSON/YAML code blocks',
|
||||
settings_option_structured_code_auto: 'Auto: Tree for long blocks',
|
||||
settings_option_structured_code_on: 'Tree by default',
|
||||
@@ -13388,6 +13404,8 @@ const LOCALES = {
|
||||
settings_desc_render_user_markdown: 'When enabled, bold, italic, links, and other markdown in your own messages are rendered. Off by default; fenced code blocks and math always render regardless of this setting.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_structured_code: 'JSON/YAML code blocks',
|
||||
settings_option_structured_code_auto: 'Auto: Tree for long blocks',
|
||||
settings_option_structured_code_on: 'Tree by default',
|
||||
@@ -14926,6 +14944,8 @@ const LOCALES = {
|
||||
settings_desc_render_user_markdown: 'When enabled, bold, italic, links, and other markdown in your own messages are rendered. Off by default; fenced code blocks and math always render regardless of this setting.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_structured_code: 'JSON/YAML code blocks',
|
||||
settings_option_structured_code_auto: 'Auto: Tree for long blocks',
|
||||
settings_option_structured_code_on: 'Tree by default',
|
||||
@@ -16577,6 +16597,8 @@ const LOCALES = {
|
||||
settings_desc_render_user_markdown: 'Lorsqu\'il est activé, le gras, l\'italique, les liens et autres éléments markdown dans vos propres messages sont rendus. Désactivé par défaut ; les blocs de code et les formules mathématiques sont toujours rendus, indépendamment de ce paramètre.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_structured_code: 'Blocs de code JSON/YAML',
|
||||
settings_option_structured_code_auto: 'Auto : Arborescence pour les blocs longs',
|
||||
settings_option_structured_code_on: 'Arborescence par défaut',
|
||||
@@ -18184,6 +18206,8 @@ const LOCALES = {
|
||||
settings_desc_render_user_markdown: 'When enabled, bold, italic, links, and other markdown in your own messages are rendered. Off by default; fenced code blocks and math always render regardless of this setting.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_structured_code: 'JSON/YAML code blocks',
|
||||
settings_option_structured_code_auto: 'Auto: Tree for long blocks',
|
||||
settings_option_structured_code_on: 'Tree by default',
|
||||
@@ -19843,6 +19867,8 @@ const LOCALES = {
|
||||
settings_desc_structured_code: 'Gdy wybrano tryb automatyczny, bloki JSON/YAML o długości przynajmniej podanej liczby wierszy zostaną otwarte w widoku drzewa. Widok drzewa zawsze otwiera strukturyzowaną przeglądarkę; widok źródła zachowuje podświetlony składniowo tekst. Nadal możesz przełączać tryby dla każdego bloku osobno.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_worklog_details_expanded_default: 'Otwieraj szczegóły Worklog automatycznie',
|
||||
settings_desc_worklog_details_expanded_default: 'Gdy ta opcja jest włączona, nowe szczegóły Worklog zaczynają rozwinięte, dzięki czemu karty narzędzi, Thinking i postępu są widoczne bez dodatkowego kliknięcia. Gdy jest wyłączona, szczegóły Worklog pozostają domyślnie zwinięte. Ręczne decyzje o zwinięciu/rozwinięciu w danej turze mają pierwszeństwo.',
|
||||
settings_label_chat_activity_display_mode: 'Wyświetlanie aktywności',
|
||||
@@ -21378,6 +21404,8 @@ const LOCALES = {
|
||||
settings_desc_render_user_markdown: 'Khi bật, chữ đậm, chữ nghiêng, liên kết và các Markdown khác trong tin nhắn của bạn sẽ được render. Mặc định tắt; khối code fenced và công thức toán luôn được render bất kể cài đặt này.',
|
||||
settings_label_large_text_paste_as_attachment: 'Attach large pasted text as file',
|
||||
settings_desc_large_text_paste_as_attachment: 'When enabled, long pasted text becomes a .md attachment instead of filling the composer.',
|
||||
settings_label_project_quick_create: 'Show per-project new-conversation buttons',
|
||||
settings_desc_project_quick_create: 'When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.',
|
||||
settings_label_structured_code: 'Khối code JSON/YAML',
|
||||
settings_option_structured_code_auto: 'Tự động: dạng cây cho khối dài',
|
||||
settings_option_structured_code_on: 'Mặc định dạng cây',
|
||||
|
||||
@@ -1059,6 +1059,13 @@
|
||||
</label>
|
||||
<div style="font-size:11px;color:var(--muted);margin-top:4px" data-i18n="settings_desc_large_text_paste_as_attachment">When enabled, long pasted text becomes a .md attachment instead of filling the composer.</div>
|
||||
</div>
|
||||
<div class="settings-field" style="margin-top:8px">
|
||||
<label style="display:flex;align-items:center;gap:8px;cursor:pointer">
|
||||
<input type="checkbox" id="settingsProjectQuickCreate" style="width:15px;height:15px;accent-color:var(--accent)">
|
||||
<span data-i18n="settings_label_project_quick_create">Show per-project new-conversation buttons</span>
|
||||
</label>
|
||||
<div style="font-size:11px;color:var(--muted);margin-top:4px" data-i18n="settings_desc_project_quick_create">When enabled, each project chip in the sidebar gets a + button to start a conversation in that project.</div>
|
||||
</div>
|
||||
<div class="settings-field" style="margin-top:8px">
|
||||
<label for="settingsStructuredCodeMode" data-i18n="settings_label_structured_code">JSON/YAML code blocks</label>
|
||||
<select id="settingsStructuredCodeMode" style="width:100%;padding:8px;background:var(--code-bg);color:var(--text);border:1px solid var(--border2);border-radius:6px">
|
||||
|
||||
@@ -7475,6 +7475,7 @@ function _appearancePayloadFromUi(){
|
||||
auto_scroll_follow: !!($('settingsAutoScrollFollow')||{}).checked,
|
||||
render_user_markdown: !!($('settingsRenderUserMarkdown')||{}).checked,
|
||||
large_text_paste_as_attachment: !!($('settingsLargeTextPasteAsAttachment')||{}).checked,
|
||||
project_quick_create_buttons: !!($('settingsProjectQuickCreate')||{}).checked,
|
||||
..._structuredCodeViewFromUi(),
|
||||
show_titlebar_profile: !!($('settingsShowTitlebarProfile')||{}).checked,
|
||||
worklog_details_expanded_default: worklogDetailsExpanded,
|
||||
@@ -7565,6 +7566,7 @@ async function _autosaveAppearanceSettings(payload){
|
||||
window._sessionEndlessScrollEnabled=!!(saved&&saved.session_endless_scroll);
|
||||
window._autoScrollFollow=!saved||saved.auto_scroll_follow!==false;
|
||||
window._largeTextPasteAsAttachment=!saved||saved.large_text_paste_as_attachment!==false;
|
||||
window._projectQuickCreate=!!(saved&&saved.project_quick_create_buttons);
|
||||
if(saved&&Object.prototype.hasOwnProperty.call(saved,'structured_code_default_view')){
|
||||
// Re-sync from the server-validated/clamped values so the UI and runtime
|
||||
// globals match exactly what was persisted.
|
||||
@@ -7927,6 +7929,15 @@ async function loadSettingsPanel(){
|
||||
_scheduleAppearanceAutosave();
|
||||
};
|
||||
}
|
||||
const pqcCb=$('settingsProjectQuickCreate');
|
||||
if(pqcCb){
|
||||
pqcCb.checked=!!(settings.project_quick_create_buttons);
|
||||
window._projectQuickCreate=pqcCb.checked;
|
||||
pqcCb.onchange=function(){
|
||||
window._projectQuickCreate=this.checked;
|
||||
_scheduleAppearanceAutosave();
|
||||
};
|
||||
}
|
||||
const structuredCodeModeSel=$('settingsStructuredCodeMode');
|
||||
const structuredCodeLinesField=$('settingsStructuredCodeAutoLines');
|
||||
if(structuredCodeModeSel){
|
||||
@@ -10255,6 +10266,7 @@ function _applySavedSettingsUi(saved, body, opts){
|
||||
window._sessionEndlessScrollEnabled=!!body.session_endless_scroll;
|
||||
window._autoScrollFollow=body.auto_scroll_follow!==false;
|
||||
window._largeTextPasteAsAttachment=body.large_text_paste_as_attachment!==false;
|
||||
window._projectQuickCreate=!!body.project_quick_create_buttons;
|
||||
if(Object.prototype.hasOwnProperty.call(body,'structured_code_default_view')){
|
||||
_applyStructuredCodeViewSettings(body.structured_code_default_view,body.structured_code_auto_tree_lines,false);
|
||||
}
|
||||
@@ -10825,6 +10837,7 @@ async function saveSettings(andClose){
|
||||
body.auto_scroll_follow=!!($('settingsAutoScrollFollow')||{}).checked;
|
||||
body.render_user_markdown=!!($('settingsRenderUserMarkdown')||{}).checked;
|
||||
body.large_text_paste_as_attachment=!!($('settingsLargeTextPasteAsAttachment')||{}).checked;
|
||||
body.project_quick_create_buttons=!!($('settingsProjectQuickCreate')||{}).checked;
|
||||
Object.assign(body,_structuredCodeViewFromUi());
|
||||
body.language=language;
|
||||
body.show_token_usage=showTokenUsage;
|
||||
|
||||
+1
-1
@@ -6407,7 +6407,7 @@ function renderSessionListFromCache(){
|
||||
clearTimeout(_lpTimer);_lpTimer=null;_lpHandled=false;
|
||||
chip.classList.remove('long-pressing');
|
||||
},{passive:true});
|
||||
_attachProjectQuickCreateButton(chip,p);
|
||||
if(window._projectQuickCreate) _attachProjectQuickCreateButton(chip,p);
|
||||
bar.appendChild(chip);
|
||||
}
|
||||
// Create button
|
||||
|
||||
@@ -56,6 +56,15 @@ def test_quick_create_button_attaches_filter_align_and_request_path():
|
||||
assert "btn.ontouchend" in helper
|
||||
|
||||
|
||||
def test_quick_create_button_render_is_gated_off_by_default():
|
||||
"""#4676 quick-create buttons must be opt-in: the chip render site only
|
||||
attaches the per-project '+' button when window._projectQuickCreate is set."""
|
||||
src = _read(SESSIONS_JS)
|
||||
assert "if(window._projectQuickCreate) _attachProjectQuickCreateButton(chip,p);" in src
|
||||
# The attach call must never run unconditionally at the render site.
|
||||
assert "\n _attachProjectQuickCreateButton(chip,p);" not in src
|
||||
|
||||
|
||||
def test_project_quick_create_styles_exist_and_are_discrete_to_pointer_layouts():
|
||||
css = _read(STYLE_CSS)
|
||||
assert ".project-chip-quick-create" in css
|
||||
|
||||
Reference in new issue
Block a user