Handle profile update errors

This commit is contained in:
Jon Staab
2026-03-06 14:18:05 -08:00
parent 16c6015919
commit 2f3bc6cc6f
5 changed files with 72 additions and 30 deletions
+1 -1
View File
@@ -11,7 +11,7 @@
"tauri:info": "tauri info", "tauri:info": "tauri info",
"tauri:icons": "tauri icon assets/logo.png --output src-tauri/icons", "tauri:icons": "tauri icon assets/logo.png --output src-tauri/icons",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "./check.sh", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --check src && eslint src", "lint": "prettier --check src && eslint src",
"format": "git diff head --name-only --diff-filter d | grep -E '(js|ts|svelte|css)$' | xargs -r prettier --write", "format": "git diff head --name-only --diff-filter d | grep -E '(js|ts|svelte|css)$' | xargs -r prettier --write",
"format:all": "prettier --write src", "format:all": "prettier --write src",
+33 -6
View File
@@ -1,10 +1,12 @@
<script lang="ts"> <script lang="ts">
import type {Profile} from "@welshman/util" import type {Profile} from "@welshman/util"
import {getTag, makeProfile} from "@welshman/util" import {getTag, makeProfile} from "@welshman/util"
import {pubkey, profilesByPubkey} from "@welshman/app" import {pubkey, profilesByPubkey, waitForThunkError} from "@welshman/app"
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl" import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import {errorMessage} from "@lib/util"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import ProfileEditForm from "@app/components/ProfileEditForm.svelte" import ProfileEditForm from "@app/components/ProfileEditForm.svelte"
import {clearModals} from "@app/util/modal" import {clearModals} from "@app/util/modal"
import {pushToast} from "@app/util/toast" import {pushToast} from "@app/util/toast"
@@ -17,11 +19,33 @@
const back = () => history.back() const back = () => history.back()
const onsubmit = ({profile, shouldBroadcast}: {profile: Profile; shouldBroadcast: boolean}) => { const onsubmit = async ({
updateProfile({profile, shouldBroadcast}) profile,
pushToast({message: "Your profile has been updated!"}) shouldBroadcast,
clearModals() }: {
profile: Profile
shouldBroadcast: boolean
}) => {
loading = true
try {
const error = await waitForThunkError(updateProfile({profile, shouldBroadcast}))
if (error) {
pushToast({
theme: "error",
message: `Failed to update your profile: ${errorMessage(error)}`,
})
} else {
pushToast({message: "Your profile has been updated!"})
clearModals()
}
} finally {
loading = false
}
} }
let loading = $state(false)
</script> </script>
<ProfileEditForm {initialValues} {onsubmit}> <ProfileEditForm {initialValues} {onsubmit}>
@@ -30,6 +54,9 @@
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go Back Go Back
</Button> </Button>
<Button type="submit" class="btn btn-primary">Save Changes</Button> <Button type="submit" class="btn btn-primary" disabled={loading}>
<Spinner {loading} />
Save Changes
</Button>
{/snippet} {/snippet}
</ProfileEditForm> </ProfileEditForm>
@@ -1,5 +1,8 @@
<script lang="ts"> <script lang="ts">
import {makeProfile} from "@welshman/util"
import {getWalletAddress} from "@welshman/util" import {getWalletAddress} from "@welshman/util"
import {userProfile, waitForThunkError, session} from "@welshman/app"
import {errorMessage} from "@lib/util"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte" import Spinner from "@lib/components/Spinner.svelte"
import Modal from "@lib/components/Modal.svelte" import Modal from "@lib/components/Modal.svelte"
@@ -9,8 +12,7 @@
import ModalFooter from "@lib/components/ModalFooter.svelte" import ModalFooter from "@lib/components/ModalFooter.svelte"
import {updateProfile} from "@app/core/commands" import {updateProfile} from "@app/core/commands"
import {clearModals} from "@app/util/modal" import {clearModals} from "@app/util/modal"
import {userProfile, session} from "@welshman/app" import {pushToast} from "@app/util/toast"
import {makeProfile} from "@welshman/util"
const lud16 = getWalletAddress($session!.wallet!) const lud16 = getWalletAddress($session!.wallet!)
@@ -20,9 +22,13 @@
loading = true loading = true
try { try {
await updateProfile({profile: {...profile, lud16}}) const error = await waitForThunkError(updateProfile({profile: {...profile, lud16}}))
clearModals() if (error) {
pushToast({theme: "error", message: `Failed to update profile: ${errorMessage(error)}`})
} else {
clearModals()
}
} finally { } finally {
loading = false loading = false
} }
@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import {getWalletAddress} from "@welshman/util" import {getWalletAddress} from "@welshman/util"
import {session, userProfile} from "@welshman/app" import {session, waitForThunkError, userProfile} from "@welshman/app"
import {errorMessage} from "@lib/util"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte" import ModalHeader from "@lib/components/ModalHeader.svelte"
@@ -17,7 +18,7 @@
const back = () => history.back() const back = () => history.back()
let address = $state($userProfile?.lud16 || "") let address = $state($userProfile?.lud16 || "")
let isLoading = $state(false) let loading = $state(false)
const walletLud16 = $derived($session?.wallet ? getWalletAddress($session.wallet) : undefined) const walletLud16 = $derived($session?.wallet ? getWalletAddress($session.wallet) : undefined)
@@ -28,20 +29,28 @@
} }
const save = async () => { const save = async () => {
isLoading = true loading = true
try { try {
await updateProfile({ const error = await waitForThunkError(
profile: { updateProfile({
...$userProfile, profile: {
lud06: undefined, ...$userProfile,
lud16: address.trim() || undefined, lud06: undefined,
}, lud16: address.trim() || undefined,
}) },
back() }),
)
if (error) {
pushToast({theme: "error", message: `Failed to update profile: ${errorMessage(error)}`})
} else {
back()
}
} catch (error) { } catch (error) {
pushToast({theme: "error", message: "Failed to update profile"}) pushToast({theme: "error", message: "Failed to update profile"})
} finally { } finally {
isLoading = false loading = false
} }
} }
</script> </script>
@@ -61,7 +70,7 @@
placeholder="user@domain.com" placeholder="user@domain.com"
bind:value={address} bind:value={address}
class="input input-bordered flex w-full" class="input input-bordered flex w-full"
disabled={isLoading} /> disabled={loading} />
<p class="text-xs opacity-75"> <p class="text-xs opacity-75">
You can enter one manually or use your connected wallet's address (if available). Leave You can enter one manually or use your connected wallet's address (if available). Leave
empty to remove your lightning address empty to remove your lightning address
@@ -78,7 +87,7 @@
</div> </div>
<p class="text-xs opacity-75">{walletLud16}</p> <p class="text-xs opacity-75">{walletLud16}</p>
</div> </div>
<Button class="btn btn-outline btn-sm" onclick={useWalletAddress} disabled={isLoading}> <Button class="btn btn-outline btn-sm" onclick={useWalletAddress} disabled={loading}>
Use This Use This
</Button> </Button>
</div> </div>
@@ -87,9 +96,9 @@
</div> </div>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-neutral" onclick={back} disabled={isLoading}>Cancel</Button> <Button class="btn btn-neutral" onclick={back} disabled={loading}>Cancel</Button>
<Button class="btn btn-primary" onclick={save} disabled={isLoading}> <Button class="btn btn-primary" onclick={save} disabled={loading}>
{#if isLoading} {#if loading}
<span class="loading loading-spinner loading-sm"></span> <span class="loading loading-spinner loading-sm"></span>
{:else} {:else}
<Icon icon={CheckCircle} /> <Icon icon={CheckCircle} />
+2 -2
View File
@@ -676,7 +676,7 @@ export const initProfile = (profile: Profile) => {
return publishThunk({event, relays: []}) return publishThunk({event, relays: []})
} }
export const updateProfile = async ({ export const updateProfile = ({
profile, profile,
shouldBroadcast = !getTag(PROTECTED, profile.event?.tags || []), shouldBroadcast = !getTag(PROTECTED, profile.event?.tags || []),
}: { }: {
@@ -697,5 +697,5 @@ export const updateProfile = async ({
const event = makeEvent(template.kind, template) const event = makeEvent(template.kind, template)
const relays = router.merge(scenarios).getUrls() const relays = router.merge(scenarios).getUrls()
await publishThunk({event, relays}).complete return publishThunk({event, relays})
} }