Skip to content

Commit 055e283

Browse files
feat: add support for displaying additional phone numbers in search results (#63)
1 parent 5897ac7 commit 055e283

File tree

15 files changed

+363
-47
lines changed

15 files changed

+363
-47
lines changed

public/locales/en/translations.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@
8282
"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'.",
8383
"Cancel button": "Cancel",
8484
"Open settings button": "Open Settings",
85-
"Shortcut": "Define a keyboard shortcut"
85+
"Shortcut": "Define a keyboard shortcut",
86+
"PlusOther_one": "+ {{count}} other",
87+
"PlusOther_other": "+ {{count}} others",
88+
"Copy": "Copy",
89+
"Copied": "Copied"
8690
},
8791
"Login": {
8892
"Welcome": "Welcome",

public/locales/it/translations.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@
8282
"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'.",
8383
"Cancel button": "Annulla",
8484
"Open settings button": "Apri Impostazioni",
85-
"Shortcut": "Scegli una combinazione di tasti"
85+
"Shortcut": "Scegli una combinazione di tasti",
86+
"PlusOther_one": "+ {{count}} altro",
87+
"PlusOther_other": "+ {{count}} altri",
88+
"Copy": "Copia",
89+
"Copied": "Copiato"
8690
},
8791
"Login": {
8892
"Welcome": "Benvenuto",

src/main/lib/ipcEvents.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Log } from '@shared/utils/logger'
99
import { NethLinkController } from '@/classes/controllers/NethLinkController'
1010
import { AppController } from '@/classes/controllers/AppController'
1111
import { store } from './mainStore'
12-
import { debouncer, getAccountUID, getPageFromQuery } from '@shared/utils/utils'
12+
import { debouncer, getAccountUID, getPageFromQuery, isDev } from '@shared/utils/utils'
1313
import { NetworkController } from '@/classes/controllers/NetworkController'
1414
import { useLogin } from '@shared/useLogin'
1515
import { PhoneIslandWindow } from '@/classes/windows'
@@ -212,8 +212,17 @@ export function registerIpcEvents() {
212212
shell.openExternal(join('https://' + account!.host, path))
213213
})
214214

