Skip to content

Commit

Permalink
✨ Add video fallback url (#277)
Browse files Browse the repository at this point in the history
* ✨ Add video fallback url for deactivated accounts

* ✨ Add fallback for takendown accounts too

* ✨ Add fallback url in author feed
  • Loading branch information
foysalit authored Jan 10, 2025
1 parent 9ba1f47 commit 15dd68a
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 13 deletions.
4 changes: 4 additions & 0 deletions app/actions/ModActionPanel/QuickAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,10 @@ function Form(
<div className="max-w-xl">
<PreviewCard
subject={subject}
isAuthorDeactivated={!!record?.repo.deactivatedAt}
isAuthorTakendown={
!!record?.repo.moderation.subjectStatus?.takendown
}
className="border-2 border-dashed border-gray-300"
>
{!isSubjectDid && record?.repo && (
Expand Down
10 changes: 9 additions & 1 deletion components/common/PreviewCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ export function PreviewCard({
title,
children,
className,
isAuthorDeactivated,
isAuthorTakendown,
}: {
subject: string
isAuthorDeactivated?: boolean
isAuthorTakendown?: boolean
title?: string | ReactNode
children?: ReactNode
className?: string
Expand All @@ -41,7 +45,11 @@ export function PreviewCard({
<p className="text-sm font-medium text-gray-500 dark:text-gray-50 mb-3">
{displayTitle}
</p>
<RecordCard uri={subject} />
<RecordCard
uri={subject}
isAuthorDeactivated={isAuthorDeactivated}
isAuthorTakendown={isAuthorTakendown}
/>
{children}
</div>
)
Expand Down
37 changes: 33 additions & 4 deletions components/common/RecordCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,31 @@ import { ShieldCheckIcon } from '@heroicons/react/24/solid'
import { StarterPackRecordCard } from './starterpacks/RecordCard'
import { useLabelerAgent } from '@/shell/ConfigurationContext'

export function RecordCard(props: { uri: string; showLabels?: boolean }) {
const { uri, showLabels = false } = props
export function RecordCard(props: {
uri: string
showLabels?: boolean
isAuthorDeactivated?: boolean
isAuthorTakendown?: boolean
}) {
const {
uri,
showLabels = false,
isAuthorDeactivated,
isAuthorTakendown,
} = props
const parsed = parseAtUri(uri)
if (!parsed) {
return null
}
if (parsed.collection === CollectionId.Post) {
return <PostCard uri={uri} showLabels={showLabels} />
return (
<PostCard
uri={uri}
showLabels={showLabels}
isAuthorTakendown={isAuthorTakendown}
isAuthorDeactivated={isAuthorDeactivated}
/>
)
}
if (parsed.collection === CollectionId.FeedGenerator) {
return <FeedGeneratorRecordCard uri={uri} />
Expand Down Expand Up @@ -53,7 +70,17 @@ export function RecordCard(props: { uri: string; showLabels?: boolean }) {
)
}

function PostCard({ uri, showLabels }: { uri: string; showLabels?: boolean }) {
function PostCard({
uri,
showLabels,
isAuthorTakendown,
isAuthorDeactivated,
}: {
uri: string
showLabels?: boolean
isAuthorTakendown?: boolean
isAuthorDeactivated?: boolean
}) {
const labelerAgent = useLabelerAgent()

const { error, data } = useQuery({
Expand Down Expand Up @@ -118,6 +145,8 @@ function PostCard({ uri, showLabels }: { uri: string; showLabels?: boolean }) {
dense
showLabels={showLabels}
item={{ post: data.thread.post }}
isAuthorTakendown={isAuthorTakendown}
isAuthorDeactivated={isAuthorDeactivated}
controls={['like', 'repost', 'workspace']}
/>
)
Expand Down
6 changes: 6 additions & 0 deletions components/common/feeds/AuthorFeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,12 @@ export const useAuthorFeedQuery = ({
export function AuthorFeed({
id,
onReport,
isAuthorDeactivated,
isAuthorTakendown,
}: {
id: string
isAuthorDeactivated: boolean
isAuthorTakendown: boolean
onReport: (uri: string) => void
}) {
const [query, setQuery] = useState('')
Expand All @@ -154,6 +158,8 @@ export function AuthorFeed({
onLoadMore={hasNextPage ? () => fetchNextPage() : undefined}
typeFilter={typeFilter}
setTypeFilter={setTypeFilter}
isAuthorDeactivated={isAuthorDeactivated}
isAuthorTakendown={isAuthorTakendown}
/>
)
}
6 changes: 6 additions & 0 deletions components/common/posts/Posts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export function Posts({
setSearchQuery,
typeFilter,
setTypeFilter,
isAuthorDeactivated,
isAuthorTakendown,
}: {
isFromAppview?: boolean
items: AppBskyFeedDefs.FeedViewPost[]
Expand All @@ -36,6 +38,8 @@ export function Posts({
setSearchQuery: (query: string) => void
typeFilter: TypeFilterKey
setTypeFilter: (type: TypeFilterKey) => void
isAuthorDeactivated: boolean
isAuthorTakendown: boolean
}) {
const [mode, setMode] = useState<Mode>(Mode.Feed)

Expand Down Expand Up @@ -103,6 +107,8 @@ export function Posts({
{mode === Mode.Feed ? (
<div className="mx-auto max-w-3xl w-full py-2 sm:py-4 sm:px-6 lg:px-8">
<PostsFeed
isAuthorDeactivated={isAuthorDeactivated}
isAuthorTakendown={isAuthorTakendown}
items={items}
onReport={onReport}
onLoadMore={onLoadMore}
Expand Down
47 changes: 42 additions & 5 deletions components/common/posts/PostsFeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
} from '@/workspace/hooks'
import { ImageList } from './ImageList'
import { useGraphicMediaPreferences } from '@/config/useLocalPreferences'
import { getVideoUrlWithFallback } from '../video/helpers'
const VideoPlayer = dynamic(() => import('@/common/video/player'), {
ssr: false,
})
Expand All @@ -51,10 +52,14 @@ export function PostsFeed({
items,
onReport,
onLoadMore,
isAuthorDeactivated,
isAuthorTakendown,
}: {
items: AppBskyFeedDefs.FeedViewPost[]
onReport: (uri: string) => void
onLoadMore?: () => void
isAuthorDeactivated?: boolean
isAuthorTakendown?: boolean
}) {
return (
<div className="border border-gray-200 dark:border-slate-700 border-b-0">
Expand All @@ -63,7 +68,13 @@ export function PostsFeed({
key={`post-${i}`}
className="bg-white dark:bg-slate-800 border-b border-gray-200 dark:border-slate-700 pt-6 pb-4 px-4"
>
<PostAsCard item={item} onReport={onReport} dense />
<PostAsCard
item={item}
onReport={onReport}
dense
isAuthorDeactivated={isAuthorDeactivated}
isAuthorTakendown={isAuthorTakendown}
/>
</div>
))}
{onLoadMore && <LoadMore onLoadMore={onLoadMore} />}
Expand All @@ -87,10 +98,14 @@ export function PostAsCard({
onReport,
className = '',
showLabels = true,
isAuthorDeactivated,
isAuthorTakendown,
controls = [...PostControlOptions],
}: {
item: AppBskyFeedDefs.FeedViewPost
dense?: boolean
isAuthorDeactivated?: boolean
isAuthorTakendown?: boolean
controls?: PostControl[]
onReport?: (uri: string) => void
className?: string
Expand All @@ -100,7 +115,11 @@ export function PostAsCard({
<div className={`bg-white dark:bg-slate-800 ${className}`}>
<PostHeader item={item} dense={dense} />
<PostContent item={item} dense={dense} />
<PostEmbeds item={item} />
<PostEmbeds
item={item}
isAuthorTakendown={isAuthorTakendown}
isAuthorDeactivated={isAuthorDeactivated}
/>
{showLabels && <PostLabels item={item} dense={dense} />}
{!!controls?.length && (
<PostControls item={item} onReport={onReport} controls={controls} />
Expand Down Expand Up @@ -237,7 +256,15 @@ function PostContent({
const getImageSizeClass = (imageCount: number) =>
imageCount < 3 ? 'w-32 h-32' : 'w-20 h-20'

export function PostEmbeds({ item }: { item: AppBskyFeedDefs.FeedViewPost }) {
export function PostEmbeds({
item,
isAuthorTakendown,
isAuthorDeactivated,
}: {
isAuthorTakendown?: boolean
isAuthorDeactivated?: boolean
item: AppBskyFeedDefs.FeedViewPost
}) {
const { getMediaFiltersForLabels } = useGraphicMediaPreferences()
const embed = AppBskyEmbedRecordWithMedia.isView(item.post.embed)
? item.post.embed.media
Expand All @@ -254,11 +281,21 @@ export function PostEmbeds({ item }: { item: AppBskyFeedDefs.FeedViewPost }) {

if (AppBskyEmbedVideo.isView(embed)) {
const captions = item.post.record?.['embed']?.['captions']
const sourceUrl = getVideoUrlWithFallback(embed.playlist, {
isAuthorDeactivated,
isAuthorTakendown,
})
const thumbnailUrl = embed.thumbnail
? getVideoUrlWithFallback(embed.thumbnail, {
isAuthorDeactivated,
isAuthorTakendown,
})
: undefined
return (
<div className="flex gap-2 pb-2 pl-4" aria-label={embed.alt}>
<VideoPlayer
source={embed.playlist}
thumbnail={embed.thumbnail}
source={sourceUrl}
thumbnail={thumbnailUrl}
alt={embed.alt}
mediaFilters={mediaFilters}
captions={captions ? (captions as AppBskyEmbedVideo.Caption[]) : []}
Expand Down
17 changes: 17 additions & 0 deletions components/common/video/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { FALLBACK_VIDEO_URL } from '@/lib/constants'

export const getVideoUrlWithFallback = (
originalUri: string,
opts?: { isAuthorDeactivated?: boolean; isAuthorTakendown?: boolean },
): string => {
const [find, replace] = FALLBACK_VIDEO_URL
if (!find || !replace) {
return originalUri
}

if (!opts?.isAuthorDeactivated && !opts?.isAuthorTakendown) {
return originalUri
}

return originalUri.replace(find, replace)
}
24 changes: 21 additions & 3 deletions components/repositories/AccountView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,14 @@ export function AccountView({
<Details profile={profile} repo={repo} id={id} />
)}
{currentView === Views.Posts && (
<Posts id={id} onReport={setReportUri} />
<Posts
id={id}
onReport={setReportUri}
isAuthorTakendown={
!!repo.moderation?.subjectStatus?.takendown
}
isAuthorDeactivated={!!repo.deactivatedAt}
/>
)}
{currentView === Views.Follows && (
<Follows count={profile?.followsCount} id={id} />
Expand Down Expand Up @@ -640,7 +647,7 @@ function Details({
</LabelList>
</DataField>
<DataField label="Tags">
<LabelList className='flex-wrap gap-1'>
<LabelList className="flex-wrap gap-1">
{!tags.length && <LabelListEmpty />}
{tags.map((tag) => (
<SubjectTag key={tag} tag={tag} />
Expand Down Expand Up @@ -692,11 +699,22 @@ function Details({
function Posts({
id,
onReport,
isAuthorDeactivated,
isAuthorTakendown,
}: {
id: string
onReport: (uri: string) => void
isAuthorDeactivated: boolean
isAuthorTakendown: boolean
}) {
return <AuthorFeed id={id} onReport={onReport} />
return (
<AuthorFeed
id={id}
onReport={onReport}
isAuthorTakendown={isAuthorTakendown}
isAuthorDeactivated={isAuthorDeactivated}
/>
)
}

function Invites({ repo }: { repo: GetRepo.OutputSchema }) {
Expand Down
4 changes: 4 additions & 0 deletions lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ export const HIGH_PROFILE_FOLLOWER_THRESHOLD = process.env
.NEXT_PUBLIC_HIGH_PROFILE_FOLLOWER_THRESHOLD
? parseInt(process.env.NEXT_PUBLIC_HIGH_PROFILE_FOLLOWER_THRESHOLD)
: Infinity

export const FALLBACK_VIDEO_URL = (
process.env.NEXT_PUBLIC_FALLBACK_VIDEO_URL || ''
).split(':')

0 comments on commit 15dd68a

Please sign in to comment.