Copy the Chatwoot (v4.14.0) frontend runnable subset into frontend/ for customization: - app/javascript/ (Vue SPA: dashboard, widget, sdk, portal, superadmin) - app/views/ (ERB templates for vite-plugin-ruby entrypoint resolution) - app/helpers/, app/assets/ (Rails view helpers, static assets) - enterprise/ (Enterprise edition frontend overlay) - config/vite.json, vite.config.ts, bin/vite (Vite-Rails toolchain) - package.json, pnpm-lock.yaml, tailwind/postcss/eslint configs - Gemfile, Gemfile.lock (vite_rails gem for bin/vite binstub) Excluded Rails backend: controllers, models, services, jobs, mailers, policies, db, lib, spec, public, node_modules. Update references to the new frontend location: - .gitignore: exclude frontend build artifacts (node_modules, tmp, packs), keep frontend/bin/ and frontend/vendor/ via negation - backend/scripts/parity_frontend_smoke.sh: CHATWOOT_DIR default reference/chatwoot -> ../frontend - backend/scripts/parity_frontend_browser_smoke.mjs: same default update - AGENTS.md: add frontend section with Rails/Vite coupling notes - README: architecture tree includes frontend/
68 lines
2.0 KiB
JavaScript
68 lines
2.0 KiB
JavaScript
import { isApple } from './platform';
|
|
|
|
export const isEnter = e => {
|
|
return e.key === 'Enter';
|
|
};
|
|
|
|
export const isEscape = e => {
|
|
return e.key === 'Escape';
|
|
};
|
|
|
|
export const hasPressedShift = e => {
|
|
return e.shiftKey;
|
|
};
|
|
|
|
export const hasPressedCommand = e => {
|
|
return e.metaKey;
|
|
};
|
|
|
|
// True when the platform's "command" modifier is held: Cmd (metaKey) on
|
|
// Apple platforms (macOS, iOS/iPadOS hardware keyboards), Ctrl (ctrlKey)
|
|
// elsewhere. Mirrors the `$mod` convention used by tinykeys and
|
|
// prosemirror-keymap so the editor and the app agree on what counts as the
|
|
// send modifier.
|
|
export const hasPressedMod = e => Boolean(isApple() ? e.metaKey : e.ctrlKey);
|
|
|
|
export const hasPressedEnterAndNotCmdOrShift = e => {
|
|
return isEnter(e) && !hasPressedMod(e) && !hasPressedShift(e);
|
|
};
|
|
|
|
// Detects the platform-aware "send" shortcut: Cmd+Enter on Apple platforms,
|
|
// Ctrl+Enter on Windows/Linux.
|
|
export const hasPressedCommandAndEnter = e => hasPressedMod(e) && isEnter(e);
|
|
|
|
// If layout is QWERTZ then we add the Shift+keysToModify to fix an known issue
|
|
// https://github.com/chatwoot/chatwoot/issues/9492
|
|
export const keysToModifyInQWERTZ = new Set(['Alt+KeyP', 'Alt+KeyL']);
|
|
|
|
export const LAYOUT_QWERTY = 'QWERTY';
|
|
export const LAYOUT_QWERTZ = 'QWERTZ';
|
|
export const LAYOUT_AZERTY = 'AZERTY';
|
|
|
|
/**
|
|
* Determines whether the active element is typeable.
|
|
*
|
|
* @param {KeyboardEvent} e - The keyboard event object.
|
|
* @returns {boolean} `true` if the active element is typeable, `false` otherwise.
|
|
*
|
|
* @example
|
|
* document.addEventListener('keydown', e => {
|
|
* if (isActiveElementTypeable(e)) {
|
|
* handleTypeableElement(e);
|
|
* }
|
|
* });
|
|
*/
|
|
export const isActiveElementTypeable = e => {
|
|
/** @type {HTMLElement | null} */
|
|
// @ts-ignore
|
|
const activeElement = e.target || document.activeElement;
|
|
|
|
return !!(
|
|
activeElement?.tagName === 'INPUT' ||
|
|
activeElement?.tagName === 'NINJA-KEYS' ||
|
|
activeElement?.tagName === 'TEXTAREA' ||
|
|
activeElement?.contentEditable === 'true' ||
|
|
activeElement?.className?.includes('ProseMirror')
|
|
);
|
|
};
|