create reusable StatusAccountCard component

pull/300/head
Dario Piotrowicz 2023-02-16 12:54:19 +00:00
rodzic aa21606df1
commit bed859f737
6 zmienionych plików z 54 dodań i 51 usunięć

Wyświetl plik

@ -1,12 +1,12 @@
import { component$, $, useStyles$ } from '@builder.io/qwik'
import { Link, useNavigate } from '@builder.io/qwik-city'
import { formatTimeAgo } from '~/utils/dateTime'
import { Avatar } from '../avatar'
import type { Account, MastodonStatus } from '~/types'
import styles from '../../utils/innerHtmlContent.scss?inline'
import { MediaGallery } from '../MediaGallery.tsx'
import { useAccountUrl } from '~/utils/useAccountUrl'
import { getDisplayNameElement } from '~/utils/getDisplayNameElement'
import { StatusAccountCard } from '../StatusAccountCard/StatusAccountCard'
type Props = {
status: MastodonStatus
@ -29,17 +29,7 @@ export default component$((props: Props) => {
<RebloggerLink account={reblogger}></RebloggerLink>
<div onClick$={handleContentClick}>
<div class="flex justify-between mb-3">
<div class="flex">
<Avatar primary={status.account} secondary={reblogger} />
<div class="flex-col ml-3">
<div>
<Link class="no-underline" href={accountUrl}>
{getDisplayNameElement(status.account)}
</Link>
</div>
<div class="text-wildebeest-500">@{status.account.username}</div>
</div>
</div>
<StatusAccountCard status={status} subText="username" secondaryAvatar={reblogger} />
<Link class="no-underline" href={statusUrl}>
<div class="text-wildebeest-500 flex items-baseline">
<i style={{ height: '0.75rem', width: '0.75rem' }} class="fa fa-xs fa-globe w-3 h-3" />

Wyświetl plik

@ -0,0 +1,29 @@
import { component$ } from '@builder.io/qwik'
import { Link } from '@builder.io/qwik-city'
import { type MastodonStatus } from '~/types'
import { getDisplayNameElement } from '~/utils/getDisplayNameElement'
import { useAccountUrl } from '~/utils/useAccountUrl'
import { Avatar, type AvatarDetails } from '../avatar'
export const StatusAccountCard = component$<{
status: MastodonStatus
subText: 'username' | 'acct'
secondaryAvatar?: AvatarDetails | null
}>(({ status, subText, secondaryAvatar }) => {
const accountUrl = useAccountUrl(status.account)
return (
<Link
href={accountUrl}
class="inline-grid grid-cols-[repeat(2,_max-content)] grid-rows-[1fr,1fr] items-center no-underline"
>
<div class="row-span-2">
<Avatar primary={status.account} secondary={secondaryAvatar ?? null} />
</div>
<div class="ml-2 col-start-2 row-start-1">{getDisplayNameElement(status.account)}</div>
<div class="ml-2 text-wildebeest-400 col-start-2 row-start-2">
@{subText === 'username' ? status.account.username : status.account.acct}
</div>
</Link>
)
})

Wyświetl plik

@ -1,32 +1,35 @@
import { component$ } from '@builder.io/qwik'
import { Link } from '@builder.io/qwik-city'
import type { Account } from '~/types'
import { useAccountUrl } from '~/utils/useAccountUrl'
type AvatarDetails = Partial<Pick<Account, 'id'>> & Pick<Account, 'display_name' | 'avatar' | 'url'>
export type AvatarDetails = Partial<Pick<Account, 'id'>> & Pick<Account, 'display_name' | 'avatar' | 'url'>
type Props = {
primary: AvatarDetails
secondary: AvatarDetails | null
withLinks?: boolean
}
export const Avatar = component$<Props>(({ primary, secondary }) => {
export const Avatar = component$<Props>(({ primary, secondary, withLinks }) => {
const primaryUrl = useAccountUrl(primary)
const secondaryUrl = useAccountUrl(secondary)
// eslint-disable-next-line qwik/single-jsx-root
const primaryImg = <img class="rounded h-12 w-12" src={primary.avatar} alt={`Avatar of ${primary.display_name}`} />
const secondaryImg = (
<img
class="absolute right-0 bottom-0 rounded h-6 w-6"
src={secondary?.avatar}
alt={`Avatar of ${secondary?.display_name}`}
/>
)
return (
<div class={`relative ${secondary && 'pr-2 pb-2'}`}>
<a href={primaryUrl}>
<img class="rounded h-12 w-12" src={primary.avatar} alt={`Avatar of ${primary.display_name}`} />
</a>
{secondary && (
<a href={secondaryUrl}>
<img
class="absolute right-0 bottom-0 rounded h-6 w-6"
src={secondary.avatar}
alt={`Avatar of ${secondary.display_name}`}
/>
</a>
)}
{withLinks ? <Link href={primaryUrl}>{primaryImg}</Link> : primaryImg}
{secondary && (withLinks ? <Link href={secondaryUrl}>{secondaryImg}</Link> : secondaryImg)}
</div>
)
})

Wyświetl plik

@ -5,8 +5,8 @@ export const george = generateDummyAccount({
username: 'george',
acct: 'george_george@dummy.users.wildebeest.com',
display_name: 'George :verified: 👍',
avatar: getAvatarUrl(805),
avatar_static: getAvatarUrl(805),
avatar: getAvatarUrl(837),
avatar_static: getAvatarUrl(837),
})
export const zak = generateDummyAccount({

Wyświetl plik

@ -87,6 +87,7 @@ export default component$(() => {
url: url.toString(),
}}
secondary={null}
withLinks={true}
/>
</div>
<p class="col-start-2">Signed in as:</p>

Wyświetl plik

@ -5,17 +5,15 @@ import { formatDateTime } from '~/utils/dateTime'
import { formatRoundedNumber } from '~/utils/numbers'
import * as statusAPI from 'wildebeest/functions/api/v1/statuses/[id]'
import * as contextAPI from 'wildebeest/functions/api/v1/statuses/[id]/context'
import { DocumentHead, Link, loader$ } from '@builder.io/qwik-city'
import { DocumentHead, loader$ } from '@builder.io/qwik-city'
import StickyHeader from '~/components/StickyHeader/StickyHeader'
import { Avatar } from '~/components/avatar'
import { MediaGallery } from '~/components/MediaGallery.tsx'
import { getNotFoundHtml } from '~/utils/getNotFoundHtml/getNotFoundHtml'
import { getErrorHtml } from '~/utils/getErrorHtml/getErrorHtml'
import styles from '../../../../utils/innerHtmlContent.scss?inline'
import { getTextContent } from 'wildebeest/backend/src/activitypub/objects'
import { getDocumentHead } from '~/utils/getDocumentHead'
import { useAccountUrl } from '~/utils/useAccountUrl'
import { getDisplayNameElement } from '~/utils/getDisplayNameElement'
import { StatusAccountCard } from '~/components/StatusAccountCard/StatusAccountCard'
export const statusLoader = loader$<
{ DATABASE: D1Database },
@ -57,7 +55,7 @@ export default component$(() => {
<>
<StickyHeader withBackButton />
<div class="bg-wildebeest-700 p-4">
<AccountCard status={loaderData.status} />
<StatusAccountCard subText="acct" status={loaderData.status} />
<div class="leading-normal inner-html-content text-lg" dangerouslySetInnerHTML={loaderData.status.content} />
<MediaGallery medias={loaderData.status.media_attachments} />
@ -73,24 +71,6 @@ export default component$(() => {
)
})
export const AccountCard = component$<{ status: MastodonStatus }>(({ status }) => {
const accountUrl = useAccountUrl(status.account)
return (
<div class="flex">
<Avatar primary={status.account} secondary={null} />
<div class="flex flex-col">
<div class="p-1">
<Link href={accountUrl} class="no-underline">
{getDisplayNameElement(status.account)}
</Link>
</div>
<div class="p-1 text-wildebeest-400">@{status.account.acct}</div>
</div>
</div>
)
})
export const InfoTray = component$<{ status: MastodonStatus }>(({ status }) => {
return (
<div class="text-wildebeest-500 mt-4 text-sm">