@involvex/youtube-music-cli 0.0.36 → 0.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [0.0.38](https://github.com/involvex/youtube-music-cli/compare/v0.0.36...v0.0.38) (2026-02-22)
2
+
3
+ ### Bug Fixes
4
+
5
+ - **search:** prevent 'q' key from triggering quit when typing in search bar ([32cd888](https://github.com/involvex/youtube-music-cli/commit/32cd888afcabc30d10988491da12c653cb5175d5))
6
+
1
7
  ## [0.0.36](https://github.com/involvex/youtube-music-cli/compare/v0.0.35...v0.0.36) (2026-02-22)
2
8
 
3
9
  ### Features
@@ -46,7 +46,7 @@ function SearchBar({ onInput, isActive = true }) {
46
46
  }
47
47
  }, [isActive, onInput]);
48
48
  useKeyBinding(['tab'], cycleType);
49
- useKeyBinding(['escape'], clearSearch);
49
+ useKeyBinding(['escape'], clearSearch, { bypassBlock: true });
50
50
  useKeyboardBlocker(isActive);
51
51
  return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.secondary, paddingX: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: theme.colors.dim, children: "Type: " }), searchTypes.map((type, index) => (_jsxs(Text, { color: navState.searchType === type
52
52
  ? theme.colors.primary
@@ -3,7 +3,9 @@
3
3
  * This uses a centralized manager to avoid multiple useInput calls and memory leaks.
4
4
  * Uses a ref-based approach to always call the latest handler without stale closures.
5
5
  */
6
- export declare function useKeyBinding(keys: readonly string[], handler: () => void): void;
6
+ export declare function useKeyBinding(keys: readonly string[], handler: () => void, options?: {
7
+ bypassBlock?: boolean;
8
+ }): void;
7
9
  /**
8
10
  * Global Keyboard Manager Component
9
11
  * This should be rendered once at the root of the app.
@@ -10,16 +10,20 @@ const registry = new Set();
10
10
  * This uses a centralized manager to avoid multiple useInput calls and memory leaks.
11
11
  * Uses a ref-based approach to always call the latest handler without stale closures.
12
12
  */
13
- export function useKeyBinding(keys, handler) {
13
+ export function useKeyBinding(keys, handler, options) {
14
14
  const handlerRef = useRef(handler);
15
15
  handlerRef.current = handler;
16
16
  useEffect(() => {
17
- const entry = { keys, handler: () => handlerRef.current() };
17
+ const entry = {
18
+ keys,
19
+ handler: () => handlerRef.current(),
20
+ bypassBlock: options?.bypassBlock,
21
+ };
18
22
  registry.add(entry);
19
23
  return () => {
20
24
  registry.delete(entry);
21
25
  };
22
- }, [keys]); // keys is the only dep; handlerRef is a stable ref
26
+ }, [keys, options?.bypassBlock]); // keys and bypassBlock are deps; handlerRef is a stable ref
23
27
  }
24
28
  /**
25
29
  * Global Keyboard Manager Component
@@ -30,7 +34,65 @@ export function KeyboardManager() {
30
34
  useInput((input, key) => {
31
35
  if (blockCount > 0) {
32
36
  // When keyboard input is blocked (e.g., within a focused text input),
33
- // we deliberately skip executing global shortcuts.
37
+ // check if any entry has bypassBlock flag and matches this key.
38
+ for (const entry of registry) {
39
+ if (entry.bypassBlock) {
40
+ for (const binding of entry.keys) {
41
+ const lowerBinding = binding.toLowerCase();
42
+ // Check for ESC key (most common bypass case)
43
+ if (lowerBinding === 'escape' && key.escape) {
44
+ entry.handler();
45
+ return;
46
+ }
47
+ // Handle other bypass keys
48
+ const isMatch = ((lowerBinding === 'return' || lowerBinding === 'enter') &&
49
+ key.return) ||
50
+ (lowerBinding === 'backspace' && key.backspace) ||
51
+ (lowerBinding === 'tab' && key.tab) ||
52
+ (lowerBinding === 'up' && key.upArrow) ||
53
+ (lowerBinding === 'down' && key.downArrow) ||
54
+ (lowerBinding === 'left' && key.leftArrow) ||
55
+ (lowerBinding === 'right' && key.rightArrow) ||
56
+ (lowerBinding === 'pageup' && key.pageUp) ||
57
+ (lowerBinding === 'pagedown' && key.pageDown) ||
58
+ (() => {
59
+ const parts = lowerBinding.split('+');
60
+ const hasCtrl = parts.includes('ctrl');
61
+ const hasMeta = parts.includes('meta') || parts.includes('alt');
62
+ const hasShift = parts.includes('shift');
63
+ const mainKey = parts[parts.length - 1];
64
+ if (hasCtrl && !key.ctrl)
65
+ return false;
66
+ if (hasMeta && !key.meta)
67
+ return false;
68
+ if (hasShift && !key.shift)
69
+ return false;
70
+ // Check arrow keys
71
+ if (mainKey === 'up' && key.upArrow)
72
+ return true;
73
+ if (mainKey === 'down' && key.downArrow)
74
+ return true;
75
+ if (mainKey === 'left' && key.leftArrow)
76
+ return true;
77
+ if (mainKey === 'right' && key.rightArrow)
78
+ return true;
79
+ // Handle '=' and '+'
80
+ if (mainKey === '=' && input === '=')
81
+ return true;
82
+ if (mainKey === '+' && input === '+')
83
+ return true;
84
+ if (mainKey === '+' && key.shift && input === '=')
85
+ return true;
86
+ return (input.toLowerCase() === mainKey && !key.ctrl && !key.meta);
87
+ })();
88
+ if (isMatch) {
89
+ entry.handler();
90
+ return;
91
+ }
92
+ }
93
+ }
94
+ }
95
+ // If no bypass handler matched, skip all global shortcuts
34
96
  return;
35
97
  }
36
98
  // Debug logging for key presses (helps diagnose binding issues)
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@involvex/youtube-music-cli",
3
- "version": "0.0.36",
3
+ "version": "0.0.38",
4
4
  "description": "- A Commandline music player for youtube-music",
5
5
  "repository": {
6
6
  "type": "git",