Skip to content

Commit 9d6c524

Browse files
committed
feat: add contact search to command bar (Spotlight-style)
Transform the command bar from a simple phone dialer into a full contact search bar. Users can now type a name to search the phonebook and local operators, navigate results with arrow keys, and call with Enter. - Search phonebook via API with 250ms debounce and stale-request cancellation - Local operator matching (name + extension) displayed first, deduped against phonebook results - Operator results show avatar and presence indicator - Keyboard navigation: ArrowUp/Down to select, Enter to call, Escape to close - Dynamic window resize via new COMMAND_BAR_RESIZE IPC event with full setBounds rect (avoids DPI issues on Windows) - Cache operators/avatars with 30s TTL to avoid redundant API calls - Memoize expensive computations (operator filtering, result merging) - Fix IPC listener leak: proper cleanup on effect re-run - Non-mutating mapContact for safer data handling
1 parent 3285e61 commit 9d6c524

8 files changed

Lines changed: 453 additions & 91 deletions

File tree

public/locales/en/translations.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@
936936
"download": "Download the update"
937937
},
938938
"CommandBar": {
939-
"Placeholder": "Enter a phone number...",
939+
"Placeholder": "Search contact or dial number...",
940940
"Call": "Call"
941941
},
942942
"Errors": {

public/locales/it/translations.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@
936936
"download": "Scarica l'aggiornamento"
937937
},
938938
"CommandBar": {
939-
"Placeholder": "Inserisci un numero di telefono...",
939+
"Placeholder": "Cerca contatto o componi numero...",
940940
"Call": "Chiama"
941941
},
942942
"Errors": {

src/main/classes/controllers/CommandBarController.ts

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,20 @@ export class CommandBarController {
4040
// Start grace period to ignore blur events during focus transition
4141
this.isShowingInProgress = true
4242

43-
// Restore original size if it was reset to [0,0]
44-
window.setBounds({
45-
width: this.originalSize.width,
46-
height: this.originalSize.height
47-
})
48-
4943
const cursorPoint = screen.getCursorScreenPoint()
5044
const currentDisplay = screen.getDisplayNearestPoint(cursorPoint)
5145
const { x, y, width, height } = currentDisplay.workArea
52-
const windowBounds = window.getBounds()
5346

54-
const centerX = x + Math.round((width - windowBounds.width) / 2)
47+
const centerX = x + Math.round((width - this.originalSize.width) / 2)
5548
const centerY = y + Math.round(height * 0.3)
5649

57-
window.setBounds({ x: centerX, y: centerY })
50+
// Always pass the full rect to setBounds to avoid DPI issues on Windows
51+
window.setBounds({
52+
x: centerX,
53+
y: centerY,
54+
width: this.originalSize.width,
55+
height: this.originalSize.height
56+
})
5857

5958
const isWindows = process.platform === 'win32'
6059

@@ -102,8 +101,6 @@ export class CommandBarController {
102101
const window = this.window.getWindow()
103102
if (window && this.isVisible) {
104103
this.isVisible = false
105-
// Reset size to [0,0] to avoid slowness/inconsistent state - same as PhoneIsland pattern
106-
window.setBounds({ width: 0, height: 0 })
107104

108105
if (isMac) {
109106
window.hide()
@@ -124,6 +121,24 @@ export class CommandBarController {
124121
}
125122
}
126123

124+
resize(size: { width: number, height: number }) {
125+
try {
126+
const window = this.window.getWindow()
127+
if (window && this.isVisible) {
128+
const bounds = window.getBounds()
129+
// Always pass the full rect to avoid DPI issues on Windows
130+
window.setBounds({
131+
x: bounds.x,
132+
y: bounds.y,
133+
width: size.width,
134+
height: size.height
135+
})
136+
}
137+
} catch (e) {
138+
Log.warning('error during resizing CommandBarWindow:', e)
139+
}
140+
}
141+
127142
toggle() {
128143
// Throttle toggle calls to prevent rapid open/close cycles
129144
const now = Date.now()

src/main/lib/ipcEvents.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,14 @@ export function registerIpcEvents() {
550550
}
551551
})
552552

553+
ipcMain.on(IPC_EVENTS.COMMAND_BAR_RESIZE, (_, size: { width: number, height: number }) => {
554+
try {
555+
CommandBarController.instance?.resize(size)
556+
} catch (e) {
557+
Log.error('COMMAND_BAR_RESIZE error', e)
558+
}
559+
})
560+
553561
ipcMain.on(IPC_EVENTS.CHANGE_COMMAND_BAR_SHORTCUT, async (_, combo) => {
554562
if (!isUserLoggedIn()) {
555563
disableCommandBarShortcuts()

src/renderer/public/locales/en/translations.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@
937937
"download": "Download the update"
938938
},
939939
"CommandBar": {
940-
"Placeholder": "Enter a phone number...",
940+
"Placeholder": "Search contact or dial number...",
941941
"Call": "Call"
942942
},
943943
"Errors": {

src/renderer/public/locales/it/translations.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@
937937
"download": "Scarica l'aggiornamento"
938938
},
939939
"CommandBar": {
940-
"Placeholder": "Inserisci un numero di telefono...",
940+
"Placeholder": "Cerca contatto o componi numero...",
941941
"Call": "Chiama"
942942
},
943943
"Errors": {

0 commit comments

Comments
 (0)