Skip to content

Commit

Permalink
✨ Toggleable preview cards in event viewer (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
foysalit authored Aug 21, 2024
1 parent 1386153 commit ea6f0ff
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 31 deletions.
37 changes: 24 additions & 13 deletions components/mod-event/EventItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '@atproto/api'
import { ItemTitle } from './ItemTitle'
import { MessageContext } from '@/dms/MessageContext'
import { PreviewCard } from '@/common/PreviewCard'

const LinkToAuthor = ({
creatorHandle,
Expand Down Expand Up @@ -41,7 +42,7 @@ const Comment = ({
}
}) => {
return (
<Card>
<>
<div className="flex justify-between text-gray-500">
<span>
By{' '}
Expand All @@ -67,7 +68,7 @@ const Comment = ({
header="Removed: "
labels={modEvent.event.negateLabelVals as string[] | undefined}
/>
</Card>
</>
)
}

Expand All @@ -79,7 +80,7 @@ const Email = ({
}
}) => {
return (
<Card>
<>
<p className="text-gray-500">
By{' '}
{modEvent.creatorHandle
Expand All @@ -90,7 +91,7 @@ const Email = ({
<p>Subject: {modEvent.event.subjectLine}</p>
)}
{modEvent.event.comment && <p>{modEvent.event.comment}</p>}
</Card>
</>
)
}

Expand All @@ -110,7 +111,7 @@ const Report = ({
const isAppeal =
modEvent.event.reportType === ComAtprotoModerationDefs.REASONAPPEAL
return (
<Card>
<>
<div className="flex justify-between">
<span>
By{' '}
Expand All @@ -137,7 +138,7 @@ const Report = ({
{isMessageSubject(modEvent.subject) && (
<MessageContext className="mt-3" subject={modEvent.subject} />
)}
</Card>
</>
)
}

Expand All @@ -153,7 +154,7 @@ const TakedownOrMute = ({
}) => {
const expiresAt = getExpiresAtFromEvent(modEvent)
return (
<Card>
<>
<div className="flex justify-between">
<span>
By{' '}
Expand Down Expand Up @@ -189,7 +190,7 @@ const TakedownOrMute = ({
header="Removed: "
labels={modEvent.event.negateLabelVals as string[] | undefined}
/>
</Card>
</>
)
}

Expand Down Expand Up @@ -236,7 +237,7 @@ const Label = ({
} & ToolsOzoneModerationDefs.ModEventView
}) => {
return (
<Card>
<>
<p>
<span>
By{' '}
Expand All @@ -250,7 +251,7 @@ const Label = ({
) : null}
<EventLabels header="Added: " labels={modEvent.event.createLabelVals} />
<EventLabels header="Removed: " labels={modEvent.event.negateLabelVals} />
</Card>
</>
)
}

Expand All @@ -262,7 +263,7 @@ const Tag = ({
} & ToolsOzoneModerationDefs.ModEventView
}) => {
return (
<Card>
<>
<p>
<span>
By{' '}
Expand All @@ -276,7 +277,7 @@ const Tag = ({
) : null}
<EventLabels isTag header="Added: " labels={modEvent.event.add} />
<EventLabels isTag header="Removed: " labels={modEvent.event.remove} />
</Card>
</>
)
}

Expand All @@ -300,10 +301,12 @@ export const ModEventItem = ({
modEvent,
showContentDetails,
showContentAuthor,
showContentPreview,
}: {
modEvent: ToolsOzoneModerationDefs.ModEventView
showContentDetails: boolean
showContentAuthor: boolean
showContentPreview: boolean
}) => {
let eventItem: JSX.Element = <p>{modEvent.event.$type as string}</p>
if (
Expand Down Expand Up @@ -341,10 +344,18 @@ export const ModEventItem = ({
//@ts-ignore
eventItem = <Email modEvent={modEvent} />
}
const previewSubject = modEvent.subject.uri || modEvent.subject.did
return (
<div className="mt-4">
<ItemTitle {...{ modEvent, showContentDetails, showContentAuthor }} />
{eventItem}
<Card>
{eventItem}
{typeof previewSubject === 'string' && showContentPreview && (
<div className="border-t dark:border-gray-500 mt-2">
<PreviewCard subject={previewSubject} />
</div>
)}
</Card>
</div>
)
}
58 changes: 41 additions & 17 deletions components/mod-event/EventList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { ArchiveBoxXMarkIcon, ChevronDownIcon } from '@heroicons/react/20/solid'
import { getSubjectTitle } from './helpers/subject'
import { useState } from 'react'
import { ActionButton } from '@/common/buttons'
import { FunnelIcon as FunnelEmptyIcon } from '@heroicons/react/24/outline'
import {
FunnelIcon as FunnelEmptyIcon,
EyeSlashIcon,
EyeIcon,
} from '@heroicons/react/24/outline'
import { FunnelIcon as FunnelFilledIcon } from '@heroicons/react/24/solid'
import { EventFilterPanel } from './FilterPanel'

Expand Down Expand Up @@ -80,16 +84,20 @@ export const ModEventList = (
oldestFirst,
createdAfter,
createdBefore,
showContentPreview,
applyFilterMacro,
changeListFilter,
resetListFilters,
toggleContentPreview,
} = useModEventList(props)

const [showFiltersPanel, setShowFiltersPanel] = useState(false)
const isEntireHistoryView = !props.subject && !props.createdBy
const subjectTitle = getSubjectTitle(modEvents?.[0]?.subject)
const noEvents = modEvents.length === 0 && !isInitialLoadingModEvents
const isShowingEventsByCreator = !!props.createdBy
const isMultiSubjectView =
includeAllUserRecords || isEntireHistoryView || isShowingEventsByCreator
return (
<div className="mr-1">
<div className="flex flex-row justify-between items-center">
Expand All @@ -111,18 +119,35 @@ export const ModEventList = (
Moderation event stream
</h4>
)}
<ActionButton
size="xs"
appearance="outlined"
onClick={() => setShowFiltersPanel((current) => !current)}
>
{hasFilter ? (
<FunnelFilledIcon className="h-3 w-3 mr-1" />
) : (
<FunnelEmptyIcon className="h-3 w-3 mr-1" />
<div className="flex flex-row">
{isMultiSubjectView && (
<ActionButton
size="xs"
className="mr-2"
appearance="outlined"
title="Show record content preview for each event"
onClick={() => toggleContentPreview()}
>
{showContentPreview ? (
<EyeSlashIcon className="h-3 w-3 mx-1" />
) : (
<EyeIcon className="h-3 w-3 mx-1" />
)}
</ActionButton>
)}
<span className="text-xs">Configure</span>
</ActionButton>
<ActionButton
size="xs"
appearance="outlined"
onClick={() => setShowFiltersPanel((current) => !current)}
>
{hasFilter ? (
<FunnelFilledIcon className="h-3 w-3 mr-1" />
) : (
<FunnelEmptyIcon className="h-3 w-3 mr-1" />
)}
<span className="text-xs">Configure</span>
</ActionButton>
</div>
</div>
{showFiltersPanel && (
<EventFilterPanel
Expand Down Expand Up @@ -177,11 +202,10 @@ export const ModEventList = (
// may be reporting different subjects
isEntireHistoryView || isShowingEventsByCreator
}
showContentDetails={
includeAllUserRecords ||
isEntireHistoryView ||
isShowingEventsByCreator
}
// When the event history is being displayed for a single record/subject
// there's no point showing the preview in each event
showContentPreview={showContentPreview && isMultiSubjectView}
showContentDetails={isMultiSubjectView}
/>
)
})
Expand Down
2 changes: 1 addition & 1 deletion components/mod-event/FilterPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const EventFilterPanel = ({
toggleCommentFilter,
setCommentFilterKeyword,
changeListFilter,
}: Omit<EventListState, 'includeAllUserRecords'> &
}: Omit<EventListState, 'includeAllUserRecords' | 'showContentPreview'> &
Pick<
ReturnType<typeof useModEventList>,
| 'changeListFilter'
Expand Down
8 changes: 8 additions & 0 deletions components/mod-event/useModEventList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const initialListState = {
removedLabels: [],
addedTags: '',
removedTags: '',
showContentPreview: false,
}

// The 2 fields need overriding because in the initialState, they are set as undefined so the alternative string type is not accepted without override
Expand All @@ -51,6 +52,7 @@ export type EventListState = Omit<
reportTypes: string[]
addedLabels: string[]
removedLabels: string[]
showContentPreview: boolean
}

type EventListFilterPayload =
Expand Down Expand Up @@ -80,6 +82,9 @@ type EventListAction =
| {
type: 'RESET'
}
| {
type: 'TOGGLE_CONTENT_PREVIEW'
}

const eventListReducer = (state: EventListState, action: EventListAction) => {
switch (action.type) {
Expand All @@ -96,6 +101,8 @@ const eventListReducer = (state: EventListState, action: EventListAction) => {
return { ...state, ...action.payload }
case 'RESET':
return initialListState
case 'TOGGLE_CONTENT_PREVIEW':
return { ...state, showContentPreview: !state.showContentPreview }
default:
return state
}
Expand Down Expand Up @@ -246,6 +253,7 @@ export const useModEventList = (
applyFilterMacro: (payload: Partial<EventListState>) =>
dispatch({ type: 'SET_FILTERS', payload }),
resetListFilters: () => dispatch({ type: 'RESET' }),
toggleContentPreview: () => dispatch({ type: 'TOGGLE_CONTENT_PREVIEW' }),

// State data
...listState,
Expand Down

0 comments on commit ea6f0ff

Please sign in to comment.