kopia lustrzana https://github.com/cloudflare/wildebeest
create reusable StatusAccountCard component
rodzic
aa21606df1
commit
bed859f737
|
@ -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" />
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
})
|
|
@ -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>
|
||||
)
|
||||
})
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -87,6 +87,7 @@ export default component$(() => {
|
|||
url: url.toString(),
|
||||
}}
|
||||
secondary={null}
|
||||
withLinks={true}
|
||||
/>
|
||||
</div>
|
||||
<p class="col-start-2">Signed in as:</p>
|
||||
|
|
|
@ -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">
|
||||
|
|
Ładowanie…
Reference in New Issue