Skip to content

Commit

Permalink
Merge pull request #10707 from Jarsen136/issue-10679
Browse files Browse the repository at this point in the history
feat: Profiles: Popup to create profile
  • Loading branch information
vikiival authored Aug 2, 2024
2 parents d7fc001 + 87245e4 commit 7814248
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 28 deletions.
23 changes: 17 additions & 6 deletions components/carousel/CarouselTypeGenerative.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
<template>
<CarouselIndex
data-testid="generative-activity"
:title="$t('general.generativeArt')"
:nfts="nfts.value"
action-type="pagination"
/>
<div ref="carouselDrop">
<CarouselIndex
data-testid="generative-activity"
:title="$t('general.generativeArt')"
:nfts="nfts.value"
action-type="pagination"
/>
</div>
</template>

<script lang="ts" setup>
import { useElementVisibility } from '@vueuse/core'
import { useCarouselGenerativeNftEvents } from './utils/useCarouselEvents'
import { useProfileOnboardingStore } from '@/stores/profileOnboarding'
const nfts = useCarouselGenerativeNftEvents()
const carouselDrop = ref()
watch([useElementVisibility(carouselDrop)], ([isVisible]) => {
if (isVisible) {
useProfileOnboardingStore().setCarouselVisited()
}
})
</script>
15 changes: 15 additions & 0 deletions components/landing/LandingPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,15 @@

