Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(profiles): faster profile images and Option to remove img and clear profile #10434

Merged
merged 23 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
16e0025
add(profiles): allow clearing profile banner and image
hassnian Jun 8, 2024
186818a
ref(SelectImageField.vue): rename emits to emit
hassnian Jun 8, 2024
1628853
add(profiles): delete profile feature
hassnian Jun 8, 2024
414daf5
add(profiles): upload profile image
hassnian Jun 8, 2024
daa35df
Merge branch 'main' into issue-10420
hassnian Jun 10, 2024
e068568
fix(profiles): upload profile image response type
hassnian Jun 10, 2024
132a1a4
ref(profiles): remove upload image type
hassnian Jun 10, 2024
17c9a65
ref(profiles): add safety delay when deleting profile
hassnian Jun 10, 2024
ce7ff61
ref(profiles): use image worker to upload images
hassnian Jun 10, 2024
9ca8c9f
add(profiles): add delete profile confirm safety delay seconds
hassnian Jun 12, 2024
075780f
add(ProfileCreateModal.vue): add profile clear notification
hassnian Jun 14, 2024
713970a
Merge branch 'main' into issue-10420
hassnian Jun 14, 2024
ed4400b
Merge branch 'main' into issue-10420
hassnian Jun 20, 2024
ccc77f1
update(profiles): upload image with address and type
hassnian Jun 20, 2024
2ca1860
Merge branch 'main' into issue-10420
hassnian Jun 25, 2024
badf8a8
Merge branch 'main' into issue-10420
hassnian Jun 25, 2024
1938b9c
Merge branch 'main' into issue-10420
hassnian Jul 1, 2024
66c7d2c
ref(profiles): add upload image
hassnian Jul 1, 2024
e5b10f3
fix(profiles): delete profile missing signature
hassnian Jul 1, 2024
dffdc13
fix(profiles): image upload throw error typo
hassnian Jul 1, 2024
4f0738f
Merge branch 'main' into issue-10420
hassnian Jul 5, 2024
d662bbd
Merge branch 'main' into issue-10420
vikiival Jul 8, 2024
d9d88b8
Merge branch 'main' into issue-10420
hassnian Jul 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion components/profile/ProfileDetail.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<template>
<div>
<ProfileCreateModal v-model="isModalActive" @success="fetchProfile" />
<ProfileCreateModal
v-model="isModalActive"
@success="fetchProfile"
@deleted="fetchProfile" />
<ProfileFollowModal
:key="`${followersCount}-${followingCount}`"
v-model="isFollowModalActive"
Expand Down
56 changes: 44 additions & 12 deletions components/profile/create/Modal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
v-if="stage === 3"
:farcaster-user-data="farcasterUserData"
:use-farcaster="useFarcaster"
@submit="handleFormSubmition" />
@submit="handleFormSubmition"
@delete="handleProfileDelete" />
<Loading v-if="stage === 4" />
<Success v-if="stage === 5" @close="close" />
</ModalBody>
Expand All @@ -36,28 +37,30 @@ import {
SocialLink,
UpdateProfileRequest,
createProfile,
deleteProfile,
updateProfile,
uploadImage,
} from '@/services/profile'
import { rateLimitedPinFileToIPFS } from '@/services/nftStorage'
import { appClient, createChannel } from '@/services/farcaster'
import { StatusAPIResponse } from '@farcaster/auth-client'
import { useDocumentVisibility } from '@vueuse/core'
import { getBioWithLinks } from '../utils'

const emit = defineEmits(['close', 'success', 'deleted'])
const props = defineProps<{
modelValue: boolean
}>()

const documentVisibility = useDocumentVisibility()
const { $i18n } = useNuxtApp()
const { accountId } = useAuth()

const profile = inject<{ hasProfile: Ref<boolean> }>('userProfile')

const hasProfile = computed(() => profile?.hasProfile.value)

const initialStep = computed(() => (hasProfile.value ? 2 : 1))

const emit = defineEmits(['close', 'success'])
const { getSignaturePair } = useVerifyAccount()
const vOpen = useVModel(props, 'modelValue')
const stage = ref(initialStep.value)
Expand All @@ -69,12 +72,26 @@ const close = () => {
emit('close')
}

const uploadImage = async (
imageFile: File | null,
): Promise<string | undefined> =>
imageFile
? sanitizeIpfsUrl(await rateLimitedPinFileToIPFS(imageFile))
: undefined
const uploadProfileImage = async (
file: File | null,
type: 'image' | 'banner',
): Promise<string | undefined> => {
if (!file) {
return undefined
}

const { signature, message } = await getSignaturePair()

const response = await uploadImage({
file,
type,
address: accountId.value,
signature,
message,
})

return response.url
}

const constructSocials = (profileData: ProfileFormData): SocialLink[] => {
return [
Expand All @@ -100,11 +117,11 @@ const processProfile = async (profileData: ProfileFormData) => {
const { signature, message } = await getSignaturePair()

const imageUrl = profileData.image
? await uploadImage(profileData.image)
? await uploadProfileImage(profileData.image, 'image')
: profileData.imagePreview

const bannerUrl = profileData.banner
? await uploadImage(profileData.banner)
? await uploadProfileImage(profileData.banner, 'banner')
: profileData.bannerPreview

const profileBody: CreateProfileRequest | UpdateProfileRequest = {
Expand All @@ -114,7 +131,7 @@ const processProfile = async (profileData: ProfileFormData) => {
? getBioWithLinks(profileData.description)
: profileData.description,
image: imageUrl,
banner: bannerUrl,
banner: hasProfile.value ? bannerUrl ?? null : bannerUrl!,
socials: constructSocials(profileData),
signature,
message,
Expand All @@ -125,6 +142,21 @@ const processProfile = async (profileData: ProfileFormData) => {
: createProfile(profileBody as CreateProfileRequest)
}

const handleProfileDelete = async (address: string) => {
try {
const { signature, message } = await getSignaturePair()
await deleteProfile({ address, message, signature })
infoMessage($i18n.t('profiles.profileHasBeenCleared'), {
title: $i18n.t('profiles.profileReset'),
})
emit('deleted')
close()
} catch (error) {
warningMessage(error!.toString())
console.error(error)
}
}

const handleFormSubmition = async (profileData: ProfileFormData) => {
stage.value = 4 // Go to loading stage
try {
Expand Down
11 changes: 8 additions & 3 deletions components/profile/create/SelectImageField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,22 @@
vSelectedFile?.name ?? 'Click To Select A File'
}}</span>
<NeoButton
v-if="vSelectedFile"
v-if="vSelectedFile || preview"
class="absolute right-3 top-3"
variant="icon"
no-shadow
icon="xmark"
@click="vSelectedFile = null" />
@click="clear" />
</div>
</NeoUpload>
</template>
<script setup lang="ts">
import { NeoButton, NeoIcon, NeoUpload } from '@kodadot1/brick'

const NuxtImg = resolveComponent('NuxtImg')

const ONE_MB = 1024 * 1024

const emit = defineEmits(['clear'])
const props = defineProps<{
modelValue: File | null
preview?: string
Expand All @@ -50,6 +50,11 @@ const selectedFilePreview = computed(() =>
vSelectedFile.value ? URL.createObjectURL(vSelectedFile.value as File) : '',
)

const clear = () => {
vSelectedFile.value = null
emit('clear')
}

const fileSelected = (file: File | null) => {
if (file && props.maxSizeInMb && file.size > props.maxSizeInMb * ONE_MB) {
vSelectedFile.value = null
Expand Down
Loading
Loading