Skip to content

Commit

Permalink
Merge pull request #24 from nezz0746/feat/profile-revamp
Browse files Browse the repository at this point in the history
feat: profile page & map navigation revamp
  • Loading branch information
nezz0746 authored Dec 1, 2023
2 parents 0176441 + 3304571 commit 4054ef4
Show file tree
Hide file tree
Showing 20 changed files with 213 additions and 116 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Instate is an conceptual protocol created to build localized applications with l

## @instate/kit

ConnectButton exports Rainbowkit's original ConnectButton with an additional LocalAccountButton that let user's pick the local account they would like to use for your application. Just like for networks, you can require a certain location and
This kit exports Rainbowkit's original ConnectButton with an additional LocalAccountButton that let user's pick the local account they would like to use for your application. Just like for networks, you can require a certain location and
propose a local account switch to your user, or (soon) a move if the user doesn't have a local account in your application vicinity.

<img src="./LocalAccountButton.png" />
Expand Down
13 changes: 13 additions & 0 deletions apps/subgraph/generated/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,19 @@ export class NetworkStateTravel extends Entity {
set nextGeohash(value: string) {
this.set("nextGeohash", Value.fromString(value));
}

get transactionHash(): Bytes {
let value = this.get("transactionHash");
if (!value || value.kind == ValueKind.NULL) {
throw new Error("Cannot return null for a required field.");
} else {
return value.toBytes();
}
}

set transactionHash(value: Bytes) {
this.set("transactionHash", Value.fromBytes(value));
}
}