<script lang="ts" setup>
import type { Prefix } from '@kodadot1/static'
import { openProfileCreateModal } from '@/components/profile/create/openProfileModal'
import { useProfileOnboardingStore } from '@/stores/profileOnboarding'
const hiddenCarrouselPrefixes: Prefix[] = ['dot']
const forbiddenPrefixesForTopCollections: Prefix[] = ['ksm', 'dot', 'imx']
const { urlPrefix } = usePrefix()
const profileOnboardingStore = useProfileOnboardingStore()
const { hasProfile } = useProfile()
// currently only supported on rmrk
const showCarousel = computed(
Expand All @@ -50,4 +54,15 @@ const showCarousel = computed(
const showTopCollections = computed(
() => !forbiddenPrefixesForTopCollections.includes(urlPrefix.value),
)
watchEffect(() => {
if (!hasProfile.value && profileOnboardingStore.getShouldShowOnboarding) {
profileOnboardingStore.setOnboardingShown()
// delay to show onboarding modal to avoid disturbing the user
setTimeout(() => {
openProfileCreateModal()
}, 2000)
}
})
</script>
2 changes: 2 additions & 0 deletions components/navbar/ProfileDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ import {
} from '@/utils/config/i18n'
import { ConnectWalletModalConfig } from '@/components/common/ConnectWallet/useConnectWallet'
import ConnectWalletButton from '@/components/shared/ConnectWalletButton.vue'
import { useProfileOnboardingStore } from '@/stores/profileOnboarding'
const identityStore = useIdentityStore()
const { isDarkMode } = useTheme()
Expand All @@ -113,6 +114,7 @@ const profileIcon = computed(() =>
const langsFlags = computed(() => langsFlagsList)
const toggleWalletConnectModal = () => {
useProfileOnboardingStore().setSidebarToggled()
neoModal.closeAll()
if (!document.querySelector('.connect-wallet-modal')) {
Expand Down
20 changes: 9 additions & 11 deletions components/profile/ProfileDetail.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
<template>
<div>
<ProfileCreateModal
v-model="isModalActive"
@success="fetchProfile"
@deleted="fetchProfile"
/>
<ProfileFollowModal
:key="`${followersCount}-${followingCount}`"
v-model="isFollowModalActive"
Expand Down Expand Up @@ -500,11 +495,9 @@ const { isRemark, isSub } = useIsChain(urlPrefix)
const listingCartStore = useListingCartStore()
const { vm } = useChain()
const { hasProfile, userProfile, fetchProfile, isFetchingProfile }
const { hasProfile, userProfile, isFetchingProfile }
= useProfile()
provide('userProfile', { hasProfile, userProfile })
const { data: followers, refresh: refreshFollowers } = useAsyncData(
`followersof${route.params.id}`,
() =>
Expand All @@ -529,14 +522,14 @@ const followingCount = computed(() => following.value?.totalCount ?? 0)
const editProfileConfig: ButtonConfig = {
label: $i18n.t('profile.editProfile'),
icon: 'pen',
onClick: () => (isModalActive.value = true),
onClick: () => openProfileCreateModal(true),
classes: 'hover:!bg-transparent',
}
const createProfileConfig: ButtonConfig = {
label: $i18n.t('profile.createProfile'),
icon: 'sparkles',
onClick: () => (isModalActive.value = true),
onClick: () => openProfileCreateModal(true),
variant: 'primary',
}
Expand All @@ -555,7 +548,6 @@ const displayName = ref('')
const web = ref('')
const legal = ref('')
const riot = ref('')
const isModalActive = ref(false)
const isFollowModalActive = ref(false)
const followModalTab = ref<'followers' | 'following'>('followers')
const collections = ref(
Expand Down Expand Up @@ -791,6 +783,12 @@ watch(collections, (value) => {
collections: value.length ? value.toString() : undefined,
})
})
onMounted(() => {
if (!hasProfile.value && isOwner.value) {
openProfileCreateModal()
}
})
</script>

<style lang="scss" scoped>
Expand Down
14 changes: 9 additions & 5 deletions components/profile/create/Modal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,22 @@ import { appClient, createChannel } from '@/services/farcaster'
const emit = defineEmits(['close', 'success', 'deleted'])
const props = defineProps<{
modelValue: boolean
skipIntro?: boolean
}>()
const documentVisibility = useDocumentVisibility()
const { $i18n } = useNuxtApp()
const { accountId } = useAuth()
const { fetchProfile } = useProfile()
const profile = inject<{ hasProfile: Ref<boolean> }>('userProfile')
const { hasProfile, userProfile } = useProfile()
const hasProfile = computed(() => profile?.hasProfile.value)
provide('userProfile', { hasProfile, userProfile })
const initialStep = computed(() => (hasProfile.value ? 2 : 1))
const initialStep = computed(() => (props.skipIntro || hasProfile.value ? 2 : 1))
const { getSignaturePair } = useVerifyAccount()
const vOpen = useVModel(props, 'modelValue')
const vOpen = ref(true)
const stage = ref(initialStep.value)
const farcasterUserData = ref<StatusAPIResponse>()
const useFarcaster = ref(false)
Expand Down Expand Up @@ -165,6 +166,7 @@ const handleProfileDelete = async (address: string) => {
title: $i18n.t('profiles.profileReset'),
})
emit('deleted')
fetchProfile()
close()
}
catch (error) {
Expand All @@ -178,6 +180,8 @@ const handleFormSubmition = async (profileData: ProfileFormData) => {
try {
await processProfile(profileData)
emit('success')
fetchProfile()
stage.value = 5 // Go to success stage
}
catch (error) {
Expand Down
5 changes: 2 additions & 3 deletions components/profile/create/openProfileModal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@ export const ProfileCreateModalConfig = {
trapFocus: false,
}

export const openProfileCreateModal = (config = {}) => {
export const openProfileCreateModal = (skipIntro: boolean = false) => {
const { neoModal } = useProgrammatic()

neoModal.closeAll()

return neoModal.open({
...ProfileCreateModalConfig,
...config,
innerProps: {
value: true,
skipIntro,
},
})
}
7 changes: 6 additions & 1 deletion components/profile/create/stages/Success.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
<NeoButton
class="min-[400px]:!w-[150px] !w-full"
variant="primary-rounded"
:tag="NuxtLink"
:to="profileUrl"
:label="'Go To Profile'"
@click="emit('close')"
/>
Expand All @@ -43,7 +45,10 @@
<script setup lang="ts">
import { NeoButton, NeoIcon } from '@kodadot1/brick'
const NuxtLink = resolveComponent('NuxtLink')
const { urlPrefix } = usePrefix()
const { accountId } = useAuth()
const emit = defineEmits(['close'])
const profileUrl = window.location.href
const profileUrl = computed(() => `/${urlPrefix.value}/u/${accountId.value}`)
</script>
2 changes: 1 addition & 1 deletion composables/useFetchProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function useFetchProfile(address?: string) {
computed(() => address && toSubstrateAddress(address)),
],
queryFn: () => (address ? fetchProfileByAddress(address!) : null),
staleTime: 1000 * 60 * 5,
staleTime: 1000 * 10,
})

return {
Expand Down
2 changes: 1 addition & 1 deletion composables/useProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function useUserProfile() {
} = useFetchProfile(params?.id as string)

return {
hasProfile: computed(() => !!profile.value),
hasProfile: computed(() => isLoading.value || !!profile.value),
userProfile: profile,
fetchProfile,
isFetchingProfile: isLoading,
Expand Down
32 changes: 32 additions & 0 deletions stores/profileOnboarding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { defineStore } from 'pinia'

export interface ProfileOnboardingState {
onboardingShown: boolean
sidebarToggled: boolean
carouselVisited: boolean
}

export const useProfileOnboardingStore = defineStore('profileOnboarding', {
state: (): ProfileOnboardingState => ({
onboardingShown: false,
sidebarToggled: false,
carouselVisited: false,
}),
getters: {
getShouldShowOnboarding: (state) => {
const { accountId } = useAuth()
return accountId.value && !state.onboardingShown && state.sidebarToggled && state.carouselVisited
},
},
actions: {
setOnboardingShown() {
this.onboardingShown = true
},
setSidebarToggled() {
this.sidebarToggled = true
},
setCarouselVisited() {
this.carouselVisited = true
},
},
})

0 comments on commit 7814248

Please sign in to comment.