Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -692,17 +692,23 @@ const emit = defineEmits<{

async function handleExit() {
// Release if we own the lock, or if there was an error checking (we might still own it)
if (lockStatus.value?.isOwnLock || lockError.value) {
const released = await moderationStore.releaseLock(projectV2.value.id)
const projectId = projectV2.value?.id
if (projectId && (lockStatus.value?.isOwnLock || lockError.value)) {
const released = await moderationStore.releaseLock(projectId)
if (!released && lockStatus.value?.isOwnLock) {
console.warn('Failed to release moderation lock for project:', projectV2.value.id)
console.warn('Failed to release moderation lock for project:', projectId)
}
}
emit('exit')
}

async function retryAcquireLock() {
const result = await moderationStore.acquireLock(projectV2.value.id)
const projectId = projectV2.value?.id
if (!projectId) {
console.warn('[retryAcquireLock] No project ID available')
return
}
const result = await moderationStore.acquireLock(projectId)

if (result.success) {
handleLockAcquired()
Expand Down Expand Up @@ -790,6 +796,8 @@ async function maintainPrefetchQueue() {
if (isPrefetching.value) return
if (!moderationStore.isQueueMode) return

const currentProjectId = projectV2.value?.id

isPrefetching.value = true

try {
Expand All @@ -798,7 +806,9 @@ async function maintainPrefetchQueue() {
prefetchQueue.value = prefetchQueue.value.filter((p) => now - p.validatedAt < PREFETCH_STALE_MS)

// 2. Remove entries for current project
prefetchQueue.value = prefetchQueue.value.filter((p) => p.projectId !== projectV2.value.id)
if (currentProjectId) {
prefetchQueue.value = prefetchQueue.value.filter((p) => p.projectId !== currentProjectId)
}

// 3. If queue is full enough, exit early
if (prefetchQueue.value.length >= PREFETCH_TARGET_COUNT) {
Expand All @@ -808,7 +818,7 @@ async function maintainPrefetchQueue() {
// 4. Get remaining queue items (excluding current and already prefetched)
const prefetchedIds = new Set(prefetchQueue.value.map((p) => p.projectId))
const queueItems = [...moderationStore.currentQueue.items]
const currentIndex = queueItems.indexOf(projectV2.value.id)
const currentIndex = currentProjectId ? queueItems.indexOf(currentProjectId) : -1
const remainingItems =
currentIndex >= 0 ? queueItems.slice(currentIndex + 1) : queueItems.slice(1)

Expand Down Expand Up @@ -873,7 +883,11 @@ const MAX_SKIP_ATTEMPTS = 10

async function skipToNextProject() {
// Skip the current project
const currentProjectId = projectV2.value.id
const currentProjectId = projectV2.value?.id
if (!currentProjectId) {
console.warn('[skipToNextProject] No current project ID, aborting')
return
}
debug('[skipToNextProject] Starting. Current project:', currentProjectId)
debug('[skipToNextProject] Queue before complete:', [...moderationStore.currentQueue.items])

Expand Down Expand Up @@ -1822,16 +1836,30 @@ function generateModpackMessage(allFiles: {

const hasNextProject = ref(false)
async function sendMessage(status: ProjectStatus) {
// Capture project data upfront to avoid null issues during async operations
const projectId = projectV2.value?.id
const threadId = projectV2.value?.thread_id
const projectType = projectV2.value?.project_type

if (!projectId) {
addNotification({
title: 'Error submitting moderation',
text: 'Project data unavailable. Please try again.',
type: 'error',
})
return
}

try {
await useBaseFetch(`project/${projectV2.value.id}`, {
await useBaseFetch(`project/${projectId}`, {
method: 'PATCH',
body: {
status,
},
})

if (message.value) {
await useBaseFetch(`thread/${projectV2.value.thread_id}`, {
if (message.value && threadId) {
await useBaseFetch(`thread/${threadId}`, {
method: 'POST',
body: {
body: {
Expand All @@ -1842,23 +1870,24 @@ async function sendMessage(status: ProjectStatus) {
})
}

if (
projectV2.value.project_type === 'modpack' &&
Object.keys(modpackJudgements.value).length > 0
) {
if (projectType === 'modpack' && Object.keys(modpackJudgements.value).length > 0) {
await useBaseFetch(`moderation/project`, {
internal: true,
method: 'POST',
body: modpackJudgements.value,
})
}

done.value = true
const willHaveNext = moderationStore.completeCurrentProject(projectId, 'completed')

// Release the lock after successful submission
await moderationStore.releaseLock(projectV2.value.id)
moderationStore.releaseLock(projectId).catch((err) => {
console.warn('Failed to release lock:', err)
})

hasNextProject.value = moderationStore.completeCurrentProject(projectV2.value.id, 'completed')
// Set both states together - hasNextProject MUST be set before done
// to avoid the race condition where done=true renders with hasNextProject=false
hasNextProject.value = willHaveNext
done.value = true
Copy link
Contributor

Choose a reason for hiding this comment

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

potentially a loading state for the awaits could mitigate this as well

} catch (error) {
console.error('Error submitting moderation:', error)
addNotification({
Expand Down Expand Up @@ -1900,7 +1929,7 @@ async function endChecklist(status?: string) {
if (!(await navigateToNextUnlockedProject())) {
// Fallback: batch check remaining projects with metadata
const remainingIds: string[] = []
const currentProjectId = projectV2.value.id
const currentProjectId = projectV2.value?.id
const queueItems = moderationStore.currentQueue.items

// Build list of remaining projects, excluding current
Expand Down Expand Up @@ -1971,10 +2000,21 @@ async function endChecklist(status?: string) {
}

async function skipCurrentProject() {
// Release the lock before skipping
await moderationStore.releaseLock(projectV2.value.id)
const projectId = projectV2.value?.id
if (!projectId) {
addNotification({
title: 'Error skipping project',
text: 'Project data unavailable. Please try again.',
type: 'error',
})
return
}

moderationStore.releaseLock(projectId).catch((err) => {
console.warn('Failed to release lock:', err)
})

hasNextProject.value = moderationStore.completeCurrentProject(projectV2.value.id, 'skipped')
hasNextProject.value = moderationStore.completeCurrentProject(projectId, 'skipped')

await endChecklist('skipped')
}
Expand Down