export class LocalRecord extends Entity {
Expand Down
1 change: 1 addition & 0 deletions apps/subgraph/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type NetworkStateTravel @entity(immutable: true) {
account: Bytes! # address
previousGeohash: String! # string
nextGeohash: String! # string
transactionHash: Bytes!
}

# --------------------- RECORD ---------------------
Expand Down
1 change: 1 addition & 0 deletions apps/subgraph/src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export function handleNetworkStateTravel(event: StateMoveEvent): void {
travel.account = event.params.account;
travel.previousGeohash = event.params.previousGeohash;
travel.nextGeohash = event.params.nextGeohash;
travel.transactionHash = event.transaction.hash;

let agent = Agent.load(event.params.account);

Expand Down
4 changes: 0 additions & 4 deletions apps/web/app/map/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { commonLocations } from '@/services/constants'
import AccountMarker from '@/components/Map/AccountMarker'
import FogLayer from '@/components/Map/Fog'
import AppNavigationBar from '@/components/AppNavigationBar'
import AppMapControls from '@/components/AppMapControls'
import usePath from '@/hooks/usePath'
import NetworkStateLayers from '@/components/Map/NetworkStateLayers'
import { ConnectButton } from '@instate/kit'
Expand Down Expand Up @@ -44,9 +43,6 @@ const Home = ({ children }: HomeProps) => {
{isProfile && <FogLayer />}
{isLocalDrops && <LocalDropFocusRegion />}
{isTile && <NetworkStateLayers />}
<div className="absolute w-full bottom-0 p-3">
<AppMapControls />
</div>
</Map>
</div>
<div className="w-[50%]">
Expand Down
46 changes: 25 additions & 21 deletions apps/web/app/map/profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import type { NextPage } from 'next'
import useAppAgent from '@/hooks/useAppAgent'
import { truncateAddress } from '@/services/utils'
import StateHeader from '@/components/StateHeader'
import Tabs from '@/components/Tabs'
import { NetworkState } from '@instate/kit'
import AccountNFTs from '@/components/LocalAccountNFTs'
import { NetworkState, useLocalAccount } from '@instate/kit'
import ConnectedLocalAccount from '@/components/ConnectedLocalAccount'

const Home: NextPage = () => {
const { agent } = useAppAgent()
const { switchLocalAccount } = useLocalAccount()

return (
<>
Expand All @@ -21,25 +21,29 @@ const Home: NextPage = () => {
(agent?.records.length ? ` (${agent?.records.length})` : ''),
content: (
<div className="flex flex-col gap-2 mt-2 w-full overflow-scroll">
{agent?.records.map(({ geohash, id }) => {
return (
<div
key={geohash}
className="bg-base-300 flex flex-col gap-2 p-2 text-base-content rounded-md select-none"
>
<div className="flex flex-row items-center justify-between">
<p className="font-bold text-lg font-sans-display">
Local Account:{' '}
<span className="text-primary">{geohash}</span>
</p>
<p className="font-thin underline">
{truncateAddress(id, 6)}
</p>
<ConnectedLocalAccount />
<div className="grid grid-cols-2 gap-2">
{agent?.records.map((record) => {
return (
<div
onClick={() => {
switchLocalAccount(record.geohash)
}}
key={record.geohash}
className="flex flex-col gap-2 p-2 text-base-content rounded-md select-none bg-neutral-900 hover:cursor-pointer hover:bg-neutral-700"
>
<div className="flex flex-row items-center justify-between">
<p className="font-bold text-lg font-sans-display">
Local Account:{' '}
<span className="text-primary">
{record.geohash}
</span>
</p>
</div>
</div>
<AccountNFTs account={id} />
</div>
)
})}
)
})}
</div>
</div>
),
},
Expand Down
49 changes: 49 additions & 0 deletions apps/web/components/ConnectedLocalAccount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { useLocalAccount } from '@instate/kit'
import AccountNFTs from './LocalAccountNFTs'
import { truncateAddress } from '@/services/utils'
import useChain from '@/hooks/useChain'
import Link from 'next/link'

const ConnectedLocalAccount = ({}) => {
const { localAccount } = useLocalAccount()
const { chain } = useChain()

return (
<div className="bg-neutral-900 rounded-md p-4">
<div className="flex flex-row justify-between items-center border-b pb-2 mb-2 border-base-100">
<p className="font-bold text-lg font-sans-display">
Connected Local Account:{' '}
<span className="text-primary">{localAccount?.geohash}</span>
</p>
{localAccount && (
<Link
className="btn btn-outline btn-sm flex flex-row items-center gap-2 px-2"
href={
chain?.blockExplorers?.default.url +
'/address/' +
localAccount?.id
}
target="_blank"
>
<div className=" relative">
<svg
width="123"
height="123"
viewBox="0 0 123 123"
className="fill-current w-4 h-4"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M25.79 58.4149C25.7901 57.7357 25.9244 57.0633 26.1851 56.4361C26.4458 55.809 26.8278 55.2396 27.3092 54.7605C27.7907 54.2814 28.3619 53.9021 28.9903 53.6444C29.6187 53.3867 30.2918 53.2557 30.971 53.2589L39.561 53.2869C40.9305 53.2869 42.244 53.831 43.2124 54.7994C44.1809 55.7678 44.725 57.0813 44.725 58.4509V90.9309C45.692 90.6439 46.934 90.3379 48.293 90.0179C49.237 89.7962 50.0783 89.262 50.6805 88.5019C51.2826 87.7418 51.6102 86.8006 51.61 85.8309V45.5409C51.61 44.1712 52.154 42.8576 53.1224 41.889C54.0908 40.9204 55.4043 40.3762 56.774 40.3759H65.381C66.7506 40.3762 68.0641 40.9204 69.0325 41.889C70.0009 42.8576 70.545 44.1712 70.545 45.5409V82.9339C70.545 82.9339 72.7 82.0619 74.799 81.1759C75.5787 80.8462 76.2441 80.2941 76.7122 79.5886C77.1803 78.8832 77.4302 78.0555 77.431 77.2089V32.6309C77.431 31.2615 77.9749 29.9481 78.9431 28.9797C79.9113 28.0113 81.2245 27.4672 82.5939 27.4669H91.201C92.5706 27.4669 93.884 28.0109 94.8525 28.9794C95.8209 29.9478 96.365 31.2613 96.365 32.6309V69.3399C103.827 63.9319 111.389 57.4279 117.39 49.6069C118.261 48.4717 118.837 47.1386 119.067 45.7267C119.297 44.3148 119.174 42.8678 118.709 41.5149C115.931 33.5227 111.516 26.1983 105.745 20.0105C99.974 13.8228 92.9749 8.90785 85.1955 5.58032C77.4161 2.2528 69.0277 0.585938 60.5671 0.686416C52.1065 0.786893 43.7601 2.6525 36.062 6.16383C28.3638 9.67517 21.4834 14.7549 15.8611 21.078C10.2388 27.401 5.99842 34.8282 3.41131 42.8842C0.824207 50.9401 -0.0526487 59.4474 0.836851 67.8617C1.72635 76.276 4.36263 84.4119 8.57696 91.7489C9.31111 93.0145 10.3912 94.0444 11.6903 94.7175C12.9894 95.3906 14.4536 95.679 15.911 95.5489C17.539 95.4059 19.566 95.2029 21.976 94.9199C23.0251 94.8008 23.9937 94.2999 24.6972 93.5126C25.4008 92.7253 25.7901 91.7067 25.791 90.6509L25.79 58.4149Z" />
<path d="M25.6021 110.51C34.6744 117.11 45.3959 121.072 56.5802 121.957C67.7646 122.841 78.9757 120.615 88.9731 115.523C98.9705 110.431 107.364 102.673 113.226 93.1068C119.087 83.5405 122.188 72.539 122.185 61.3197C122.185 59.9197 122.12 58.5347 122.027 57.1577C99.808 90.2957 58.7831 105.788 25.604 110.505" />
</svg>
</div>
<p className="text-sm">{truncateAddress(localAccount?.id, 6)}</p>
</Link>
)}
</div>
<AccountNFTs account={localAccount?.id} />
</div>
)
}

export default ConnectedLocalAccount
13 changes: 12 additions & 1 deletion apps/web/components/LocalAccountNFTs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,23 @@ import { OwnedNft } from 'alchemy-sdk'
import { useEffect, useState } from 'react'
import { getAlchemyNFT } from 'shared-config'

const AccountNFTs = ({ account }: { account: string }) => {
const AccountNFTs = ({ account }: { account?: string }) => {
const { chainId } = useChain()
const [nfts, setNfts] = useState<OwnedNft[] | null>(null)
const [nftsLoading, setNftsLoading] = useState(false)

const fetchNFTs = async () => {
if (!account) return

setNftsLoading(true)

const nfts = getAlchemyNFT(chainId)

const { ownedNfts } = await nfts.getNftsForOwner(account)

setNfts(ownedNfts)

setNftsLoading(false)
}

useEffect(() => {
Expand All @@ -36,6 +43,10 @@ const AccountNFTs = ({ account }: { account: string }) => {
</div>
)
})
) : nftsLoading ? (
<div className="w-full text-center">
<span className="loading loading-spinner bg-primary loading-xs"></span>
</div>
) : (
<p>Nothing here yet</p>
)}
Expand Down
14 changes: 3 additions & 11 deletions apps/web/components/Map/AccountMarker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ import { useEffect } from 'react'
import { MapPinIcon } from '@heroicons/react/24/outline'
import { useAccount } from 'wagmi'
import classNames from 'classnames'
import { emojiAvatarForAddress, useLocalAccount } from '@instate/kit'
import { emojiAvatarForAddress } from '@instate/kit'
import usePath from '@/hooks/usePath'
import useMapUtils from '@/hooks/useMapUtils'
import AccountZoomEffects from './AccountZoomEffects'

const AccountMarker = () => {
const { isProfile } = usePath()
const { localAccount } = useLocalAccount()
const { flyToGeohash } = useMapUtils()

const { address } = useAccount()
const {
Expand All @@ -23,13 +21,6 @@ const AccountMarker = () => {
updatePosition(latitude, longitude)
}, [])

useEffect(() => {
const { geohash } = localAccount || {}
if (geohash) {
flyToGeohash(geohash, 3)
}
}, [localAccount])

if (!isProfile) return null

return (
Expand Down Expand Up @@ -57,6 +48,7 @@ const AccountMarker = () => {
<MapPinIcon className="w-6 h-6 text-gray-800" />
)}
</div>
<AccountZoomEffects />
</Marker>
)
}
Expand Down
10 changes: 1 addition & 9 deletions apps/web/components/Map/AccountZoomEffects.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
import { usePosition } from '@/hooks/usePosition'
import { commonLocations } from '@/services/constants'
import { precisionToZoom } from '@/services/map_utils'
import { useEffect } from 'react'
import { useMap } from 'react-map-gl'

const AccountZoomEffects = () => {
const {
position: { precision, latitude, longitude },
position: { precision },
} = usePosition()
const { mainMap } = useMap()

useEffect(() => {
if (precision) {
mainMap?.flyTo({
center: [longitude, latitude],
zoom: precisionToZoom[precision],
speed: 5,
})
}
return () => {
mainMap?.flyTo({
center: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,29 @@ import classNames from 'classnames'
import MoveButton from './MoveButton'
import { useAccount } from 'wagmi'
import useAppAgent from '@/hooks/useAppAgent'
import useAppAddresses from '@/hooks/useAppAddresses'
import { usePathname } from 'next/navigation'
import AccountZoomEffects from './Map/AccountZoomEffects'
import { NetworkStateQuery } from '@instate/kit'
import { useEffect } from 'react'
import useMapUtils from '@/hooks/useMapUtils'

const AppMapControls = () => {
const { stateTile } = useAppAddresses()
type NetworkStateMotionProps = {
currentNetworkState: NetworkStateQuery['networkState']
}

const NetworkStateMotion = ({
currentNetworkState,
}: NetworkStateMotionProps) => {
const { flyToGeohash } = useMapUtils()
const { address } = useAccount()
const { setPrecision, position } = usePosition()
const { geohashes, refetch } = useAppAgent()

useEffect(() => {
flyToGeohash(position.geohash)
}, [position.precision])

return (
<div className="flex flex-row justify-between gap-4 items-center bg-opacity-90 p-3 bg-neutral rounded-lg">
<AccountZoomEffects />
<div className="flex flex-row items-center w-full gap-2 justify-between font-display">
<div className="border border-primary p-2 rounded-md">
<p className="text-xl">{position.geohash}</p>
</div>
</div>
<div className="flex flex-row justify-between gap-4 items-center ">
<p className="text-xl">Motion:</p>
<div className="font-display w-full flex flex-row items-center">
<div className="flex-grow ml-10">
<input
Expand Down Expand Up @@ -49,7 +54,7 @@ const AppMapControls = () => {
<div className="w-full flex flex-row justify-end">
<MoveButton
address={address}
tile={stateTile}
tile={currentNetworkState?.id}
geohash={position.geohash}
disabled={geohashes.includes(position.geohash)}
onMoveSuccess={() => {
Expand All @@ -61,14 +66,4 @@ const AppMapControls = () => {
)
}

/**
* NOTE: Could move to vite app, NextJS slot routing is a hellhole
* @returns
*/
const AppMapControlsRouted = () => {
const pathName = usePathname()

return pathName.includes('/profile') ? <AppMapControls /> : null
}

export default AppMapControlsRouted
export default NetworkStateMotion
14 changes: 8 additions & 6 deletions apps/web/components/SelectedLocalDrop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,12 @@ const LocalDropButtons = ({
<div>
{!canMint && (
<>
<p className="text-sm mb-1 text-justify">
You&apos;ve never visted this location, create your local account
now:
</p>
{localCase === 'create-account' && (
<p className="text-sm mb-1 text-justify">
You&apos;ve never visted this location, create your local
account now:
</p>
)}
<button
onClick={() => {
if (localCase === 'create-account') {
Expand All @@ -120,7 +122,7 @@ const LocalDropButtons = ({
}
}}
disabled={createAccountLoading}
className="btn btn-primary btn-sm w-full"
className="btn btn-primary w-full"
>
{createAccountLoading && (
<span className="loading loading-spinner bg-primary loading-xs"></span>
Expand Down Expand Up @@ -192,7 +194,7 @@ const MintButton = ({
onClick={() => {
write && write()
}}
className="btn btn-primary btn-sm w-full"
className="btn btn-primary w-full"
>
{(pendingConfirm || pendingTx) && (
<span className="loading loading-spinner bg-primary loading-xs"></span>
Expand Down
Loading

0 comments on commit 4054ef4

Please sign in to comment.