Skip to content

Commit

Permalink
Import Contacts fix attempt (#13)
Browse files Browse the repository at this point in the history
* feat: qr code improvements

* apply pending connection events

* chore: hide import contacts for now

* fix: import native contact fixes and improvements
  • Loading branch information
MarcusVirg authored Dec 17, 2023
1 parent bb55b98 commit 69c2e72
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 61 deletions.
1 change: 0 additions & 1 deletion apps/resplice/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"date-fns-tz": "^2.0.0",
"html5-qrcode": "^2.3.8",
"js-search": "^2.0.1",
"jsqr": "^1.4.0",
"libphonenumber-js": "^1.10.49",
"qrcode": "^1.5.3",
"rxjs": "^7.8.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@
isInviting = true
const inviteType = InviteType[attribute.type.toUpperCase() as keyof typeof InviteType]
switch (inviteType) {
case InviteType.EMAIL:
await protocol.invite.create({
name: contact.name,
value: { $case: 'email', email: attribute.value }
})
break
case InviteType.PHONE:
await protocol.invite.create({
name: contact.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@
</div>
{#if !contact.inviteState}
<div class="flex-none flex flex-col space-y-4 p-4">
{#if contact.attributes.length}
{#each contact.attributes as attribute}
{#if contact.attributes.filter((a) => a.type === 'phone').length}
{#each contact.attributes.filter((a) => a.type === 'phone') as attribute}
<ContactImportAttribute {contact} {attribute} />
{/each}
{:else}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,47 @@
import { createEventDispatcher } from 'svelte'
import { isSupported } from '@resplice/utils'
import { getGoogleContacts, getNativeContacts } from '$modules/invite/services/contactProviders'
import { ButtonAlt as Button, GoogleIcon, PhonePortraitIcon } from '@resplice/components'
const dispatch = createEventDispatcher()
import { ButtonAlt as Button, GoogleIcon, PhonePortraitIcon, toast } from '@resplice/components'
const dispatch = createEventDispatcher()
const isContactPickerSupported = isSupported('contacts')
let isNativeLoading = false
let isGoogleLoading = false
async function onContactPickerClick() {
isNativeLoading = true
const contacts = await getNativeContacts()
console.log(contacts)
dispatch('import', contacts)
try {
isNativeLoading = true
const contacts = await getNativeContacts()
console.log(contacts)
dispatch('import', contacts)
isNativeLoading = false
} catch (e) {
isNativeLoading = false
toast.new({
type: toast.type.WARNING,
title: 'Import Error',
message: 'Could not import contacts from your device. Please try again.'
})
console.error(e)
}
}
async function onGoogleProviderClick() {
isGoogleLoading = true
const contacts = await getGoogleContacts()
dispatch('import', contacts)
try {
isGoogleLoading = true
const contacts = await getGoogleContacts()
dispatch('import', contacts)
isGoogleLoading = false
} catch (e) {
isGoogleLoading = false
toast.new({
type: toast.type.WARNING,
title: 'Import Error',
message: 'Could not import contacts from Google. Please try again.'
})
console.error(e)
}
}
</script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
</script>

<button class="flex items-center space-x-2 w-full px-4 py-2" on:click>
<!-- Replace with person icon inside of a circle -->
<div class="w-12 h-12 rounded-full bg-slate-200 text-slate-600 flex justify-center items-center">
<PersonIcon height={24} width={24} />
</div>
Expand Down
65 changes: 31 additions & 34 deletions apps/resplice/src/modules/invite/services/contactProviders.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { parsePhoneNumber } from 'libphonenumber-js'
import { isSupported } from '@resplice/utils'
import config from '$services/config'

Expand All @@ -22,7 +23,7 @@ type GoogleToken = {
scope: string
token_type: string
}
export function getGoogleContacts() {
export function getGoogleContacts(): Promise<ProviderContact[]> {
return new Promise((resolve, reject) => {
async function onGoogleToken(token: GoogleToken) {
const contacts = await fetchGoogleContacts(token.access_token)
Expand All @@ -37,7 +38,8 @@ export function getGoogleContacts() {
client_id: config.googleOAuthClientId,
scope: 'https://www.googleapis.com/auth/contacts.readonly',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
callback: onGoogleToken
callback: onGoogleToken,
error_callback: () => reject()
})
client.requestAccessToken()
})
Expand Down Expand Up @@ -80,41 +82,36 @@ export async function fetchGoogleContacts(accessToken: string): Promise<Provider

export async function getNativeContacts(): Promise<ProviderContact[]> {
const isContactPickerSupported = isSupported('contacts')
if (!isContactPickerSupported) return []
if (!isContactPickerSupported) throw new Error('Contact picker not supported')

try {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const contacts: any[] = await (navigator as any).contacts.select(['name', 'tel', 'icon'], {
multiple: true
})
console.log(contacts)
return contacts.map((c, idx) => {
const attributes: ProviderContactAttribute[] = []

if (c.tel) {
c.tel.forEach((tel: string, idx: number) =>
attributes.push({ type: 'phone', name: `Phone ${idx + 1}`, value: tel })
)
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const contacts: any[] = await (navigator as any).contacts.select(['name', 'tel', 'icon'], {
multiple: true
})

if (c.email) {
c.email.forEach((email: string, idx: number) =>
attributes.push({ type: 'email', name: `Email ${idx + 1}`, value: email })
)
}
return contacts.map((c, idx) => {
const attributes: ProviderContactAttribute[] = []

return {
id: idx.toString(),
name: c.name[0],
avatar: c.icon,
attributes: attributes
}
})
} catch (err) {
// TODO: Show an alert
console.log(err)
return []
}
if (c.tel) {
c.tel.forEach((tel: string, idx: number) => {
const phone = parsePhoneNumber(tel, 'US')
if (phone) attributes.push({ type: 'phone', name: `Phone ${idx + 1}`, value: phone.number })
})
}

if (c.email) {
c.email.forEach((email: string, idx: number) =>
attributes.push({ type: 'email', name: `Email ${idx + 1}`, value: email })
)
}

return {
id: idx.toString(),
name: c.name[0],
avatar: c.icon ? c.icon[0] || '' : '',
attributes: attributes
}
})
}

export async function getContactsFromCsv(csv: Blob): Promise<ProviderContact[]> {
Expand Down
6 changes: 0 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/components/src/lib/ButtonAlt.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
<button
class={cx(
$$props.class,
'w-full flex space-x-4 rounded-full border-2 border-gray-700 px-8 py-4 duration-75 ease-in-out active:scale-95 focus:ring-4 focus:ring-green-200 focus:outline-none'
'relative w-full flex space-x-4 rounded-full border-2 border-gray-700 px-8 py-4 duration-75 ease-in-out active:scale-95 focus:ring-4 focus:ring-green-200 focus:outline-none'
)}
disabled={disabled || isLoading}
on:click
>
{#if isLoading}
<div
class="absolute left-0 top-0 h-full w-full flex items-center justify-center bg-gray-400 bg-opacity-60 rounded-lg"
class="absolute left-0 top-0 h-full w-full flex items-center justify-center bg-gray-400 bg-opacity-60 rounded-full"
>
<Spinner width={24} />
</div>
Expand Down

0 comments on commit 69c2e72

Please sign in to comment.