Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Advanced tag filters #266

Merged
merged 11 commits into from
Jan 8, 2025
23 changes: 16 additions & 7 deletions app/actions/ModActionPanel/QuickAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
ChevronUpIcon,
} from '@heroicons/react/24/outline'
import { LabelSelector } from '@/common/labels/Selector'
import { pluralize, takesKeyboardEvt } from '@/lib/util'
import { takesKeyboardEvt } from '@/lib/util'
import { Loading } from '@/common/Loader'
import { ActionDurationSelector } from '@/reports/ModerationForm/ActionDurationSelector'
import { MOD_EVENTS } from '@/mod-event/constants'
Expand Down Expand Up @@ -200,6 +200,7 @@ function Form(
const shouldShowDurationInHoursField =
isTakedownEvent || isMuteEvent || isMuteReporterEvent
const canManageChat = usePermission('canManageChat')
const canTakedown = usePermission('canTakedown')

// navigate to next or prev report
const navigateQueue = (delta: 1 | -1) => {
Expand Down Expand Up @@ -491,7 +492,13 @@ function Form(
submitForm()
}
useKeyPressEvent('c', safeKeyHandler(onCancel))
useKeyPressEvent('s', safeKeyHandler(submitForm))
useKeyPressEvent(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to the PR. fixes #265

's',
safeKeyHandler((e) => {
e.stopImmediatePropagation()
submitForm()
}),
)
useKeyPressEvent('n', safeKeyHandler(submitAndGoNext))
useKeyPressEvent(
'a',
Expand All @@ -513,9 +520,11 @@ function Form(
)
useKeyPressEvent(
't',
safeKeyHandler(() => {
setModEventType(MOD_EVENTS.TAKEDOWN)
}),
canTakedown
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixes #244

? safeKeyHandler(() => {
setModEventType(MOD_EVENTS.TAKEDOWN)
})
: undefined,
)

return (
Expand Down Expand Up @@ -635,8 +644,8 @@ function Form(
{!!subjectStatus?.tags?.length && (
<div className={`mb-3`}>
<FormLabel label="Tags">
<LabelList className="-ml-1 flex-wrap">
{subjectStatus.tags.map((tag) => {
<LabelList className="-ml-1 flex-wrap gap-1">
{subjectStatus.tags.sort().map((tag) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes having the lang tags being placed in random places.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that .sort() will sort the input array in place. I don't know if that's fine or if a copy should be made before sorting ?

return <SubjectTag key={tag} tag={tag} />
})}
</LabelList>
Expand Down
38 changes: 2 additions & 36 deletions app/surprise-me/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const Timer = () => {
}, 1000)

return (
<div className="flex flex-row justify-center py-4">
<div className="flex flex-row justify-center py-4 dark:text-gray-200">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes #152

<p className="font-bold text-xl">{getDuration(seconds)}</p>
</div>
)
Expand All @@ -44,41 +44,7 @@ export default function SurpriseMePage() {
<>
{/* This is valid jsx but because of a known bug, typescript is confused */}
{/* @ts-ignore:next-line */}
<style global jsx>
{`
.game-block {
margin: 0;
padding: 0;
width: 1.5em;
height: 1.5em;
border: 1px solid #ddd;
}
.piece-i {
background-color: #ec858b;
}
.piece-j {
background-color: #f1b598;
}
.piece-l {
background-color: #f8efae;
}
.piece-o {
background-color: #b5a677;
}
.piece-s {
background-color: #816e56;
}
.piece-t {
background-color: #b77c72;
}
.piece-z {
background-color: #e3be58;
}
.piece-preview {
background-color: #eee;
}
`}
</style>

<Timer />
<ClientOnlyTetris />
</>
Expand Down
4 changes: 2 additions & 2 deletions components/common/SetupModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ export function SetupModal({
className="mx-auto h-20 w-auto"
title="Icon from Flaticon: https://www.flaticon.com/free-icons/lifeguard-tower"
src="/img/logo-colorful.png"
alt="Ozone - Bluesky Admin"
alt="Ozone - ATProto Moderation Service"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addresses #216

width={200}
height={200}
/>
<h2 className="mt-6 text-center text-3xl font-bold tracking-tight text-gray-900 dark:text-gray-200">
Bluesky Admin Tools
Ozone Moderation Service
</h2>
{title && (
<p className="mt-2 text-center text-sm text-gray-600 dark:text-gray-100">
Expand Down
2 changes: 1 addition & 1 deletion components/entertainment/tetris.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function TetrisGame () {
state,
controller,
}) => (
<div className="flex flex-row gap-x-4 items-start pt-4 mx-auto">
<div className="flex flex-row gap-x-4 items-start pt-4 mx-auto dark:text-gray-200">
<HeldPiece />
<div>
<p>Points: {points}</p>
Expand Down
103 changes: 0 additions & 103 deletions components/reports/QueueFilter/Language.tsx

This file was deleted.

11 changes: 6 additions & 5 deletions components/reports/QueueFilter/Panel.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Popover, Transition } from '@headlessui/react'
import { ChevronDownIcon } from '@heroicons/react/20/solid'
import { QueueFilterLanguage } from './Language'
import { QueueFilterSubjectType } from './SubjectType'
import { useSearchParams } from 'next/navigation'
import { useQueueFilterBuilder } from '../useQueueFilter'
import { ToolsOzoneModerationQueryStatuses } from '@atproto/api'
import { getLanguageFlag } from 'components/tags/SubjectTag'
import { getCollectionName } from '../helpers/subject'
import { classNames } from '@/lib/util'
import { QueueFilterTags } from './Tag'

// Takes all the queue filters manageable in the panel and displays a summary of selections made
const FilterSummary = ({
Expand All @@ -17,7 +17,7 @@ const FilterSummary = ({
}) => {
const { tags, excludeTags, collections, subjectType } = queueFilters
if (
!tags?.length &&
!tags?.filter(Boolean).length &&
!excludeTags?.length &&
!collections?.length &&
!subjectType
Expand Down Expand Up @@ -117,12 +117,13 @@ export const QueueFilterPanel = () => {
leaveFrom="transform scale-100 opacity-100"
leaveTo="transform scale-95 opacity-0"
>
<Popover.Panel className="absolute left-0 z-10 mt-1 flex w-screen max-w-max -translate-x-1/5 px-4">
<div className="w-fit-content flex-auto rounded bg-white dark:bg-slate-800 p-4 text-sm leading-6 shadow-lg dark:shadow-slate-900 ring-1 ring-gray-900/5">
<Popover.Panel className="absolute left-0 z-10 mt-1 flex max-w-max -translate-x-1/5 px-4">
<div className="flex-auto w-96 rounded bg-white dark:bg-slate-800 p-4 text-sm leading-6 shadow-lg dark:shadow-slate-900 ring-1 ring-gray-900/5">
<div className="flex flex-row px-2 gap-6">
<QueueFilterLanguage />
<QueueFilterSubjectType />
</div>

<QueueFilterTags />
</div>
</Popover.Panel>
</Transition>
Expand Down
91 changes: 39 additions & 52 deletions components/reports/QueueFilter/SubjectType.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,40 @@
import { XCircleIcon } from '@heroicons/react/24/solid'
import { ButtonGroup } from '@/common/buttons'
import {
CollectionId,
EmbedTypes,
getCollectionName,
getEmbedTypeName,
} from '../helpers/subject'
import { CollectionId, getCollectionName } from '../helpers/subject'
import { Checkbox } from '@/common/forms'
import { useQueueFilter } from '../useQueueFilter'

export const QueueFilterSubjectType = () => {
const { queueFilters, toggleCollection, toggleSubjectType, toggleEmbedType } =
useQueueFilter()
const allEmbedTypes = Object.values(EmbedTypes)
const {
queueFilters,
toggleCollection,
toggleSubjectType,
clearSubjectType,
} = useQueueFilter()

const selectedCollections = queueFilters.collections || []
const hasSubjectTypeFilter =
!!queueFilters.subjectType || !!selectedCollections.length
const selectedIncludeEmbedTypes: string[] =
queueFilters.tags?.filter((tag) => {
return tag.startsWith('embed:')
}) || []
const selectedExcludeEmbedTypes: string[] =
queueFilters.excludeTags?.filter((tag) => {
return tag.startsWith('embed:')
}) || []

return (
<div>
<h3 className="text-gray-900 dark:text-gray-200 mb-2">
Subject Type Filters
<button
type="button"
className="flex flex-row items-center"
onClick={() => {
if (hasSubjectTypeFilter) {
clearSubjectType()
}
}}
>
Subject Type Filters
{hasSubjectTypeFilter && <XCircleIcon className="h-4 w-4 ml-1" />}
</button>
</h3>

<ButtonGroup
Expand Down Expand Up @@ -63,44 +71,23 @@ export const QueueFilterSubjectType = () => {
Record Collection
</h3>

{Object.values(CollectionId).map((collectionId) => {
const isSelected = selectedCollections.includes(collectionId)
return (
<Checkbox
label={getCollectionName(collectionId)}
value={collectionId}
key={collectionId}
checked={isSelected}
onChange={() => {
toggleCollection(collectionId)
}}
/>
)
})}
</div>
<div>
<h3 className="text-gray-900 dark:text-gray-200 my-2 border-b border-gray-400 pb-1">
Record Embed
</h3>
{[...allEmbedTypes, 'noEmbed'].map((embedType) => {
const isNoEmbed = embedType === 'noEmbed'
const isSelected = isNoEmbed
? allEmbedTypes.every((et) =>
selectedExcludeEmbedTypes.includes(et),
)
: selectedIncludeEmbedTypes.includes(embedType)
return (
<Checkbox
label={getEmbedTypeName(embedType)}
value={embedType}
key={embedType}
checked={isSelected}
onChange={() => {
toggleEmbedType(embedType)
}}
/>
)
})}
<div className="flex flex-row gap-x-3 gap-y-1 flex-wrap">
{Object.values(CollectionId).map((collectionId) => {
const isSelected = selectedCollections.includes(collectionId)
return (
<Checkbox
className="flex items-center"
label={getCollectionName(collectionId)}
value={collectionId}
key={collectionId}
checked={isSelected}
onChange={() => {
toggleCollection(collectionId)
}}
/>
)
})}
</div>
</div>
</div>
)}
Expand Down
Loading
Loading