diff --git a/apps/electron-backend/src/app/app.ts b/apps/electron-backend/src/app/app.ts index 7eae76a51..07e9d479c 100644 --- a/apps/electron-backend/src/app/app.ts +++ b/apps/electron-backend/src/app/app.ts @@ -1,4 +1,4 @@ -import { BrowserWindow, screen, shell } from 'electron'; +import { BrowserWindow, Menu, screen, shell } from 'electron'; import { join } from 'path'; import { environment } from '../environments/environment'; import { rendererAppName, rendererAppPort } from './constants'; @@ -115,6 +115,43 @@ export default class App { store.set(WINDOW_BOUNDS, App.mainWindow.getNormalBounds()); } }); + + // Enable context menu for input fields only + App.mainWindow.webContents.on('context-menu', (event, params) => { + const { isEditable, editFlags } = params; + + // Check if this is an editable field (input, textarea, contenteditable) + // editFlags.canPaste is a good indicator of an input field + if (isEditable && editFlags.canPaste) { + const menu = Menu.buildFromTemplate([ + { + label: 'Cut', + role: 'cut', + enabled: editFlags.canCut, + }, + { + label: 'Copy', + role: 'copy', + enabled: editFlags.canCopy, + }, + { + label: 'Paste', + role: 'paste', + enabled: editFlags.canPaste, + }, + { + type: 'separator', + }, + { + label: 'Select All', + role: 'selectAll', + enabled: editFlags.canSelectAll, + }, + ]); + + menu.popup(); + } + }); } private static loadMainWindow() { diff --git a/apps/web/src/app/home/video-player/video-player.component.ts b/apps/web/src/app/home/video-player/video-player.component.ts index 5ce337d7e..a7327012f 100644 --- a/apps/web/src/app/home/video-player/video-player.component.ts +++ b/apps/web/src/app/home/video-player/video-player.component.ts @@ -368,6 +368,10 @@ export class VideoPlayerComponent implements OnInit { */ @HostListener('document:keydown.i', ['$event']) handleInfoKeyPress(event: Event): void { + // Don't trigger hotkeys when user is typing in input fields + if (this.isTypingInInput(event)) { + return; + } // Prevent default behavior and show info overlay event.preventDefault(); this.toggleInfoOverlay(); @@ -380,6 +384,10 @@ export class VideoPlayerComponent implements OnInit { handleKeyPress(event: KeyboardEvent): void { // Only handle digit keys (0-9) if (event.key >= '0' && event.key <= '9') { + // Don't trigger hotkeys when user is typing in input fields + if (this.isTypingInInput(event)) { + return; + } event.preventDefault(); this.handleChannelNumberInput(event.key); } @@ -453,4 +461,17 @@ export class VideoPlayerComponent implements OnInit { this.channelNumberTimeout = undefined; } } + + /** + * Check if the user is currently typing in an input or textarea field + * @param event Keyboard event + * @returns true if the event target is an input or textarea element + */ + private isTypingInInput(event: Event): boolean { + const target = event.target; + return ( + target instanceof HTMLInputElement || + target instanceof HTMLTextAreaElement + ); + } } diff --git a/apps/web/src/styles.scss b/apps/web/src/styles.scss index 1ee747487..bf39f175d 100644 --- a/apps/web/src/styles.scss +++ b/apps/web/src/styles.scss @@ -23,6 +23,12 @@ html { font-family: Roboto, 'Helvetica Neue', sans-serif; } +// Re-enable context menu and text selection for input fields +input, +textarea { + user-select: text; +} + @media (display-mode: standalone) { body { overscroll-behavior-y: contain; diff --git a/libs/ui/components/src/lib/recent-playlists/playlist-item/playlist-item.component.scss b/libs/ui/components/src/lib/recent-playlists/playlist-item/playlist-item.component.scss index d6277ee91..bfb2026a0 100644 --- a/libs/ui/components/src/lib/recent-playlists/playlist-item/playlist-item.component.scss +++ b/libs/ui/components/src/lib/recent-playlists/playlist-item/playlist-item.component.scss @@ -26,13 +26,6 @@ mat-list-item { margin-top: 2px !important; } -// Light theme -@media (prefers-color-scheme: light) { - .meta { - color: rgba(0, 0, 0, 0.6); - } -} - .cdk-drag-preview { box-sizing: border-box; border-radius: 12px;