mirror of
https://github.com/modrinth/code.git
synced 2026-08-27 10:04:52 +00:00
Moderation Changes Phase 2.-1 (#6833)
* better default state handling
* make next stage button work for going to next project
* fix skill issue
* actually fix initial values this time,
make single line inputs with varying lengths (text input and dropdown) use their widest possible length instead of whatever the hell they used to be
* loaders in progress
* loaders and versions test (probably dont use them as the messages suck and idrk what they should do quick fix/message wise)
* WIP the wip
* good enough for now slug taken improvements
* trim all those extra newlines
* viewedness
* batch prefetch queue + technically slightly faster checklist init
* show all valid alternative project types regardless of current project type
* Hide moderation permissions stage when it should be, and I'm sure this won't cause any issues
* Hide moderation permissions stage when it should be, and I'm sure this won't cause any issues
* gimme them versions
* better moderation permission stage shown check?
* betterer moderation permission stage shown check?
* bettererer moderation permission stage shown check? + also began deleting legacy checklist types
* fix certain stages being able to be considered viewed before being viewed
* more removals + i forgot to remove an import last commit
* changed nothing™️
* remove severities + bandaid post-approval message priorities + dependencies
* fix message preview tooltips
* next stage = next project when done
* insufficient description custom fix
* fix that thing coolbot told me was broken I forgot what it was oops
* oh there was a second bug there
* make alternate versions and incorrect project type required cuz they are
* re-navigate button also damn that's a lot of other stuff that pnpm fix... fixed?
* you cant just quick fix a slug into a taken one
* maybe lets not just try and set a slug to something entirely invalid?
* what if we just didn't drop ur queue :smart:
* more queue upgrades
* tweaks
* I love unbreaking things
* un-nuked renavigate button
* prepr
* prepr worked this time i think
* undo more mistakes
* i love intellij refactoring
* ok i think we're good
This commit is contained in:
@@ -573,8 +573,8 @@ import { versionQueryOptions } from '~/composables/queries/version'
|
||||
import { useServerInstallContent } from '~/composables/use-server-install-content'
|
||||
import { userCollectProject, userFollowProject } from '~/composables/user.js'
|
||||
import { injectCurrentProjectId } from '~/providers/current-project.ts'
|
||||
import { loadChecklistState } from '~/services/moderation-checklist-storage.ts'
|
||||
import { useModerationQueue } from '~/services/moderation-queue.ts'
|
||||
import { loadChecklistState } from '~/services/moderation/checklist-storage.ts'
|
||||
import { useModerationQueue } from '~/services/moderation/queue.ts'
|
||||
import { getReportPath, reportProject } from '~/utils/report-helpers.ts'
|
||||
|
||||
definePageMeta({
|
||||
@@ -1106,7 +1106,7 @@ const { data: thread } = useQuery({
|
||||
|
||||
const isSettings = computed(() => route.name.startsWith('type-project-settings'))
|
||||
|
||||
// Transform versionsV3 to be same shape as versionsV2 for compatibility in project pages
|
||||
// Jank modpack loaders fix
|
||||
const versionsRaw = computed(() => {
|
||||
return (versionsV3.value ?? []).map((version) => {
|
||||
const files = Array.isArray(version.files) ? version.files : []
|
||||
@@ -1893,23 +1893,11 @@ function setModerationChecklistOpen(open) {
|
||||
showModerationChecklist.value = open
|
||||
}
|
||||
|
||||
function isProjectInActiveModerationQueue(projectId = project.value?.id) {
|
||||
return (
|
||||
!!projectId &&
|
||||
moderationQueue.isQueueMode &&
|
||||
moderationQueue.currentQueue.items.includes(projectId)
|
||||
)
|
||||
}
|
||||
|
||||
async function openModerationChecklistFromMenu() {
|
||||
const projectId = project.value?.id
|
||||
if (!projectId) return
|
||||
|
||||
await moderationQueue.ready
|
||||
if (!isProjectInActiveModerationQueue(projectId)) {
|
||||
await moderationQueue.setSingleProject(projectId)
|
||||
}
|
||||
|
||||
setModerationChecklistOpen(true)
|
||||
}
|
||||
|
||||
|
||||
@@ -108,6 +108,12 @@
|
||||
@switch-page="goToPage"
|
||||
/>
|
||||
<ConfettiExplosion v-if="visible" />
|
||||
<QueueSummaryModal
|
||||
ref="queueSummaryModal"
|
||||
:completed-ids="moderationQueue.currentQueue.completed"
|
||||
:skipped-ids="moderationQueue.currentQueue.skipped"
|
||||
@review-skipped="reviewSkippedQueue"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-3">
|
||||
@@ -160,8 +166,11 @@ import { useQuery } from '@tanstack/vue-query'
|
||||
import ConfettiExplosion from 'vue-confetti-explosion'
|
||||
|
||||
import ModerationQueueCard from '~/components/ui/moderation/ModerationQueueCard.vue'
|
||||
import QueueSummaryModal from '~/components/ui/moderation/QueueSummaryModal.vue'
|
||||
import { type ModerationProject, toModerationProjects } from '~/helpers/moderation.ts'
|
||||
import { useModerationQueue } from '~/services/moderation-queue.ts'
|
||||
import { getProjectTypeForUrlShorthand } from '~/helpers/projects.js'
|
||||
import { useModerationQueue } from '~/services/moderation/queue.ts'
|
||||
import { findNextEligibleQueueProject } from '~/services/moderation/queue-eligibility.ts'
|
||||
|
||||
useHead({ title: 'Projects queue - Modrinth' })
|
||||
|
||||
@@ -172,6 +181,8 @@ const route = useRoute()
|
||||
const router = useRouter()
|
||||
const client = injectModrinthClient()
|
||||
|
||||
const queueSummaryModal = ref()
|
||||
|
||||
const visible = ref(false)
|
||||
if (import.meta.client && history && history.state && history.state.confetti) {
|
||||
setTimeout(async () => {
|
||||
@@ -184,6 +195,14 @@ if (import.meta.client && history && history.state && history.state.confetti) {
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
if (import.meta.client && history && history.state && history.state.queueSummary) {
|
||||
setTimeout(async () => {
|
||||
history.state.queueSummary = false
|
||||
await nextTick()
|
||||
queueSummaryModal.value?.show()
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
moderate: {
|
||||
id: 'moderation.moderate',
|
||||
@@ -498,60 +517,36 @@ function goToPage(page: number) {
|
||||
currentPage.value = page
|
||||
}
|
||||
|
||||
function notifySkippedProjects(skippedCount: number) {
|
||||
if (skippedCount <= 0) return
|
||||
addNotification({
|
||||
title: 'Skipped projects',
|
||||
text: `Skipped ${skippedCount} project(s) already moderated or locked by others.`,
|
||||
type: 'info',
|
||||
autoCloseMs: 2000,
|
||||
})
|
||||
}
|
||||
|
||||
async function findFirstEligibleProject(): Promise<string | null> {
|
||||
let skippedCount = 0
|
||||
const candidateIds = [...moderationQueue.currentQueue.items]
|
||||
if (candidateIds.length === 0) return null
|
||||
|
||||
while (moderationQueue.hasItems) {
|
||||
const currentId = moderationQueue.getCurrentProjectId()
|
||||
if (!currentId) return null
|
||||
const next = await findNextEligibleQueueProject(client, moderationQueue, candidateIds)
|
||||
|
||||
const project = projectsById.value.get(currentId)
|
||||
|
||||
if (project && project.project.status !== 'processing') {
|
||||
await moderationQueue.completeCurrentProject(currentId, 'skipped')
|
||||
skippedCount++
|
||||
continue
|
||||
}
|
||||
|
||||
try {
|
||||
const lockStatus = await moderationQueue.checkLock(currentId)
|
||||
|
||||
if (!lockStatus.locked || lockStatus.expired || lockStatus.is_own_lock) {
|
||||
notifySkippedProjects(skippedCount)
|
||||
return currentId
|
||||
}
|
||||
|
||||
await moderationQueue.completeCurrentProject(currentId, 'skipped')
|
||||
skippedCount++
|
||||
} catch {
|
||||
return currentId
|
||||
}
|
||||
if (!next) {
|
||||
await Promise.all(candidateIds.map((id) => moderationQueue.excludeProject(id)))
|
||||
return null
|
||||
}
|
||||
|
||||
notifySkippedProjects(skippedCount)
|
||||
|
||||
return null
|
||||
await Promise.all(next.excluded.map((id) => moderationQueue.excludeProject(id)))
|
||||
return next.project
|
||||
}
|
||||
|
||||
function getProjectRouteParam(projectId: string): string {
|
||||
return projectsById.value.get(projectId)?.project.slug || projectId
|
||||
}
|
||||
|
||||
function getProjectRouteType(projectId: string): string {
|
||||
const projectType = projectsById.value.get(projectId)?.project.project_types[0]
|
||||
if (!projectType) return 'project'
|
||||
return getProjectTypeForUrlShorthand(projectType, [])
|
||||
}
|
||||
|
||||
async function navigateToModerationProject(projectId: string) {
|
||||
await navigateTo({
|
||||
name: 'type-project',
|
||||
params: {
|
||||
type: 'project',
|
||||
type: getProjectRouteType(projectId),
|
||||
project: getProjectRouteParam(projectId),
|
||||
},
|
||||
state: {
|
||||
@@ -593,12 +588,8 @@ async function moderateAllInFilter() {
|
||||
async function startFromProject(projectId: string) {
|
||||
const allFilteredProjectIds = await getFilteredProjectIds()
|
||||
const projectIndex = allFilteredProjectIds.indexOf(projectId)
|
||||
if (projectIndex === -1) {
|
||||
await moderationQueue.setSingleProject(projectId)
|
||||
} else {
|
||||
const projectIds = allFilteredProjectIds.slice(projectIndex)
|
||||
await moderationQueue.setQueue(projectIds)
|
||||
}
|
||||
const projectIds = projectIndex === -1 ? [projectId] : allFilteredProjectIds.slice(projectIndex)
|
||||
await moderationQueue.setQueue(projectIds)
|
||||
|
||||
const targetProjectId = await findFirstEligibleProject()
|
||||
|
||||
@@ -613,4 +604,21 @@ async function startFromProject(projectId: string) {
|
||||
|
||||
await navigateToModerationProject(targetProjectId)
|
||||
}
|
||||
|
||||
async function reviewSkippedQueue() {
|
||||
await moderationQueue.startSkippedReview()
|
||||
|
||||
const targetProjectId = await findFirstEligibleProject()
|
||||
|
||||
if (!targetProjectId) {
|
||||
addNotification({
|
||||
title: 'No projects available',
|
||||
text: 'All previously skipped projects are already moderated or locked by others.',
|
||||
type: 'warning',
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
await navigateToModerationProject(targetProjectId)
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user