support-form.jsjavascript
/**
* @file Support-form decision logic — the pure branches behind the Help modal's "Send to
* support" button.
*
* Extracted from renderer.html's submit handler so it can be unit-tested in plain Node
* (test/support-form.test.js) without a DOM. The renderer still owns all DOM reads/writes
* and the IPC call; this module owns only the decisions — which submissions are
* sendable, and which sentence each outcome earns — so the two stay in lock-step by
* construction.
*
* Loaded two ways (UMD-lite): the Electron renderer loads it with a plain script tag,
* which attaches window.SupportForm (no nodeIntegration needed; `module` is undefined
* there); Node tests require('../src/support-form.js') and use module.exports.
* @module support-form
*/
(function (root, factory) {
if (typeof module === 'object' && module.exports) module.exports = factory();
else root.SupportForm = factory();
})(typeof self !== 'undefined' ? self : this, function () {
/**
* Minimum message length after trimming, in characters. The server enforces 20–5000;
* the client bounds catch both ends pre-flight with friendlier wording. Whitespace
* doesn't count toward the minimum.
* @type {number}
*/
const MIN_MESSAGE_CHARS = 20;
/** Maximum message length after trimming, in characters. @type {number} */
const MAX_MESSAGE_CHARS = 5000;
/**
* Pre-flight validation of the support message.
* @param {?string} raw Message text as typed; null/undefined treated as empty.
* @returns {?{title: string, message: string}} Null when sendable, otherwise the error
* to show instead of sending.
*/
function validateMessage(raw) {
const message = (raw || '').trim();
if (message.length < MIN_MESSAGE_CHARS) {
return {
title: 'Add a little more detail.',
message: 'Please describe the problem in at least a sentence or two so we can better assist you.',
};
}
if (message.length > MAX_MESSAGE_CHARS) {
return {
title: 'That message is too long to send.',
message: 'Please keep it under 5000 characters — if you pasted logs, trim them to the part that mentions the error.',
};
}
return null;
}
/**
* Map main's submitSupportRequest result to what the user sees.
* @param {?{ok: boolean, reason: string, status: number}} result Submission result
* from the main process.
* @returns {?{title: string, message: string}} Null on success (the caller shows the
* sent notice), otherwise the error to display.
*/
function resultMessage(result) {
if (result && result.ok) return null;
if (result && (result.reason === 'signed-out' || result.status === 401)) {
return { title: 'Support submission failed.', message: 'Your session has expired — please sign in again.' };
}
if (result && result.reason === 'network') {
return { title: 'Couldn’t reach the server.', message: 'Check your internet connection and try again.' };
}
if (result && result.status === 429) {
return { title: 'You’re sending messages too quickly.', message: 'Please wait a minute and try again.' };
}
return { title: 'Support submission failed.', message: 'Something went wrong on our end — please try again in a few minutes.' };
}
return { MIN_MESSAGE_CHARS, MAX_MESSAGE_CHARS, validateMessage, resultMessage };
});