feat: display loading state and correctly wait for the content when opening persona, posts or chats (#403)

This commit is contained in:
Vojtech Simetka 2023-04-05 18:57:17 +02:00 committed by GitHub
parent b719aeac73
commit 7c660ea15c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 117 additions and 27 deletions

View File

@ -352,6 +352,16 @@ export class Firebase implements Adapter {
}
async subscribePersonaPosts(groupId: string): Promise<() => unknown> {
// Sets loading to true if the data is not yet retrieved
posts.update(({ data }) => {
const personaPostData = data.get(groupId)
if (!personaPostData) {
data.set(groupId, { approved: [], pending: [], loading: true, error: undefined })
}
return { data }
})
const pendingCollection = collection(db, `personas/${groupId}/pending`)
const postsCollection = collection(db, `personas/${groupId}/posts`)

View File

@ -25,6 +25,7 @@ interface ChatData {
loading: boolean
unread: number
chats: Map<string, Chat>
error?: Error
}
export type ChatStore = Writable<ChatData>

View File

@ -27,6 +27,7 @@ type PersonaStore = {
favorite: string[]
all: Map<string, Persona>
loading: boolean
error?: Error
}
function createPersonaStore(): Writable<PersonaStore> {

View File

@ -16,7 +16,7 @@ export interface PostPending extends Post {
}
interface PostData {
data: Map<string, { approved: Post[]; pending: PostPending[]; loading: boolean }>
data: Map<string, { approved: Post[]; pending: PostPending[]; loading: boolean; error?: Error }>
}
export interface PostStore extends Writable<PostData> {

View File

@ -5,13 +5,19 @@
import adapter from '$lib/adapters'
import ChatScreen from '$lib/components/chat-screen.svelte'
import Container from '$lib/components/container.svelte'
import InfoBox from '$lib/components/info-box.svelte'
import Wallet from '$lib/components/icons/wallet.svelte'
import { ROUTES } from '$lib/routes'
import { chats, type Chat } from '$lib/stores/chat'
import { chats } from '$lib/stores/chat'
import { profile } from '$lib/stores/profile'
import { onDestroy, onMount } from 'svelte'
import Button from '$lib/components/button.svelte'
import { canConnectWallet } from '$lib/services'
const chatId = $page.params.chatId
let chat: Chat | undefined
$: chat = $chats.chats.get(chatId)
let unsubscribe: undefined | (() => unknown)
onMount(async () => {
@ -25,11 +31,40 @@
function sendMessage(text: string) {
adapter.sendChatMessage(chatId, text)
}
$: chat = $chats.chats.get(chatId)
</script>
{#if chat === undefined}
{#if $profile.signer === undefined}
<Container>
<InfoBox>
<Button
variant="primary"
icon={Wallet}
label="Connect wallet"
on:click={adapter.signIn}
disabled={!canConnectWallet()}
/>
<span class="connect-info">
{#if canConnectWallet()}
Please connect wallet to check the chat.
{:else}
Please install a web3 wallet to access the chat.
{/if}
</span>
</InfoBox>
</Container>
{:else if $chats.loading}
<Container>
<InfoBox>
<div>Loading...</div>
</InfoBox>
</Container>
{:else if $chats.error}
<Container>
<InfoBox>
<div>Something went wrong</div>
</InfoBox>
</Container>
{:else if chat === undefined}
<div>There is no chat</div>
{:else}
<ChatScreen
@ -39,6 +74,3 @@
onBack={() => goto(ROUTES.CHATS)}
/>
{/if}
<style lang="scss">
</style>

View File

@ -37,8 +37,8 @@
}
const groupId = $page.params.id
const persona = $personas.all.get(groupId)
let personaPosts = $posts.data.get(groupId)
$: persona = $personas.all.get(groupId)
$: personaPosts = $posts.data.get(groupId)
let sortAsc = false
let sortBy: SortBy = 'date'
let filterQuery = ''
@ -62,13 +62,23 @@
const addToFavorite = () => adapter.addPersonaToFavorite(groupId, persona)
const removeFromFavorite = () => adapter.removePersonaFromFavorite(groupId, persona)
$: personaPosts = $posts.data.get(groupId)
</script>
<svelte:window bind:scrollY={y} />
{#if persona === undefined}
{#if $personas.loading || personaPosts?.loading}
<Container>
<InfoBox>
<div>Loading...</div>
</InfoBox>
</Container>
{:else if $personas.error || personaPosts?.error}
<Container>
<InfoBox>
<div>Something went wrong</div>
</InfoBox>
</Container>
{:else if persona === undefined}
<Container>
<InfoBox>
<div>There is no persona with group ID {groupId}</div>

View File

@ -46,8 +46,8 @@
}
const groupId = $page.params.id
const persona = $personas.all.get(groupId)
let personaPosts = $posts.data.get(groupId)
$: persona = $personas.all.get(groupId)
$: personaPosts = $posts.data.get(groupId)
let sortAsc = false
let sortBy: SortBy = 'date'
let filterQuery = ''
@ -74,13 +74,23 @@
})
let y: number
$: personaPosts = $posts.data.get(groupId)
</script>
<svelte:window bind:scrollY={y} />
{#if persona === undefined}
{#if $personas.loading || personaPosts?.loading}
<Container>
<InfoBox>
<div>Loading...</div>
</InfoBox>
</Container>
{:else if $personas.error || personaPosts?.error}
<Container>
<InfoBox>
<div>Something went wrong</div>
</InfoBox>
</Container>
{:else if persona === undefined}
<Container>
<InfoBox>
<div>There is no persona with group ID {groupId}</div>

View File

@ -51,11 +51,13 @@
const postId = $page.params.postId
const groupId = $page.params.id
let post = $posts.data.get(groupId)?.pending.find((p) => p.postId === postId)
$: post = $posts.data.get(groupId)?.pending.find((p) => p.postId === postId)
const persona = $personas.all.get(groupId)
$: personaPosts = $posts.data.get(groupId)
$: post = personaPosts?.pending.find((p) => p.postId === postId)
$: persona = $personas.all.get(groupId)
let draftChat: DraftChat | undefined = undefined
$: console.log({ persona, post, personaPosts })
const startChat = async () => {
if (!persona || !post) return
@ -88,7 +90,19 @@
<Banner icon={Info}>Connect to see your GO balance</Banner>
{/if}
{#if post === undefined}
{#if $personas.loading || personaPosts?.loading}
<Container>
<InfoBox>
<div>Loading...</div>
</InfoBox>
</Container>
{:else if $personas.loading || personaPosts?.error}
<Container>
<InfoBox>
<div>Something went wrong</div>
</InfoBox>
</Container>
{:else if post === undefined}
<Container>
<InfoBox>
<div>There is no post with post ID {$page.params.postId}</div>

View File

@ -21,9 +21,9 @@
const postId = $page.params.postId
const groupId = $page.params.id
let post = $posts.data.get(groupId)?.approved.find((p) => p.postId === postId)
$: post = $posts.data.get(groupId)?.approved.find((p) => p.postId === postId)
const persona = $personas.all.get($page.params.id)
$: personaPosts = $posts.data.get(groupId)
$: post = personaPosts?.approved.find((p) => p.postId === postId)
$: persona = $personas.all.get(groupId)
let draftChat: DraftChat | undefined = undefined
const startChat = async () => {
@ -59,7 +59,19 @@
<svelte:window bind:scrollY={y} />
{#if post === undefined}
{#if $personas.loading || personaPosts?.loading}
<Container>
<InfoBox>
<div>Loading...</div>
</InfoBox>
</Container>
{:else if $personas.loading || personaPosts?.error}
<Container>
<InfoBox>
<div>Something went wrong</div>
</InfoBox>
</Container>
{:else if post === undefined}
<Container>
<InfoBox>
<div>There is no post with post ID {$page.params.postId}</div>