From 0dfb436de044189ed12f82762f3dc56daaa2d576 Mon Sep 17 00:00:00 2001 From: therockerline Date: Mon, 12 May 2025 12:47:52 +0200 Subject: [PATCH 01/11] feat: add support for displaying additional phone numbers in search results --- public/locales/en/translations.json | 4 ++- public/locales/it/translations.json | 4 ++- .../public/locales/en/translations.json | 4 ++- .../public/locales/it/translations.json | 4 ++- .../BaseModule/ContactNameAndAction.tsx | 4 ++- .../NethVoice/SearchResults/SearchNumber.tsx | 26 ++++++++++++-- .../SearchResults/SearchNumberBox.tsx | 8 ++++- .../SearchResults/SearchNumberDetail.tsx | 36 +++++++++++++++++++ 8 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx diff --git a/public/locales/en/translations.json b/public/locales/en/translations.json index dd5f1d85..f8645d23 100644 --- a/public/locales/en/translations.json +++ b/public/locales/en/translations.json @@ -82,7 +82,9 @@ "Screen share dialog description": "This application requires permission to record the screen.\n\nClick 'Open Settings' and then select 'Privacy & Security' then 'Screen & System Audio Recording' from the list and enable the permission for 'NethLink'.", "Cancel button": "Cancel", "Open settings button": "Open Settings", - "Shortcut": "Define a keyboard shortcut" + "Shortcut": "Define a keyboard shortcut", + "PlusOther_one": "+ {{count}} other", + "PlusOther_other": "+ {{count}} others" }, "Login": { "Welcome": "Welcome", diff --git a/public/locales/it/translations.json b/public/locales/it/translations.json index e8807552..2ddf9df8 100644 --- a/public/locales/it/translations.json +++ b/public/locales/it/translations.json @@ -82,7 +82,9 @@ "Screen share dialog description": "Questa applicazione richiede il permesso di registrare lo schermo.\n\nClicca su 'Apri Impostazioni', poi seleziona 'Privacy & Sicurezza' poi 'Registrazione Schermo e Audio di Sistema' dalla lista e abilita il permesso per 'NethLink'.", "Cancel button": "Annulla", "Open settings button": "Apri Impostazioni", - "Shortcut": "Scegli una combinazione di tasti" + "Shortcut": "Scegli una combinazione di tasti", + "PlusOther_one": "+ {{count}} altro", + "PlusOther_other": "+ {{count}} altri" }, "Login": { "Welcome": "Benvenuto", diff --git a/src/renderer/public/locales/en/translations.json b/src/renderer/public/locales/en/translations.json index dd5f1d85..f8645d23 100644 --- a/src/renderer/public/locales/en/translations.json +++ b/src/renderer/public/locales/en/translations.json @@ -82,7 +82,9 @@ "Screen share dialog description": "This application requires permission to record the screen.\n\nClick 'Open Settings' and then select 'Privacy & Security' then 'Screen & System Audio Recording' from the list and enable the permission for 'NethLink'.", "Cancel button": "Cancel", "Open settings button": "Open Settings", - "Shortcut": "Define a keyboard shortcut" + "Shortcut": "Define a keyboard shortcut", + "PlusOther_one": "+ {{count}} other", + "PlusOther_other": "+ {{count}} others" }, "Login": { "Welcome": "Welcome", diff --git a/src/renderer/public/locales/it/translations.json b/src/renderer/public/locales/it/translations.json index e8807552..2ddf9df8 100644 --- a/src/renderer/public/locales/it/translations.json +++ b/src/renderer/public/locales/it/translations.json @@ -82,7 +82,9 @@ "Screen share dialog description": "Questa applicazione richiede il permesso di registrare lo schermo.\n\nClicca su 'Apri Impostazioni', poi seleziona 'Privacy & Sicurezza' poi 'Registrazione Schermo e Audio di Sistema' dalla lista e abilita il permesso per 'NethLink'.", "Cancel button": "Annulla", "Open settings button": "Apri Impostazioni", - "Shortcut": "Scegli una combinazione di tasti" + "Shortcut": "Scegli una combinazione di tasti", + "PlusOther_one": "+ {{count}} altro", + "PlusOther_other": "+ {{count}} altri" }, "Login": { "Welcome": "Benvenuto", diff --git a/src/renderer/src/components/Modules/NethVoice/BaseModule/ContactNameAndAction.tsx b/src/renderer/src/components/Modules/NethVoice/BaseModule/ContactNameAndAction.tsx index 31e263e4..601e2eab 100644 --- a/src/renderer/src/components/Modules/NethVoice/BaseModule/ContactNameAndAction.tsx +++ b/src/renderer/src/components/Modules/NethVoice/BaseModule/ContactNameAndAction.tsx @@ -16,6 +16,7 @@ export const ContactNameAndActions = ({ number, isHighlight, displayedNumber, + otherNumber, avatarDim, username, isFavourite, @@ -25,6 +26,7 @@ export const ContactNameAndActions = ({ number: string isHighlight: boolean displayedNumber: string | ReactNode[] + otherNumber?: string avatarDim: 'small' | 'base' | 'extra_small' | 'large' | 'extra_large' username: string | undefined isFavourite: boolean @@ -110,7 +112,7 @@ export const ContactNameAndActions = ({ displayedNumber !== '' && displayedNumber !== null && (!Array.isArray(displayedNumber) || displayedNumber.length > 0) - ? displayedNumber + ? {displayedNumber} {otherNumber} : '-'} diff --git a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumber.tsx b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumber.tsx index b583b205..b49db19e 100644 --- a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumber.tsx +++ b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumber.tsx @@ -9,13 +9,15 @@ import { usePhoneIslandEventHandler } from '@renderer/hooks/usePhoneIslandEventH import { ContactNameAndActions } from '@renderer/components/Modules/NethVoice/BaseModule/ContactNameAndAction' import { useFavouriteModule } from '../Speeddials/hook/useFavouriteModule' import { debouncer } from '@shared/utils/utils' +import { ClassNames } from '@renderer/utils' export interface SearchNumberProps { user: SearchData - className?: string + className?: string, + onClick?: (user: SearchData) => void } -export function SearchNumber({ user, className }: SearchNumberProps) { +export function SearchNumber({ user, className, onClick }: SearchNumberProps) { const phoneBookModule = usePhonebookSearchModule() const { callNumber } = usePhoneIslandEventHandler() const [searchText] = phoneBookModule.searchTextState @@ -23,6 +25,12 @@ export function SearchNumber({ user, className }: SearchNumberProps) { const { isCallsEnabled } = useAccount() const { isSearchAlsoAFavourite } = useFavouriteModule() + + const otherNumbers = [ + user.workphone, + user.homephone, + ].filter(p => p) + const getUsernameFromPhoneNumber = (number: string) => { return user.type !== 'extension' ? operators?.extensions[number]?.username : undefined } @@ -78,12 +86,24 @@ export function SearchNumber({ user, className }: SearchNumberProps) { return (
-
+
{ + if (onClick) { + e.stopPropagation() + e.preventDefault() + onClick(user) + } + }} + > 0 ? t('Common.PlusOther', { count: otherNumbers.length }) as string : ''} isHighlight={true} username={username} isFavourite={false} diff --git a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberBox.tsx b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberBox.tsx index cd55afc5..a1027c78 100644 --- a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberBox.tsx +++ b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberBox.tsx @@ -147,7 +147,13 @@ export function SearchNumberBox({ searchResult, showContactForm }: SearchNumberB { filteredPhoneNumbers.length > 0 ? filteredPhoneNumbers.map((user, index) => ( - + { + console.log(user) + }} + /> )) : } diff --git a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx new file mode 100644 index 00000000..cd30076f --- /dev/null +++ b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx @@ -0,0 +1,36 @@ +import { + faPhone as CallIcon, + faUserPlus as AddUserIcon, + faSearch as EmptySearchIcon +} from '@fortawesome/free-solid-svg-icons' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { SearchNumber } from './SearchNumber' +import { useEffect, useState } from 'react' +import { BaseAccountData, SearchData } from '@shared/types' +import { t } from 'i18next' +import { useAccount } from '@renderer/hooks/useAccount' +import { cloneDeep } from 'lodash' +import { cleanRegex, getIsPhoneNumber, sortByProperty } from '@renderer/lib/utils' +import { useNethlinkData, useSharedState } from '@renderer/store' +import { usePhonebookSearchModule } from './hook/usePhoneBookSearchModule' +import { usePhoneIslandEventHandler } from '@renderer/hooks/usePhoneIslandEventHandler' +import { Scrollable } from '@renderer/components/Scrollable' +import { EmptyList } from '@renderer/components/EmptyList' +import { debouncer } from '@shared/utils/utils' + +interface SearchNumberBoxProps { + contact: SearchData +} +export function SearchNumberBox({ contact }: SearchNumberBoxProps) { + + return ( +
+
+ +
+ + + +
+ ) +} From 2c502dc20f7eb35d603ce6912dad1ffe87cde12d Mon Sep 17 00:00:00 2001 From: therockerline Date: Mon, 12 May 2025 16:28:47 +0200 Subject: [PATCH 02/11] feat: update SearchNumberDetails page with contact info and actions --- src/renderer/src/components/ModuleTitle.tsx | 15 +- .../Modules/NethVoice/BaseModule/Sidebar.tsx | 2 +- .../SearchResults/PhoneBookSearchModule.tsx | 12 ++ .../NethVoice/SearchResults/SearchNumber.tsx | 4 +- .../SearchResults/SearchNumberBox.tsx | 7 +- .../SearchResults/SearchNumberDetail.tsx | 168 +++++++++++++++--- 6 files changed, 171 insertions(+), 37 deletions(-) diff --git a/src/renderer/src/components/ModuleTitle.tsx b/src/renderer/src/components/ModuleTitle.tsx index e6bd1be6..9d11b3ac 100644 --- a/src/renderer/src/components/ModuleTitle.tsx +++ b/src/renderer/src/components/ModuleTitle.tsx @@ -3,13 +3,15 @@ import { Button } from "./Nethesis" import { IconProp } from "@fortawesome/fontawesome-svg-core" import { DefaultTFuncReturn } from "i18next" import { ReactNode } from "react" +import { ClassNames } from "@renderer/utils" export interface ModuleTitleProps { - title: string | DefaultTFuncReturn, + title?: string | DefaultTFuncReturn | ReactNode, action?: () => void, actionText?: string | DefaultTFuncReturn, actionIcon?: IconProp - actionComponent?: ReactNode + actionComponent?: ReactNode, + className?: string } export const ModuleTitle = ({ @@ -17,15 +19,16 @@ export const ModuleTitle = ({ action, actionText, actionIcon, - actionComponent + actionComponent, + className }: ModuleTitleProps) => { return (
-
-

+
+ {title &&

{title} -

+

} {action && (
) } From be625f5e160a2f6f2e9b783af8222b342019c3fe Mon Sep 17 00:00:00 2001 From: therockerline Date: Mon, 12 May 2025 18:15:40 +0200 Subject: [PATCH 04/11] fix: replace call with clipboard copy; update contact details display --- src/main/lib/ipcEvents.ts | 4 ++ src/preload/index.ts | 2 + .../NethVoice/SearchResults/SearchNumber.tsx | 3 +- .../SearchResults/SearchNumberDetail.tsx | 69 ++++++++----------- src/shared/constants.ts | 3 +- 5 files changed, 40 insertions(+), 41 deletions(-) diff --git a/src/main/lib/ipcEvents.ts b/src/main/lib/ipcEvents.ts index 09d59d14..6c5214dc 100644 --- a/src/main/lib/ipcEvents.ts +++ b/src/main/lib/ipcEvents.ts @@ -216,6 +216,10 @@ export function registerIpcEvents() { shell.openExternal(join(path)) }) + ipcMain.on(IPC_EVENTS.COPY_TO_CLIPBOARD, async (_, text) => { + clipboard.writeText(text) + }) + ipcMain.on(IPC_EVENTS.PHONE_ISLAND_RESIZE, (_, size) => { PhoneIslandController.instance.resize(size) }) diff --git a/src/preload/index.ts b/src/preload/index.ts index d207406a..af4031cc 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -40,6 +40,7 @@ export interface IElectronAPI { exitNethLink(): void hidePhoneIsland(): void showPhoneIsland(size: Size): void + copyToClipboard(text: string): void } @@ -98,6 +99,7 @@ const api: IElectronAPI = { exitNethLink: setEmitter(IPC_EVENTS.CLOSE_NETH_LINK), hidePhoneIsland: setEmitter(IPC_EVENTS.HIDE_PHONE_ISLAND), showPhoneIsland: setEmitter(IPC_EVENTS.SHOW_PHONE_ISLAND), + copyToClipboard: setEmitter(IPC_EVENTS.COPY_TO_CLIPBOARD), //LISTENERS - receive data async onUpdateAppNotification: addListener(IPC_EVENTS.UPDATE_APP_NOTIFICATION), diff --git a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumber.tsx b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumber.tsx index 3076dd41..7e890daa 100644 --- a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumber.tsx +++ b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumber.tsx @@ -27,6 +27,7 @@ export function SearchNumber({ user, className, onClick }: SearchNumberProps) { const otherNumbers = [ + user.cellphone, user.workphone, user.homephone, ].filter(p => p) @@ -97,7 +98,7 @@ export function SearchNumber({ user, className, onClick }: SearchNumberProps) { contact={user} number={phoneNumber} displayedNumber={highlightedNumber} - otherNumber={otherNumbers.length > 0 ? t('Common.PlusOther', { count: otherNumbers.length }) as string : ''} + otherNumber={otherNumbers.length > 1 ? t('Common.PlusOther', { count: otherNumbers.length - 1 }) as string : ''} isHighlight={true} username={username} isFavourite={false} diff --git a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx index 04ee1b3c..a4261ec4 100644 --- a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx +++ b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx @@ -17,7 +17,8 @@ import { ClassNames } from '@renderer/utils' import { ModuleTitle } from '@renderer/components/ModuleTitle' import { ReactNode } from 'react' import { IconProp } from '@fortawesome/fontawesome-svg-core' -import { CustomThemedTooltip } from '@renderer/components/Nethesis/CurstomThemedTooltip' +import { Tooltip } from 'react-tooltip' + interface SearchNumberBoxProps { contactDetail?: { contact: SearchData, @@ -54,25 +55,14 @@ export function SearchNumberDetail({ contactDetail, onBack }: SearchNumberBoxPro
- - - {primaryNumber || ''} - - - {contact.homephone} - - - {contact.cellphone} - - - {contact.workphone} - - - {contact.homeemail} - - - {contact.company} - + + {/* {primaryNumber || ''} */} + {contact.homephone} + {contact.cellphone} + {contact.workphone} + {contact.homeemail} + {contact.workemail} + {contact.company}
@@ -104,7 +94,7 @@ const ContactVisibility = ({ isPublic }: { isPublic: boolean }) => {
} -const ContactDetail = ({ children, label, icon }: { label: string | DefaultTFuncReturn, icon: IconProp, children: ReactNode }) => { +const ContactDetail = ({ children, label, icon, copy }: { label: string | DefaultTFuncReturn, icon: IconProp, children: string, copy?: boolean }) => { return
- {children} - {typeof children === 'string' && - } + {copy ? {children} : (children || '-')} + +
} -const LinkedValue = ({ children, type, className }: { className?: string, children: string, type: 'phone' | 'mail' }) => { - if (!children) return <> +const CopyValue = ({ children, className }: { className?: string, children: string }) => { + if (!children) return <>- const onClick = () => { - const url = (type === 'phone' ? 'callto://' : 'mailto://') + `${children.replace(/ /g, '')}` - window.api.openExternalPage(url); + window.api.copyToClipboard(children) } return
{children} @@ -150,7 +141,7 @@ const LinkedValue = ({ children, type, className }: { className?: string, childr className="text-base" icon={CopyIcon} /> - +
-} \ No newline at end of file +} diff --git a/src/shared/constants.ts b/src/shared/constants.ts index 7cb87e04..e984f2cd 100644 --- a/src/shared/constants.ts +++ b/src/shared/constants.ts @@ -90,7 +90,8 @@ export enum IPC_EVENTS { FULLSCREEN_EXIT = "FULLSCREEN_EXIT", SCREEN_SHARE_INIT = "SCREEN_SHARE_INIT", SCREEN_SHARE_SOURCES = "SCREEN_SHARE_SOURCES", - CHANGE_SHORTCUT = 'CHANGE_SHORTCUT' + CHANGE_SHORTCUT = 'CHANGE_SHORTCUT', + COPY_TO_CLIPBOARD = "COPY_TO_CLIPBOARD" } //PHONE ISLAND EVENTS From 6ab41c49f5bd39814e9f166c41f097281b6e6d8a Mon Sep 17 00:00:00 2001 From: therockerline Date: Tue, 13 May 2025 15:22:40 +0200 Subject: [PATCH 05/11] feat: add translation entries for copy actions; fix: make other numbers a set fix: show tooltip for copy and truncated elements --- public/locales/en/translations.json | 4 +- public/locales/it/translations.json | 4 +- src/main/lib/ipcEvents.ts | 11 +- .../public/locales/en/translations.json | 4 +- .../public/locales/it/translations.json | 4 +- .../SearchResults/PhoneBookSearchModule.tsx | 5 +- .../NethVoice/SearchResults/SearchNumber.tsx | 7 +- .../SearchResults/SearchNumberBox.tsx | 6 +- .../SearchResults/SearchNumberDetail.tsx | 137 ++++++++++++------ src/renderer/src/components/NumberCaller.tsx | 1 + 10 files changed, 127 insertions(+), 56 deletions(-) diff --git a/public/locales/en/translations.json b/public/locales/en/translations.json index f8645d23..24187630 100644 --- a/public/locales/en/translations.json +++ b/public/locales/en/translations.json @@ -84,7 +84,9 @@ "Open settings button": "Open Settings", "Shortcut": "Define a keyboard shortcut", "PlusOther_one": "+ {{count}} other", - "PlusOther_other": "+ {{count}} others" + "PlusOther_other": "+ {{count}} others", + "Copy": "Copy", + "Copied": "Copied" }, "Login": { "Welcome": "Welcome", diff --git a/public/locales/it/translations.json b/public/locales/it/translations.json index 2ddf9df8..c4644779 100644 --- a/public/locales/it/translations.json +++ b/public/locales/it/translations.json @@ -84,7 +84,9 @@ "Open settings button": "Apri Impostazioni", "Shortcut": "Scegli una combinazione di tasti", "PlusOther_one": "+ {{count}} altro", - "PlusOther_other": "+ {{count}} altri" + "PlusOther_other": "+ {{count}} altri", + "Copy": "Copia", + "Copied": "Copiato" }, "Login": { "Welcome": "Benvenuto", diff --git a/src/main/lib/ipcEvents.ts b/src/main/lib/ipcEvents.ts index 6c5214dc..148c9016 100644 --- a/src/main/lib/ipcEvents.ts +++ b/src/main/lib/ipcEvents.ts @@ -9,7 +9,7 @@ import { Log } from '@shared/utils/logger' import { NethLinkController } from '@/classes/controllers/NethLinkController' import { AppController } from '@/classes/controllers/AppController' import { store } from './mainStore' -import { debouncer, getAccountUID, getPageFromQuery } from '@shared/utils/utils' +import { debouncer, getAccountUID, getPageFromQuery, isDev } from '@shared/utils/utils' import { NetworkController } from '@/classes/controllers/NetworkController' import { useLogin } from '@shared/useLogin' import { PhoneIslandWindow } from '@/classes/windows' @@ -212,8 +212,13 @@ export function registerIpcEvents() { shell.openExternal(join('https://' + account!.host, path)) }) - ipcMain.on(IPC_EVENTS.OPEN_EXTERNAL_PAGE, async (_, path) => { - shell.openExternal(join(path)) + ipcMain.on(IPC_EVENTS.OPEN_EXTERNAL_PAGE, async (event, path) => { + if (isDev()) { + const window = BrowserWindow.fromWebContents(event.sender); + window?.loadURL(path) + } else { + shell.openExternal(path) + } }) ipcMain.on(IPC_EVENTS.COPY_TO_CLIPBOARD, async (_, text) => { diff --git a/src/renderer/public/locales/en/translations.json b/src/renderer/public/locales/en/translations.json index f8645d23..24187630 100644 --- a/src/renderer/public/locales/en/translations.json +++ b/src/renderer/public/locales/en/translations.json @@ -84,7 +84,9 @@ "Open settings button": "Open Settings", "Shortcut": "Define a keyboard shortcut", "PlusOther_one": "+ {{count}} other", - "PlusOther_other": "+ {{count}} others" + "PlusOther_other": "+ {{count}} others", + "Copy": "Copy", + "Copied": "Copied" }, "Login": { "Welcome": "Welcome", diff --git a/src/renderer/public/locales/it/translations.json b/src/renderer/public/locales/it/translations.json index 2ddf9df8..c4644779 100644 --- a/src/renderer/public/locales/it/translations.json +++ b/src/renderer/public/locales/it/translations.json @@ -84,7 +84,9 @@ "Open settings button": "Apri Impostazioni", "Shortcut": "Scegli una combinazione di tasti", "PlusOther_one": "+ {{count}} altro", - "PlusOther_other": "+ {{count}} altri" + "PlusOther_other": "+ {{count}} altri", + "Copy": "Copia", + "Copied": "Copiato" }, "Login": { "Welcome": "Benvenuto", diff --git a/src/renderer/src/components/Modules/NethVoice/SearchResults/PhoneBookSearchModule.tsx b/src/renderer/src/components/Modules/NethVoice/SearchResults/PhoneBookSearchModule.tsx index 542327db..55b368af 100644 --- a/src/renderer/src/components/Modules/NethVoice/SearchResults/PhoneBookSearchModule.tsx +++ b/src/renderer/src/components/Modules/NethVoice/SearchResults/PhoneBookSearchModule.tsx @@ -5,6 +5,7 @@ import { usePhonebookSearchModule } from "./hook/usePhoneBookSearchModule" import { SearchData } from "@shared/types" import { useNethlinkData } from "@renderer/store" import { SearchNumberDetail } from "./SearchNumberDetail" +import classNames from "classnames" export const PhoneBookSearchModule = () => { @@ -36,7 +37,9 @@ export const PhoneBookSearchModule = () => { return ( <> - { setShowAddContactModule(true) setShowPhonebookSearchModule(false) diff --git a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumber.tsx b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumber.tsx index 7e890daa..842e830d 100644 --- a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumber.tsx +++ b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumber.tsx @@ -30,7 +30,12 @@ export function SearchNumber({ user, className, onClick }: SearchNumberProps) { user.cellphone, user.workphone, user.homephone, - ].filter(p => p) + ].reduce((p, c) => { + if (c && !p.includes(c)) { + p.push(c) + } + return p + }, [] as string[]) const getUsernameFromPhoneNumber = (number: string) => { return user.type !== 'extension' ? operators?.extensions[number]?.username : undefined diff --git a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberBox.tsx b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberBox.tsx index 5b723d28..08162a3a 100644 --- a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberBox.tsx +++ b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberBox.tsx @@ -17,13 +17,15 @@ import { usePhoneIslandEventHandler } from '@renderer/hooks/usePhoneIslandEventH import { Scrollable } from '@renderer/components/Scrollable' import { EmptyList } from '@renderer/components/EmptyList' import { debouncer } from '@shared/utils/utils' +import classNames from 'classnames' interface SearchNumberBoxProps { searchResult: SearchData[] | undefined showContactForm: () => void showContactDetail: (contact: SearchData, primaryNumber: string | null) => void + className?: string } -export function SearchNumberBox({ searchResult, showContactForm, showContactDetail }: SearchNumberBoxProps) { +export function SearchNumberBox({ searchResult, showContactForm, showContactDetail, className }: SearchNumberBoxProps) { const { callNumber } = usePhoneIslandEventHandler() const phoneBookModule = usePhonebookSearchModule() const [searchText] = phoneBookModule.searchTextState @@ -103,7 +105,7 @@ export function SearchNumberBox({ searchResult, showContactForm, showContactDeta searchText && isCallsEnabled && getIsPhoneNumber(searchText) && searchText.length > 1 return ( -
+
+
{contact &&
{/* {primaryNumber || ''} */} - {contact.homephone} - {contact.cellphone} - {contact.workphone} - {contact.homeemail} - {contact.workemail} + {contact.homephone} + {contact.cellphone} + {contact.workphone} + {contact.homeemail} + {contact.workemail} {contact.company}
@@ -94,7 +97,35 @@ const ContactVisibility = ({ isPublic }: { isPublic: boolean }) => {
} -const ContactDetail = ({ children, label, icon, copy }: { label: string | DefaultTFuncReturn, icon: IconProp, children: string, copy?: boolean }) => { +const ContactDetail = ({ children, label, icon, copy, protocol }: { label: string | DefaultTFuncReturn, icon: IconProp, children: string, copy?: boolean, protocol?: 'mailto' | 'callto' }) => { + + const { isCallsEnabled } = useAccount() + const [copied, setCopied] = useState(false) + const copiedInterval = useRef() + + const removeInterval = () => { + if (copiedInterval.current) { + clearTimeout(copiedInterval.current) + } + } + const onClick = () => { + window.api.copyToClipboard(children) + setCopied(true) + copiedInterval.current = setTimeout(() => { + setCopied(false) + removeInterval() + }, 2000) + } + + const runProtocol = () => { + if (protocol === 'callto' && !isCallsEnabled) return; + const url = `${protocol}://${('' + children).replace(/ /g, '')}` + window.api.openExternalPage(url); + } + + const linkClassName = 'text-textBlueLight dark:text-textBlueDark cursor-pointer rounded-md font-normal dark:focus:outline-none dark:focus:ring-2 focus:outline-none focus:ring-2 dark:ring-offset-1 ring-offset-1 dark:ring-offset-slate-900 ring-offset-slate-50 focus:ring-primaryRing dark:focus:ring-primaryRingDark hover:underline' + + return
{label}
-
- {copy ? {children} : (children || '-')} - +
+ + {children} + + {children && copy &&
+ +
+
+ }
-
-} - -const CopyValue = ({ children, className }: { className?: string, children: string }) => { - if (!children) return <>- - - const onClick = () => { - window.api.copyToClipboard(children) - } - - return
- - {children} - - + + -
- } + diff --git a/src/renderer/src/components/NumberCaller.tsx b/src/renderer/src/components/NumberCaller.tsx index 3a3b20d8..3c7a5c3d 100644 --- a/src/renderer/src/components/NumberCaller.tsx +++ b/src/renderer/src/components/NumberCaller.tsx @@ -29,6 +29,7 @@ export const NumberCaller = ({ 'dark:text-textBlueDark text-textBlueLight', 'cursor-pointer dark:focus:outline-none dark:focus:ring-2 focus:outline-none focus:ring-2 dark:ring-offset-1 ring-offset-1 dark:ring-offset-slate-900 ring-offset-slate-50 focus:ring-primaryRing dark:focus:ring-primaryRingDark rounded-md')} {...args} + onClick={onClick} >
Date: Tue, 13 May 2025 15:36:24 +0200 Subject: [PATCH 06/11] fix: normalized result path --- src/main/lib/ipcEvents.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/lib/ipcEvents.ts b/src/main/lib/ipcEvents.ts index 148c9016..a1375c41 100644 --- a/src/main/lib/ipcEvents.ts +++ b/src/main/lib/ipcEvents.ts @@ -215,9 +215,9 @@ export function registerIpcEvents() { ipcMain.on(IPC_EVENTS.OPEN_EXTERNAL_PAGE, async (event, path) => { if (isDev()) { const window = BrowserWindow.fromWebContents(event.sender); - window?.loadURL(path) + window?.loadURL(join(path)) } else { - shell.openExternal(path) + shell.openExternal(join(path)) } }) From 8b20840f6cd5905db52599ebb1c622f5534e93d2 Mon Sep 17 00:00:00 2001 From: therockerline Date: Tue, 13 May 2025 15:49:21 +0200 Subject: [PATCH 07/11] fix: removed slash ok mailto protocol --- .../Modules/NethVoice/SearchResults/SearchNumberDetail.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx index 25ea9fda..b6304084 100644 --- a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx +++ b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx @@ -119,7 +119,7 @@ const ContactDetail = ({ children, label, icon, copy, protocol }: { label: strin const runProtocol = () => { if (protocol === 'callto' && !isCallsEnabled) return; - const url = `${protocol}://${('' + children).replace(/ /g, '')}` + const url = `${protocol}:${protocol === 'callto' ? '//' : ''}${('' + children).replace(/ /g, '')}` window.api.openExternalPage(url); } From ab705523402cd3b3dd6b4327d2bf9ee390144baf Mon Sep 17 00:00:00 2001 From: therockerline Date: Wed, 14 May 2025 17:01:03 +0200 Subject: [PATCH 08/11] fix: refactor click handlers and improve styling for contact details --- .../SearchResults/SearchNumberDetail.tsx | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx index b6304084..5ebb3fd2 100644 --- a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx +++ b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx @@ -38,22 +38,24 @@ export function SearchNumberDetail({ contactDetail, onBack }: SearchNumberBoxPro { - debouncer('onDetailBack', () => { - onBack() - }, 250) - }} + className={`flex gap-1 pt-[10px] pl-1 pr-8 pb-[10px] items-center `} + > { + debouncer('onDetailBack', () => { + onBack() + }, 250) + }} />

{contact?.displayName}

} + />
@@ -88,7 +90,7 @@ const ContactVisibility = ({ isPublic }: { isPublic: boolean }) => {
{isPublic ? t("Phonebook.Public") : t("Phonebook.Only me")} @@ -129,13 +131,13 @@ const ContactDetail = ({ children, label, icon, copy, protocol }: { label: strin return
{label}
- - {children} + {children || '-'} {children && copy &&
@@ -160,7 +162,7 @@ const ContactDetail = ({ children, label, icon, copy, protocol }: { label: strin data-tooltip-id={`tooltip-copy-${label}`} data-tooltip-content={t('Common.Copy')} /> -
From e75b5ef68a4c2e834f8830a090c843cf047863a9 Mon Sep 17 00:00:00 2001 From: therockerline Date: Thu, 15 May 2025 11:06:56 +0200 Subject: [PATCH 09/11] fix: update the text size of ModuleTitle and remove the back functionality from the title and leave it only on the back icon --- src/renderer/src/components/ModuleTitle.tsx | 4 +-- .../SearchResults/SearchNumberDetail.tsx | 31 ++++++++----------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/renderer/src/components/ModuleTitle.tsx b/src/renderer/src/components/ModuleTitle.tsx index 9d11b3ac..580be42f 100644 --- a/src/renderer/src/components/ModuleTitle.tsx +++ b/src/renderer/src/components/ModuleTitle.tsx @@ -26,7 +26,7 @@ export const ModuleTitle = ({ return (
- {title &&

+ {title &&

{title}

} {action && ( @@ -40,7 +40,7 @@ export const ModuleTitle = ({ className="text-base dark:text-textBlueDark text-textBlueLight" icon={actionIcon} />} - {actionText &&

+ {actionText &&

{actionText}

} diff --git a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx index 5ebb3fd2..655dc214 100644 --- a/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx +++ b/src/renderer/src/components/Modules/NethVoice/SearchResults/SearchNumberDetail.tsx @@ -36,26 +36,21 @@ export function SearchNumberDetail({ contactDetail, onBack }: SearchNumberBoxPro {contact &&
- { - debouncer('onDetailBack', () => { - onBack() - }, 250) - }} - /> -

- {contact?.displayName} -

-
+ contact?.displayName + } + actionComponent={ + { + debouncer('onDetailBack', () => { + onBack() + }, 250) + }} + /> } - />
From f6f38a98e5a67d416a43b72163b4009145ba8f77 Mon Sep 17 00:00:00 2001 From: therockerline Date: Fri, 16 May 2025 13:10:01 +0200 Subject: [PATCH 10/11] fix: fixed the display name logic for contacts --- .../NethVoice/BaseModule/ContactNameAndAction.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/renderer/src/components/Modules/NethVoice/BaseModule/ContactNameAndAction.tsx b/src/renderer/src/components/Modules/NethVoice/BaseModule/ContactNameAndAction.tsx index f2663afb..3f8528c5 100644 --- a/src/renderer/src/components/Modules/NethVoice/BaseModule/ContactNameAndAction.tsx +++ b/src/renderer/src/components/Modules/NethVoice/BaseModule/ContactNameAndAction.tsx @@ -49,6 +49,14 @@ export const ContactNameAndActions = ({ } } + const displayName = isFavourite + ? contact.company && contact.company !== ' ' + ? contact.company : `${t('Common.Unknown')}` + : contact.name && contact.name !== ' ' + ? contact.name + : contact.company && contact.company !== ' ' + ? contact.company + : `${t('Common.Unknown')}` return (
- {isFavourite - ? contact.company || `${t('Common.Unknown')}` - : contact.name || contact.company || `${t('Common.Unknown')}`} + {displayName} {isDev() && ( { From cc237a8eb26d90a01f9f0ad8fd07466e90454596 Mon Sep 17 00:00:00 2001 From: therockerline Date: Fri, 16 May 2025 17:16:59 +0200 Subject: [PATCH 11/11] fix: add tooltip to ModuleTitle fix colors for visibility badge --- src/renderer/src/components/ModuleTitle.tsx | 14 +++++++++++++- .../NethVoice/SearchResults/SearchNumberDetail.tsx | 8 +++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/renderer/src/components/ModuleTitle.tsx b/src/renderer/src/components/ModuleTitle.tsx index 580be42f..4e5977c7 100644 --- a/src/renderer/src/components/ModuleTitle.tsx +++ b/src/renderer/src/components/ModuleTitle.tsx @@ -4,6 +4,7 @@ import { IconProp } from "@fortawesome/fontawesome-svg-core" import { DefaultTFuncReturn } from "i18next" import { ReactNode } from "react" import { ClassNames } from "@renderer/utils" +import { Tooltip } from 'react-tooltip' export interface ModuleTitleProps { title?: string | DefaultTFuncReturn | ReactNode, @@ -26,9 +27,20 @@ export const ModuleTitle = ({ return (
- {title &&

+ {title &&

{title}

} + {action && (