Skip to content

Commit

Permalink
:rightwards_twisted_arrows: Merge with upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
foysalit committed Dec 6, 2024
2 parents d2f56db + 7aab439 commit 602e706
Show file tree
Hide file tree
Showing 113 changed files with 8,708 additions and 1,576 deletions.
74 changes: 65 additions & 9 deletions app/actions/ModActionPanel/BlobList.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
import { ComponentProps } from 'react'
import { ComponentProps, useState } from 'react'
import { ToolsOzoneModerationDefs } from '@atproto/api'
import { ShieldExclamationIcon } from '@heroicons/react/20/solid'
import { formatBytes } from '@/lib/util'
import { formatBytes, pluralize } from '@/lib/util'
import { ReviewStateIconLink } from '@/subject/ReviewStateMarker'
import { FormLabel } from '@/common/forms'
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/solid'
import { BlobListLightbox } from '@/common/BlobListLightbox'
import { PropsOf } from '@/lib/types'

export function BlobList(props: {
name: string
disabled?: boolean
authorDid: string
blobs: ToolsOzoneModerationDefs.BlobView[]
}) {
const { name, disabled, blobs } = props
const [lightboxImageIndex, setLightboxImageIndex] = useState(-1)

return (
<fieldset className="space-y-5 min-w-0">
{!blobs.length && <div className="text-sm text-gray-400">None found</div>}
{blobs.map((blob) => {
{blobs.length > 0 ? (
<BlobListLightbox
blobs={blobs}
authorDid={props.authorDid}
slideIndex={lightboxImageIndex}
onClose={() => setLightboxImageIndex(-1)}
/>
) : (
<div className="text-sm text-gray-400">No blobs found</div>
)}
{blobs.map((blob, i) => {
const { subjectStatus } = blob.moderation ?? {}
const actionColorClasses = !!subjectStatus?.takendown
? 'text-rose-600 hover:text-rose-700'
: 'text-indigo-600 hover:text-indigo-900'
// TODO: May be add better display text here? this only goes into title so not that big of a deal
const displayActionType = subjectStatus?.takendown ? 'Taken down' : ''
return (
<div key={blob.cid} className="relative flex items-start">
<div className="flex h-5 items-center ml-1">
Expand Down Expand Up @@ -58,6 +69,14 @@ export function BlobList(props: {
{blob.details.height}x{blob.details.width}px
</Chip>
)}
<button
onClick={(e) => {
e.preventDefault()
setLightboxImageIndex(i)
}}
>
<Chip>View</Chip>
</button>
</p>
</div>
</div>
Expand All @@ -67,6 +86,43 @@ export function BlobList(props: {
)
}

export const BlobListFormField = ({
blobs,
authorDid,
...rest
}: {
authorDid: string
blobs: ToolsOzoneModerationDefs.BlobView[]
} & Omit<PropsOf<typeof FormLabel>, 'label'>) => {
const [showBlobList, setShowBlobList] = useState(false)

return (
<FormLabel
{...rest}
label={
<button
type="button"
className="flex flex-row items-center"
onClick={() => setShowBlobList(!showBlobList)}
>
{pluralize(blobs.length, 'Blob', {
includeCount: false,
})}
{!showBlobList ? (
<ChevronDownIcon className="w-4 h-4 ml-1 text-white" />
) : (
<ChevronUpIcon className="w-4 h-4 ml-1 text-white" />
)}
</button>
}
>
{showBlobList && (
<BlobList blobs={blobs} authorDid={authorDid} name="subjectBlobCids" />
)}
</FormLabel>
)
}

function Chip(props: ComponentProps<'span'>) {
const { className = '', ...others } = props
return (
Expand Down
104 changes: 74 additions & 30 deletions app/actions/ModActionPanel/QuickAction.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// TODO: This is badly named so that we can rebuild this component without breaking the old one
import { useQuery, useQueryClient } from '@tanstack/react-query'
import {
AtUri,
ComAtprotoModerationDefs,
ToolsOzoneModerationDefs,
ToolsOzoneModerationEmitEvent,
Expand All @@ -10,9 +11,8 @@ import { ActionPanel } from '@/common/ActionPanel'
import { ButtonPrimary, ButtonSecondary } from '@/common/buttons'
import { Checkbox, FormLabel, Input, Textarea } from '@/common/forms'
import { PropsOf } from '@/lib/types'
import { BlobList } from './BlobList'
import { BlobListFormField } from './BlobList'
import {
LabelChip,
LabelList,
LabelListEmpty,
diffLabels,
Expand All @@ -28,9 +28,11 @@ import {
ArrowLeftIcon,
ArrowRightIcon,
CheckCircleIcon,
ChevronDownIcon,
ChevronUpIcon,
} from '@heroicons/react/24/outline'
import { LabelSelector } from '@/common/labels/Selector'
import { takesKeyboardEvt } from '@/lib/util'
import { pluralize, takesKeyboardEvt } from '@/lib/util'
import { Loading } from '@/common/Loader'
import { ActionDurationSelector } from '@/reports/ModerationForm/ActionDurationSelector'
import { MOD_EVENTS } from '@/mod-event/constants'
Expand All @@ -54,6 +56,8 @@ import {
useLabelerAgent,
usePermission,
} from '@/shell/ConfigurationContext'
import { SubjectTag } from 'components/tags/SubjectTag'
import { HighProfileWarning } from '@/repositories/HighProfileWarning'

const FORM_ID = 'mod-action-panel'
const useBreakpoint = createBreakpoint({ xs: 340, sm: 640 })
Expand Down Expand Up @@ -167,7 +171,7 @@ function Form(
const { data: subjectStatus, refetch: refetchSubjectStatus } =
useSubjectStatusQuery(subject)

const { data: { record, repo } = {}, refetch: refetchSubject } =
const { data: { record, repo, profile } = {}, refetch: refetchSubject } =
useSubjectQuery(subject)

const isSubjectDid = subject.startsWith('did:')
Expand All @@ -189,8 +193,10 @@ function Form(
const isMuteEvent = modEventType === MOD_EVENTS.MUTE
const isMuteReporterEvent = modEventType === MOD_EVENTS.MUTE_REPORTER
const isCommentEvent = modEventType === MOD_EVENTS.COMMENT
const isTakedownEvent = modEventType === MOD_EVENTS.TAKEDOWN
const isAckEvent = modEventType === MOD_EVENTS.ACKNOWLEDGE
const shouldShowDurationInHoursField =
modEventType === MOD_EVENTS.TAKEDOWN || isMuteEvent || isMuteReporterEvent
isTakedownEvent || isMuteEvent || isMuteReporterEvent
const canManageChat = usePermission('canManageChat')

// navigate to next or prev report
Expand Down Expand Up @@ -258,6 +264,13 @@ function Form(
coreEvent.durationInHours = Number(formData.get('durationInHours'))
}

if (
(isTakedownEvent || isAckEvent) &&
formData.get('acknowledgeAccountSubjects')
) {
coreEvent.acknowledgeAccountSubjects = true
}

if (formData.get('comment')) {
coreEvent.comment = formData.get('comment')
}
Expand Down Expand Up @@ -562,16 +575,11 @@ function Form(
)}

{record?.blobs && (
<FormLabel
label="Blobs"
className={`mb-3 ${subjectStatus ? 'opacity-75' : ''}`}
>
<BlobList
blobs={record.blobs}
name="subjectBlobCids"
disabled={false}
/>
</FormLabel>
<BlobListFormField
blobs={record.blobs}
authorDid={record.repo.did}
className="mb-3"
/>
)}
{isSubjectDid && canManageChat && (
<div className="mb-3">
Expand All @@ -580,7 +588,7 @@ function Form(
)}
<div className={`mb-3`}>
<FormLabel label="Labels">
<LabelList className="-ml-1">
<LabelList className="-ml-1 flex-wrap">
{!currentLabels.length && <LabelListEmpty className="ml-1" />}
{allLabels.map((label) => {
return (
Expand All @@ -597,9 +605,9 @@ function Form(
{!!subjectStatus?.tags?.length && (
<div className={`mb-3`}>
<FormLabel label="Tags">
<LabelList className="-ml-1">
<LabelList className="-ml-1 flex-wrap">
{subjectStatus.tags.map((tag) => {
return <LabelChip key={tag}>{tag}</LabelChip>
return <SubjectTag key={tag} tag={tag} />
})}
</LabelList>
</FormLabel>
Expand All @@ -612,6 +620,11 @@ function Form(
<ModEventList subject={subject} />
) : (
<div className="px-1">
{profile && (
<div className="mb-2">
<HighProfileWarning profile={profile} />
</div>
)}
<div className="relative flex flex-row gap-1 items-center">
<ModEventSelectorButton
subjectStatus={subjectStatus}
Expand Down Expand Up @@ -649,12 +662,13 @@ function Form(
<LabelSelector
id="labels"
name="labels"
formId={FORM_ID}
form={FORM_ID}
defaultLabels={currentLabels.filter((label) => {
const isExternalLabel = allLabels.some((l) => {
return l.val === label && l.src !== config.did
// If there's a label where the source is the current labeler, it's editable
const isEditableLabel = allLabels.some((l) => {
return l.val === label && l.src === config.did
})
return !isSelfLabel(label) && !isExternalLabel
return !isSelfLabel(label) && isEditableLabel
})}
/>
</div>
Expand Down Expand Up @@ -724,6 +738,21 @@ function Form(
/>
)}

{(isTakedownEvent || isAckEvent) && isSubjectDid && (
<Checkbox
value="true"
id="acknowledgeAccountSubjects"
name="acknowledgeAccountSubjects"
className="mb-3 flex items-center leading-3"
label={
<span className="leading-4">
Acknowledge all open/escalated/appealed reports on
subjects created by this user
</span>
}
/>
)}

{submission.error && (
<div className="my-2">
<ActionError error={submission.error} />
Expand Down Expand Up @@ -803,22 +832,37 @@ function Form(
function useSubjectQuery(subject: string) {
const labelerAgent = useLabelerAgent()

const getProfile = async (actor: string) => {
try {
const { data: profile } = await labelerAgent.app.bsky.actor.getProfile({
actor,
})
return profile
} catch (e) {
return undefined
}
}

return useQuery({
// subject of the report
queryKey: ['modActionSubject', { subject }],
queryFn: async () => {
if (subject.startsWith('did:')) {
const { data: repo } =
await labelerAgent.api.tools.ozone.moderation.getRepo({
const [{ data: repo }, profile] = await Promise.all([
labelerAgent.tools.ozone.moderation.getRepo({
did: subject,
})
return { repo }
}),
getProfile(subject),
])
return { repo, profile }
} else if (subject.startsWith('at://')) {
const { data: record } =
await labelerAgent.api.tools.ozone.moderation.getRecord({
const [{ data: record }, profile] = await Promise.all([
labelerAgent.tools.ozone.moderation.getRecord({
uri: subject,
})
return { record }
}),
getProfile(new AtUri(subject).host),
])
return { record, profile }
} else {
return {}
}
Expand Down
17 changes: 17 additions & 0 deletions app/configure/page-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,21 @@ import { usePathname, useSearchParams, useRouter } from 'next/navigation'
import { useConfigurationContext } from '@/shell/ConfigurationContext'
import { WorkspacePanel } from '@/workspace/Panel'
import { useWorkspaceOpener } from '@/common/useWorkspaceOpener'
import { SetsConfig } from '@/config/Sets'
import { ProtectedTagsConfig } from '@/config/ProtectedTags'

enum Views {
Configure,
Members,
Sets,
ProtectedTags,
}

const TabKeys = {
configure: Views.Configure,
members: Views.Members,
sets: Views.Sets,
protectedTags: Views.ProtectedTags,
}

export default function ConfigurePageContent() {
Expand Down Expand Up @@ -63,6 +69,14 @@ export default function ConfigurePageContent() {
view: Views.Members,
label: 'Members',
},
{
view: Views.Sets,
label: 'Sets',
},
{
view: Views.ProtectedTags,
label: 'Protected Tags',
},
]

return (
Expand All @@ -75,6 +89,9 @@ export default function ConfigurePageContent() {
/>
{currentView === Views.Configure && <LabelerConfig />}
{currentView === Views.Members && <MemberConfig />}
{currentView === Views.Sets && <SetsConfig />}
{currentView === Views.Sets && <SetsConfig />}
{currentView === Views.ProtectedTags && <ProtectedTagsConfig />}

<ModActionPanelQuick
open={!!quickOpenParam}
Expand Down
Loading

0 comments on commit 602e706

Please sign in to comment.