149 lines
4.7 KiB
JavaScript
149 lines
4.7 KiB
JavaScript
function eventIdSet(chapter) {
|
|
return new Set(
|
|
Array.isArray(chapter && chapter.events)
|
|
? chapter.events.map((event) => event.hotspotId)
|
|
: [],
|
|
)
|
|
}
|
|
|
|
function normalizeCompletedIds(chapter, completedIds) {
|
|
const knownIds = eventIdSet(chapter)
|
|
const seen = new Set()
|
|
return (Array.isArray(completedIds) ? completedIds : []).filter((id) => {
|
|
if (!knownIds.has(id) || seen.has(id)) return false
|
|
seen.add(id)
|
|
return true
|
|
})
|
|
}
|
|
|
|
function getPeopleProgress(chapter, completedIds) {
|
|
const knownIds = eventIdSet(chapter)
|
|
const completed = new Set(normalizeCompletedIds(chapter, completedIds))
|
|
const people = Array.isArray(chapter && chapter.people) ? chapter.people : []
|
|
|
|
return people
|
|
.map((person) => {
|
|
const personEventIds = (Array.isArray(person.eventIds)
|
|
? person.eventIds
|
|
: []
|
|
).filter((id) => knownIds.has(id))
|
|
const completedForPerson = personEventIds.filter((id) => completed.has(id))
|
|
const remaining = personEventIds.length - completedForPerson.length
|
|
if (!personEventIds.length) return null
|
|
|
|
let markerStatus = '看看'
|
|
let statusAria = `${person.name}有1处故事细节,可以看看发生了什么`
|
|
if (remaining === 0) {
|
|
markerStatus = '看过'
|
|
statusAria = `${person.name}这一处已经看过`
|
|
} else if (completedForPerson.length > 0) {
|
|
markerStatus = '再看看'
|
|
statusAria = `${person.name}还有${remaining}处细节,可以再看看`
|
|
} else if (remaining > 1) {
|
|
markerStatus = `${remaining}处`
|
|
statusAria = `${person.name}有${remaining}处故事细节`
|
|
}
|
|
|
|
return {
|
|
...person,
|
|
eventIds: personEventIds,
|
|
completed: remaining === 0,
|
|
completedEvents: completedForPerson.length,
|
|
remaining,
|
|
markerStatus,
|
|
statusAria,
|
|
}
|
|
})
|
|
.filter(Boolean)
|
|
}
|
|
|
|
function selectNextPerson(people, activeInstanceId) {
|
|
const active = people.find(
|
|
(person) => person.instanceId === activeInstanceId && person.remaining > 0,
|
|
)
|
|
if (active) return active
|
|
|
|
const partiallyCompleted = people.find(
|
|
(person) => person.completedEvents > 0 && person.remaining > 0,
|
|
)
|
|
return partiallyCompleted || people.find((person) => person.remaining > 0) || null
|
|
}
|
|
|
|
function getChapterProgress(
|
|
chapter,
|
|
completedIds,
|
|
activeInstanceId = '',
|
|
chapterFinished = false,
|
|
) {
|
|
const normalizedIds = normalizeCompletedIds(chapter, completedIds)
|
|
const totalEvents = Array.isArray(chapter && chapter.events)
|
|
? chapter.events.length
|
|
: 0
|
|
const completedCount = normalizedIds.length
|
|
const remainingCount = Math.max(0, totalEvents - completedCount)
|
|
const complete = totalEvents > 0 && remainingCount === 0
|
|
const people = getPeopleProgress(chapter, normalizedIds)
|
|
const nextPerson = complete
|
|
? null
|
|
: selectNextPerson(people, activeInstanceId)
|
|
const repeatPerson = Boolean(
|
|
nextPerson
|
|
&& (
|
|
nextPerson.completedEvents > 0
|
|
|| (
|
|
activeInstanceId
|
|
&& nextPerson.instanceId === activeInstanceId
|
|
)
|
|
),
|
|
)
|
|
|
|
let nextStepLabel = '下一步'
|
|
let nextStepText = '看看画中的人物和手边物件,跟着这一回往下走。'
|
|
let continueLabel = '完成后继续'
|
|
if (complete) {
|
|
nextStepLabel = chapterFinished ? '本回已收好' : '4处线索已经看过'
|
|
nextStepText = chapterFinished
|
|
? '这一回已经收进画册,也可以再次打开情感互动。'
|
|
: '情感互动已经开启,点右侧按钮打开这一页。'
|
|
continueLabel = '4处线索看完,打开情感互动'
|
|
} else if (nextPerson && repeatPerson) {
|
|
nextStepText = `还差${remainingCount}处。再看看${nextPerson.name}的手边。`
|
|
continueLabel = `下一步:再看看${nextPerson.name}`
|
|
} else if (nextPerson) {
|
|
const multiEventNote = nextPerson.remaining > 1
|
|
? ` ${nextPerson.name}身边还有${nextPerson.remaining}处细节。`
|
|
: ''
|
|
nextStepText = `还差${remainingCount}处。接着看看${nextPerson.name}。${multiEventNote}`
|
|
continueLabel = `下一步:看看${nextPerson.name}`
|
|
}
|
|
|
|
const emotionStatusText = complete
|
|
? (
|
|
chapterFinished
|
|
? '本回已收进画册,可再次打开'
|
|
: `${totalEvents}处线索已经看过,可以打开`
|
|
)
|
|
: `还差${remainingCount}处线索,看完后开启`
|
|
|
|
return {
|
|
completedIds: normalizedIds,
|
|
completedCount,
|
|
totalEvents,
|
|
remainingCount,
|
|
complete,
|
|
people,
|
|
nextPerson,
|
|
nextAction: complete ? 'complete' : (repeatPerson ? 'repeat' : 'next'),
|
|
nextStepLabel,
|
|
nextStepText,
|
|
continueLabel,
|
|
emotionStatusText,
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
normalizeCompletedIds,
|
|
getPeopleProgress,
|
|
getChapterProgress,
|
|
}
|