Skip to content

Commit e0a9890

Browse files
authored
feat(colors): add padOptions.fadeInactiveAuthorColors with toolbar UI (#7554)
Adds a new pad option `fadeInactiveAuthorColors` (default `true`) that controls whether each author's caret/background fades toward white as they go inactive. Configurable server-side (`settings.json` / `PAD_OPTIONS_FADE_INACTIVE_AUTHOR_COLORS`), per-pad in the Pad Settings panel, per-user in the My View panel, or via `?fadeInactiveAuthorColors=false`. Disabling the fade is useful on busy pads where every faded author visually counts as a second on-screen color (a 30-author pad becomes a 60-color pad), or when inactivity tracking is undesirable for whatever reason. Closes #7138.
1 parent 6e3f929 commit e0a9890

12 files changed

Lines changed: 137 additions & 3 deletions

File tree

doc/docker.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ If your database needs additional settings, you will have to use a personalized
115115
| `PAD_OPTIONS_ALWAYS_SHOW_CHAT` | | `false` |
116116
| `PAD_OPTIONS_CHAT_AND_USERS` | | `false` |
117117
| `PAD_OPTIONS_LANG` | | `null` |
118+
| `PAD_OPTIONS_FADE_INACTIVE_AUTHOR_COLORS` | Fade each author's caret/background toward white as they go inactive. Set to `false` on busy pads (every faded author counts as a second on-screen color, so 30 contributors visually become 60), when users pick light colors that fade into the background, or whenever inactivity tracking is undesirable. | `true` |
118119

119120

120121
### Shortcuts

settings.json.docker

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,8 @@
318318
"rtl": "${PAD_OPTIONS_RTL:false}",
319319
"alwaysShowChat": "${PAD_OPTIONS_ALWAYS_SHOW_CHAT:false}",
320320
"chatAndUsers": "${PAD_OPTIONS_CHAT_AND_USERS:false}",
321-
"lang": "${PAD_OPTIONS_LANG:null}"
321+
"lang": "${PAD_OPTIONS_LANG:null}",
322+
"fadeInactiveAuthorColors": "${PAD_OPTIONS_FADE_INACTIVE_AUTHOR_COLORS:true}"
322323
},
323324

324325
/*

settings.json.template

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,13 @@
302302
"rtl": false,
303303
"alwaysShowChat": false,
304304
"chatAndUsers": false,
305-
"lang": null
305+
"lang": null,
306+
/*
307+
* When true (default), each author's caret/background color fades toward white
308+
* as the author goes inactive. Set to false if users pick light colors and the
309+
* faded variants become visually indistinguishable.
310+
*/
311+
"fadeInactiveAuthorColors": true
306312
},
307313

