diff --git a/src/contexts/AccountContext.tsx b/src/contexts/AccountContext.tsx index e14d3ec..67a976e 100644 --- a/src/contexts/AccountContext.tsx +++ b/src/contexts/AccountContext.tsx @@ -35,6 +35,9 @@ import EnterPinModal from "../components/EnterPinModal/EnterPinModal"; import CreateAccountModal from "../components/CreateAccountModal/CreateAccountModal"; import LoginModal from "../components/LoginModal/LoginModal"; import { logError, logInfo, logWarning } from "../lib/logger"; +import { useToastContext } from "../components/Toaster/Toaster"; +import { useIntl } from "@cookbook/solid-intl"; +import { account as tAccount } from "../translations"; export type AccountContextStore = { likes: string[], @@ -129,6 +132,9 @@ export const AccountContext = createContext(); export function AccountProvider(props: { children: JSXElement }) { + const toast = useToastContext(); + const intl = useIntl(); + let relayAtempts: Record = {}; const relayAtemptLimit = 10; let relaysExplicitlyClosed: string[] = []; @@ -582,6 +588,8 @@ export function AccountProvider(props: { children: JSXElement }) { updateStore('followInProgress', () => pubkey); + let contactsReceived = false; + let contactData: ContactsData = { content: '', created_at: 0, @@ -591,8 +599,14 @@ export function AccountProvider(props: { children: JSXElement }) { const unsub = subscribeTo(`before_follow_${APP_ID}`, async (type, subId, content) => { if (type === 'EOSE') { + if (!contactsReceived) { + toast?.sendWarning(intl.formatMessage(tAccount.followFailed)) + updateStore('followInProgress', () => ''); + unsub(); + return; + } - if (!store.following.includes(pubkey)) { + if (!contactData.following.includes(pubkey)) { const relayInfo = contactData.content; const date = Math.floor((new Date()).getTime() / 1000); @@ -621,13 +635,14 @@ export function AccountProvider(props: { children: JSXElement }) { return; } - if (content && - content.kind === Kind.Contacts && - content.created_at && - content.created_at >= store.followingSince - ) { - contactData = extractContacts(content); - // updateContacts(content); + if (type === 'EVENT') { + if (!content || content.kind !== Kind.Contacts) return; + + contactsReceived = true; + + if (content.created_at && content.created_at >= store.followingSince) { + contactData = extractContacts(content); + } } }); @@ -642,6 +657,8 @@ export function AccountProvider(props: { children: JSXElement }) { updateStore('followInProgress', () => pubkey); + let contactsReceived = false; + let contactData: ContactsData = { content: '', created_at: 0, @@ -651,7 +668,14 @@ export function AccountProvider(props: { children: JSXElement }) { const unsub = subscribeTo(`before_unfollow_${APP_ID}`, async (type, subId, content) => { if (type === 'EOSE') { - if (store.following.includes(pubkey)) { + if (!contactsReceived) { + toast?.sendWarning(intl.formatMessage(tAccount.unfollowFailed)) + updateStore('followInProgress', () => ''); + unsub(); + return; + } + + if (contactData.following.includes(pubkey)) { const relayInfo = contactData.content; const date = Math.floor((new Date()).getTime() / 1000); @@ -680,13 +704,14 @@ export function AccountProvider(props: { children: JSXElement }) { return; } - if (content && - content.kind === Kind.Contacts && - content.created_at && - content.created_at >= store.followingSince - ) { - contactData = extractContacts(content); - // updateContacts(content); + if (type === 'EVENT') { + if (!content || content.kind !== Kind.Contacts) return; + + contactsReceived = true; + + if (content.created_at && content.created_at >= store.followingSince) { + contactData = extractContacts(content); + } } }); diff --git a/src/translations.ts b/src/translations.ts index 4346e65..97cc22f 100644 --- a/src/translations.ts +++ b/src/translations.ts @@ -34,6 +34,16 @@ export const account = { defaultMessage: 'unfollow all', description: 'Unfollow all button label', }, + followFailed: { + id: 'account.followFailed', + defaultMessage: 'Failed to complete the follow possibly due to a network error. Please try again.', + description: 'Feedback to user that the follow action has failed', + }, + unfollowFailed: { + id: 'account.unfollowFailed', + defaultMessage: 'Failed to complete the unfollow possibly due to a network error. Please try again.', + description: 'Feedback to user that the unfollow action has failed', + }, needToLogin: { id: 'account.needToLogin', defaultMessage: 'You need to be signed in to perform this action',