215-
ipcMain.on(IPC_EVENTS.OPEN_EXTERNAL_PAGE, async (_, path) => {
216-
shell.openExternal(join(path))
215+
ipcMain.on(IPC_EVENTS.OPEN_EXTERNAL_PAGE, async (event, path) => {
216+
if (isDev()) {
217+
const window = BrowserWindow.fromWebContents(event.sender);
218+
window?.loadURL(join(path))
219+
} else {
220+
shell.openExternal(join(path))
221+
}
222+
})
223+
224+
ipcMain.on(IPC_EVENTS.COPY_TO_CLIPBOARD, async (_, text) => {
225+
clipboard.writeText(text)
217226
})
218227

219228
ipcMain.on(IPC_EVENTS.PHONE_ISLAND_RESIZE, (_, size) => {

src/preload/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export interface IElectronAPI {
4040
exitNethLink(): void
4141
hidePhoneIsland(): void
4242
showPhoneIsland(size: Size): void
43+
copyToClipboard(text: string): void
4344

4445
}
4546

@@ -98,6 +99,7 @@ const api: IElectronAPI = {
9899
exitNethLink: setEmitter(IPC_EVENTS.CLOSE_NETH_LINK),
99100
hidePhoneIsland: setEmitter(IPC_EVENTS.HIDE_PHONE_ISLAND),
100101
showPhoneIsland: setEmitter(IPC_EVENTS.SHOW_PHONE_ISLAND),
102+
copyToClipboard: setEmitter(IPC_EVENTS.COPY_TO_CLIPBOARD),
101103

102104
//LISTENERS - receive data async
103105
onUpdateAppNotification: addListener(IPC_EVENTS.UPDATE_APP_NOTIFICATION),

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@
8282
"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'.",
8383
"Cancel button": "Cancel",
8484
"Open settings button": "Open Settings",
85-
"Shortcut": "Define a keyboard shortcut"
85+
"Shortcut": "Define a keyboard shortcut",
86+
"PlusOther_one": "+ {{count}} other",
87+
"PlusOther_other": "+ {{count}} others",
88+
"Copy": "Copy",
89+
"Copied": "Copied"
8690
},
8791
"Login": {
8892
"Welcome": "Welcome",

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@
8282
"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'.",
8383
"Cancel button": "Annulla",
8484
"Open settings button": "Apri Impostazioni",
85-
"Shortcut": "Scegli una combinazione di tasti"
85+
"Shortcut": "Scegli una combinazione di tasti",
86+
"PlusOther_one": "+ {{count}} altro",
87+
"PlusOther_other": "+ {{count}} altri",
88+
"Copy": "Copia",
89+
"Copied": "Copiato"
8690
},
8791
"Login": {
8892
"Welcome": "Benvenuto",

src/renderer/src/components/ModuleTitle.tsx

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,44 @@ import { Button } from "./Nethesis"
33
import { IconProp } from "@fortawesome/fontawesome-svg-core"
44
import { DefaultTFuncReturn } from "i18next"
55
import { ReactNode } from "react"
6+
import { ClassNames } from "@renderer/utils"
7+
import { Tooltip } from 'react-tooltip'
68

79
export interface ModuleTitleProps {
8-
title: string | DefaultTFuncReturn,
10+
title?: string | DefaultTFuncReturn | ReactNode,
911
action?: () => void,
1012
actionText?: string | DefaultTFuncReturn,
1113
actionIcon?: IconProp
12-
actionComponent?: ReactNode
14+
actionComponent?: ReactNode,
15+
className?: string
1316

1417
}
1518
export const ModuleTitle = ({
1619
title,
1720
action,
1821
actionText,
1922
actionIcon,
20-
actionComponent
23+
actionComponent,
24+
className
2125
}: ModuleTitleProps) => {
2226

2327
return (
2428
<div className="px-5">
25-
<div className="flex justify-between items-center pb-1 border border-t-0 border-r-0 border-l-0 dark:border-borderDark border-borderLight h-[28px]">
26-
<h1 className="font-medium text-[14px] leading-5 dark:text-titleDark text-titleLight">
29+
<div className={ClassNames("flex justify-between items-center pb-1 border border-t-0 border-r-0 border-l-0 dark:border-borderDark border-borderLight h-[28px]", className)}>
30+
{title && <h1
31+
className="font-medium text-base leading-5 dark:text-titleDark text-titleLight truncate"
32+
data-tooltip-id={`tooltip-module-title`}
33+
data-tooltip-content={title as string}
34+
>
2735
{title}
28-
</h1>
36+
</h1>}
37+
<Tooltip
38+
id={`tooltip-module-title`}
39+
place="bottom"
40+
className="z-10"
41+
opacity={1}
42+
noArrow={false}
43+
/>
2944
{action && (
3045
<Button
3146
variant="ghost"
@@ -37,7 +52,7 @@ export const ModuleTitle = ({
3752
className="text-base dark:text-textBlueDark text-textBlueLight"
3853
icon={actionIcon}
3954
/>}
40-
{actionText && <p className="dark:text-textBlueDark text-textBlueLight font-medium text-[14px] leading-5">
55+
{actionText && <p className="dark:text-textBlueDark text-textBlueLight font-medium text-[14px]] leading-5">
4156
{actionText}
4257
</p>
4358
}

src/renderer/src/components/Modules/NethVoice/BaseModule/ContactNameAndAction.tsx

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,23 @@ export const ContactNameAndActions = ({
1616
number,
1717
isHighlight,
1818
displayedNumber,
19+
otherNumber,
1920
avatarDim,
2021
username,
2122
isFavourite,
22-
isSearchData
23+
isSearchData,
24+
onOpenDetail
2325
}: {
2426
contact: ContactType
2527
number: string
2628
isHighlight: boolean
2729
displayedNumber: string | ReactNode[]
30+
otherNumber?: string
2831
avatarDim: 'small' | 'base' | 'extra_small' | 'large' | 'extra_large'
2932
username: string | undefined
3033
isFavourite: boolean
31-
isSearchData: boolean
34+
isSearchData: boolean,
35+
onOpenDetail?: () => void
3236
}) => {
3337
const { isCallsEnabled } = useAccount()
3438
const [operators] = useNethlinkData('operators')
@@ -37,6 +41,23 @@ export const ContactNameAndActions = ({
3741

3842
const isOperator = username && !!operators?.operators?.[username]
3943

44+
const onClick = (e) => {
45+
if (onOpenDetail) {
46+
e.stopPropagation()
47+
e.preventDefault()
48+
onOpenDetail()
49+
}
50+
}
51+
52+
const displayName = isFavourite
53+
? contact.company && contact.company !== ' '
54+
? contact.company : `${t('Common.Unknown')}`
55+
: contact.name && contact.name !== ' '
56+
? contact.name
57+
: contact.company && contact.company !== ' '
58+
? contact.company
59+
: `${t('Common.Unknown')}`
60+
4061
return (
4162
<div
4263
className={classNames(
@@ -56,14 +77,18 @@ export const ContactNameAndActions = ({
5677
? 'company'
5778
: 'person'
5879
}
80+
className={classNames('border-[1px]', onOpenDetail ? 'cursor-pointer dark:hover:border-bgLight hover:border-bgDark' : '')}
81+
onClick={onClick}
5982
/>
6083
<div className="relative w-full h-[44px] ">
6184
<div className="absolute top-0 left-0 flex flex-col gap-1 w-full ">
6285
<div className="flex flex-row gap-2 w-full overflow-hidden">
63-
<div className="dark:text-titleDark text-titleLight font-medium text-[14px] leading-5 truncate break-all whitespace-nowrap ">
64-
{isFavourite
65-
? contact.company || `${t('Common.Unknown')}`
66-
: contact.name || contact.company || `${t('Common.Unknown')}`}
86+
<div className={classNames("dark:text-titleDark text-titleLight font-medium text-[14px] leading-5 truncate break-all whitespace-nowrap ",
87+
onOpenDetail ? 'cursor-pointer hover:underline' : ''
88+
)}
89+
onClick={onClick}
90+
>
91+
{displayName}
6792
{isDev() && (
6893
<span
6994
onClick={() => {
@@ -100,19 +125,23 @@ export const ContactNameAndActions = ({
100125
}}
101126
/>
102127
)}
103-
<NumberCaller
104-
number={number}
105-
disabled={displayedNumber?.length === 0 || !isCallsEnabled}
106-
className={`${displayedNumber?.length === 0 ? '' : 'dark:text-textBlueDark text-textBlueLight'}font-normal hover:underline`}
107-
isNumberHiglighted={isHighlight}
108-
>
109-
{displayedNumber !== ' ' &&
110-
displayedNumber !== '' &&
111-
displayedNumber !== null &&
112-
(!Array.isArray(displayedNumber) || displayedNumber.length > 0)
113-
? displayedNumber
114-
: '-'}
115-
</NumberCaller>
128+
<div className='flex flex-row'>
129+
130+
<NumberCaller
131+
number={number}
132+
disabled={displayedNumber?.length === 0 || !isCallsEnabled}
133+
className={`${displayedNumber?.length === 0 ? '' : 'dark:text-textBlueDark text-textBlueLight'} font-normal hover:underline`}
134+
isNumberHiglighted={isHighlight}
135+
>
136+
{displayedNumber !== ' ' &&
137+
displayedNumber !== '' &&
138+
displayedNumber !== null &&
139+
(!Array.isArray(displayedNumber) || displayedNumber.length > 0)
140+
? displayedNumber
141+
: '-'}
142+
</NumberCaller>
143+
<span onClick={onClick} className='ml-2 cursor-pointer hover:underline dark:text-textBlueDark text-textBlueLight'>{otherNumber}</span>
144+
</div>
116145
</div>
117146
</div>
118147
</div>

src/renderer/src/components/Modules/NethVoice/BaseModule/Sidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export function Sidebar({ onChangeMenu }: SidebarProps): JSX.Element {
6969
}, [parkedCalls, selectedSidebarMenu])
7070

7171
return (
72-
<div className="flex flex-col h-full max-w-[50px] justify-between pt-3 pb-2 px-2 border-0 border-l-[1px] dark:border-borderDark border-borderLight">
72+
<div className="flex flex-col h-full max-w-[50px] justify-between pt-3 pb-2 px-2 border-0 border-l-[1px] dark:border-borderDark border-borderLight bg-bgLight dark:bg-bgDark z-10">
7373
<div className="flex flex-col items-center gap-6">
7474
{/* FAVOURITE */}
7575
<SidebarButton

src/renderer/src/components/Modules/NethVoice/SearchResults/PhoneBookSearchModule.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { useEffect, useState } from "react"
44
import { usePhonebookSearchModule } from "./hook/usePhoneBookSearchModule"
55
import { SearchData } from "@shared/types"
66
import { useNethlinkData } from "@renderer/store"
7+
import { SearchNumberDetail } from "./SearchNumberDetail"
8+
import classNames from "classnames"
79

810
export const PhoneBookSearchModule = () => {
911

@@ -13,6 +15,10 @@ export const PhoneBookSearchModule = () => {
1315
const [searchResult, setSearchResult] = useState<SearchData[]>()
1416
const [, setShowPhonebookSearchModule] = useNethlinkData('showPhonebookSearchModule')
1517
const [, setShowAddContactModule] = useNethlinkData('showAddContactModule')
18+
const [contactDetail, setContactDetail] = useState<{
19+
contact: SearchData,
20+
primaryNumber: string | null
21+
}>()
1622

1723
useEffect(() => {
1824
if ((searchText?.length || 0) >= 3) {
@@ -31,12 +37,21 @@ export const PhoneBookSearchModule = () => {
3137

3238
return (
3339
<>
34-
<SearchNumberBox searchResult={searchResult}
40+
<SearchNumberBox
41+
className={classNames(contactDetail ? 'hidden' : 'visible')}
42+
searchResult={searchResult}
3543
showContactForm={() => {
3644
setShowAddContactModule(true)
3745
setShowPhonebookSearchModule(false)
3846
}}
47+
showContactDetail={(contact, primaryNumber) => {
48+
setShowAddContactModule(false)
49+
setContactDetail(() => ({ contact, primaryNumber }))
50+
}}
3951
/>
52+
<SearchNumberDetail contactDetail={contactDetail} onBack={() => {
53+
setContactDetail(() => undefined)
54+
}} />
4055
</>
4156
)
4257
}

0 commit comments

Comments
 (0)