308314
/*

src/locales/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
"pad.settings.stickychat": "Chat always on screen",
109109
"pad.settings.chatandusers": "Show Chat and Users",
110110
"pad.settings.colorcheck": "Authorship colors",
111+
"pad.settings.fadeInactiveAuthorColors": "Fade inactive author colors",
111112
"pad.settings.linenocheck": "Line numbers",
112113
"pad.settings.rtlcheck": "Read content from right to left?",
113114
"pad.settings.enforceSettings": "Enforce settings for other users",

src/node/db/Pad.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type PadViewSettings = {
3333
showLineNumbers: boolean;
3434
rtlIsTrue: boolean;
3535
padFontFamily: string;
36+
fadeInactiveAuthorColors: boolean;
3637
};
3738

3839
type PadSettings = {
@@ -103,6 +104,9 @@ class Pad {
103104
settings.padOptions.showLineNumbers !== false : !!rawView.showLineNumbers,
104105
rtlIsTrue: !!rawView.rtlIsTrue,
105106
padFontFamily: typeof rawView.padFontFamily === 'string' ? rawView.padFontFamily : '',
107+
fadeInactiveAuthorColors: rawView.fadeInactiveAuthorColors == null ?
108+
settings.padOptions.fadeInactiveAuthorColors !== false :
109+
!!rawView.fadeInactiveAuthorColors,
106110
},
107111
};
108112
}

src/node/utils/Settings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ export type SettingsType = {
206206
alwaysShowChat: boolean,
207207
chatAndUsers: boolean,
208208
lang: string | null,
209+
fadeInactiveAuthorColors: boolean,
209210
},
210211
enableMetrics: boolean,
211212
padShortcutEnabled: {
@@ -439,6 +440,7 @@ const settings: SettingsType = {
439440
alwaysShowChat: false,
440441
chatAndUsers: false,
441442
lang: null,
443+
fadeInactiveAuthorColors: true,
442444
},
443445
/**
444446
* Wether to enable the /stats endpoint. The functionality in the admin menu is untouched for this.

src/static/js/ace2_inner.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ function Ace2Inner(editorInfo, cssManagers) {
141141
let doesWrap = true;
142142
let hasLineNumbers = true;
143143
let isStyled = true;
144+
let fadeInactiveAuthorColors =
145+
window.clientVars?.padOptions?.fadeInactiveAuthorColors !== false;
144146

145147
let console = (DEBUG && window.console);
146148

@@ -236,7 +238,13 @@ function Ace2Inner(editorInfo, cssManagers) {
236238
cssManagers.parent.removeSelectorStyle(authorSelector);
237239
} else if (info.bgcolor) {
238240
let bgcolor = info.bgcolor;
239-
if ((typeof info.fade) === 'number') {
241+
// The fade is controlled at runtime by the fadeInactiveAuthorColors flag (default
242+
// true), which tracks padOptions.view.fadeInactiveAuthorColors and is updated by
243+
// ace_setProperty when the user/pad-settings checkbox flips. Disabling it keeps
244+
// each author's background at their chosen value — useful on busy pads where each
245+
// faded author would otherwise count as a second on-screen color, or when
246+
// inactivity tracking is undesirable for whatever reason.
247+
if (fadeInactiveAuthorColors && (typeof info.fade) === 'number') {
240248
bgcolor = fadeColor(bgcolor, info.fade);
241249
}
242250
const textColor =
@@ -667,6 +675,15 @@ function Ace2Inner(editorInfo, cssManagers) {
667675
targetBody.classList.toggle('ltr', !value);
668676
document.documentElement.dir = value ? 'rtl' : 'ltr';
669677
},
678+
fadeinactiveauthorcolors: (value) => {
679+
fadeInactiveAuthorColors = `${value}` !== 'false';
680+
// Re-apply styles for every known author so that pre-faded backgrounds
681+
// refresh immediately when the toggle flips, instead of waiting for the
682+
// next fade tick (which only fires on join/leave).
683+
for (const [author, info] of Object.entries(authorInfos)) {
684+
if (info) setAuthorStyle(author, info);
685+
}
686+
},
670687
};
671688

672689
const setter = setters[key.toLowerCase()];

src/static/js/pad.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ const getParameters = [
7171
$('#clearAuthorship').hide();
7272
},
7373
},
74+
{
75+
name: 'fadeInactiveAuthorColors',
76+
checkVal: 'false',
77+
callback: (val) => {
78+
if (!clientVars.initialOptions) return;
79+
if (!clientVars.initialOptions.view) clientVars.initialOptions.view = {};
80+
clientVars.initialOptions.view.fadeInactiveAuthorColors = false;
81+
},
82+
},
7483
{
7584
name: 'showControls',
7685
checkVal: 'true',
@@ -214,6 +223,7 @@ const getMyViewOverrides = () => {
214223
showLineNumbers: padcookie.getPref('showLineNumbers'),
215224
rtlIsTrue: padcookie.getPref('rtlIsTrue'),
216225
padFontFamily: padcookie.getPref('padFontFamily'),
226+
fadeInactiveAuthorColors: padcookie.getPref('fadeInactiveAuthorColors'),
217227
},
218228
};
219229
if (language == null) delete overrides.lang;
@@ -549,6 +559,8 @@ const pad = {
549559
$('#padsettings-options-stickychat').prop('checked', !!padOptions.alwaysShowChat);
550560
$('#padsettings-options-chatandusers').prop('checked', !!padOptions.chatAndUsers);
551561
$('#padsettings-options-colorscheck').prop('checked', view.showAuthorColors !== false);
562+
$('#padsettings-options-fadeauthorcheck')
563+
.prop('checked', view.fadeInactiveAuthorColors !== false);
552564
$('#padsettings-options-linenoscheck').prop('checked', view.showLineNumbers !== false);
553565
$('#padsettings-options-rtlcheck').prop('checked', !!view.rtlIsTrue);
554566
$('#padsettings-viewfontmenu').val(view.padFontFamily || '');
@@ -565,6 +577,8 @@ const pad = {
565577
$('#options-stickychat').prop('checked', !!effectiveOptions.alwaysShowChat);
566578
$('#options-chatandusers').prop('checked', !!effectiveOptions.chatAndUsers);
567579
$('#options-colorscheck').prop('checked', effectiveOptions.view?.showAuthorColors !== false);
580+
$('#options-fadeauthorcheck')
581+
.prop('checked', effectiveOptions.view?.fadeInactiveAuthorColors !== false);
568582
$('#options-linenoscheck').prop('checked', effectiveOptions.view?.showLineNumbers !== false);
569583
$('#options-rtlcheck').prop('checked', !!effectiveOptions.view?.rtlIsTrue);
570584
$('#viewfontmenu').val(effectiveOptions.view?.padFontFamily || '');

src/static/js/pad_editor.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ const padeditor = (() => {
6868
padutils.bindCheckboxChange($('#options-colorscheck'), () => {
6969
pad.setMyViewOption('showAuthorColors', padutils.getCheckbox($('#options-colorscheck')));
7070
});
71+
padutils.bindCheckboxChange($('#options-fadeauthorcheck'), () => {
72+
pad.setMyViewOption(
73+
'fadeInactiveAuthorColors',
74+
padutils.getCheckbox($('#options-fadeauthorcheck')));
75+
});
7176
padutils.bindCheckboxChange($('#options-linenoscheck'), () => {
7277
pad.setMyViewOption('showLineNumbers', padutils.getCheckbox($('#options-linenoscheck')));
7378
});
@@ -108,6 +113,13 @@ const padeditor = (() => {
108113
'showAuthorColors', padutils.getCheckbox('#padsettings-options-colorscheck'));
109114
});
110115

116+
// Fade inactive author colors
117+
padutils.bindCheckboxChange($('#padsettings-options-fadeauthorcheck'), () => {
118+
pad.changePadViewOption(
119+
'fadeInactiveAuthorColors',
120+
padutils.getCheckbox('#padsettings-options-fadeauthorcheck'));
121+
});
122+
111123
// Right to left
112124
padutils.bindCheckboxChange($('#padsettings-options-rtlcheck'), () => {
113125
pad.changePadViewOption(
@@ -248,6 +260,10 @@ const padeditor = (() => {
248260
$('iframe[name="ace_outer"]').contents().find('#sidedivinner').toggleClass('authorColors', v);
249261
padutils.setCheckbox($('#options-colorscheck'), v);
250262

263+
v = getOption('fadeInactiveAuthorColors', true);
264+
self.ace.setProperty('fadeInactiveAuthorColors', v);
265+
padutils.setCheckbox($('#options-fadeauthorcheck'), v);
266+
251267
// Override from parameters if true
252268
if (settings.noColors !== false) {
253269
self.ace.setProperty('showsauthorcolors', !settings.noColors);

src/templates/pad.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ <h2 data-l10n-id="pad.settings.myView"></h2>
156156
<input type="checkbox" id="options-colorscheck">
157157
<label for="options-colorscheck" data-l10n-id="pad.settings.colorcheck"></label>
158158
</p>
159+
<p>
160+
<input type="checkbox" id="options-fadeauthorcheck" checked>
161+
<label for="options-fadeauthorcheck" data-l10n-id="pad.settings.fadeInactiveAuthorColors"></label>
162+
</p>
159163
<p>
160164
<input type="checkbox" id="options-linenoscheck" checked>
161165
<label for="options-linenoscheck" data-l10n-id="pad.settings.linenocheck"></label>
@@ -217,6 +221,10 @@ <h2 data-l10n-id="pad.settings.padSettings"></h2>
217221
<input type="checkbox" id="padsettings-options-colorscheck">
218222
<label for="padsettings-options-colorscheck" data-l10n-id="pad.settings.colorcheck"></label>
219223
</p>
224+
<p>
225+
<input type="checkbox" id="padsettings-options-fadeauthorcheck" checked>
226+
<label for="padsettings-options-fadeauthorcheck" data-l10n-id="pad.settings.fadeInactiveAuthorColors"></label>
227+
</p>
220228
<p>
221229
<input type="checkbox" id="padsettings-options-linenoscheck" checked>
222230
<label for="padsettings-options-linenoscheck" data-l10n-id="pad.settings.linenocheck"></label>

0 commit comments

Comments
 (0)