waha-shared 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.DS_Store +0 -0
- package/README.md +10 -0
- package/__init__.py +0 -0
- package/copy.ts +37 -0
- package/data/README.md +45 -0
- package/data/__init__.py +0 -0
- package/data/aslTimestamps.json +192788 -0
- package/data/bibleAudios.json +394 -0
- package/data/bibleAudios.ts +4 -0
- package/data/bibleResources/audioBibleLicenses.json +6235 -0
- package/data/bibleResources/bibleBooks.json +6071 -0
- package/data/bibleResources/bibleBooks.ts +4 -0
- package/data/bibleResources/bibleChaptersList.json +1191 -0
- package/data/bibleResources/bibleChaptersList.ts +4 -0
- package/data/bibleResources/textBibleLicenses.json +14603 -0
- package/data/bibleStatuses.json +9196 -0
- package/data/bibleStatuses.ts +4 -0
- package/data/bibleTexts.json +527 -0
- package/data/bibleTexts.ts +4 -0
- package/data/clones.json +13 -0
- package/data/countryResources/areas.json +74 -0
- package/data/countryResources/areas.ts +4 -0
- package/data/countryResources/countries.json +3362 -0
- package/data/countryResources/countries.ts +4 -0
- package/data/foundationsCurriculums.json +130 -0
- package/data/foundationsCurriculums.ts +4 -0
- package/data/languageResources/countriesAndLanguages.json +11718 -0
- package/data/languageResources/countriesAndLanguages.ts +16 -0
- package/data/languageResources/crowdinLanguages.json +2172 -0
- package/data/languageResources/iosVoiceOverLanguages.json +64 -0
- package/data/languageResources/iso6933LanguageCodes.json +7927 -0
- package/data/languageResources/mmsLanguages.json +28164 -0
- package/data/languageResources/phoneLanguages.json +1532 -0
- package/data/languageResources/phoneLanguages.ts +14 -0
- package/data/languages.json +7045 -0
- package/data/languages.ts +4 -0
- package/data/mediaDurations.json +32364 -0
- package/data/mediaDurations.ts +4 -0
- package/data/notification.json +69 -0
- package/data/notification.ts +4 -0
- package/data/numeralMaps.json +26 -0
- package/data/numeralMaps.ts +4 -0
- package/data/orphanedBibleTexts.json +2747 -0
- package/data/questions.json +317 -0
- package/data/questions.ts +4 -0
- package/data/questionsCurriculums.json +753 -0
- package/data/questionsCurriculums.ts +4 -0
- package/data/releaseNotes.json +2381 -0
- package/data/releaseNotes.ts +4 -0
- package/data/schemas/appTranslations.schema.json +802 -0
- package/data/schemas/areas.schema.json +76 -0
- package/data/schemas/aslTimestamps.schema.json +59 -0
- package/data/schemas/bibleAudios.schema.json +37 -0
- package/data/schemas/bibleBooks.schema.json +112 -0
- package/data/schemas/bibleChapters.schema.json +61 -0
- package/data/schemas/bibleStatuses.schema.json +41 -0
- package/data/schemas/bibleTexts.schema.json +60 -0
- package/data/schemas/clones.schema.json +63 -0
- package/data/schemas/countries.schema.json +84 -0
- package/data/schemas/foundationsCurriculums.schema.json +20 -0
- package/data/schemas/introductionTranslations.schema.json +101 -0
- package/data/schemas/languages.schema.json +365 -0
- package/data/schemas/mediaDurations.schema.json +41 -0
- package/data/schemas/notification.schema.json +111 -0
- package/data/schemas/numeralMaps.schema.json +57 -0
- package/data/schemas/questionTranslations.schema.json +20 -0
- package/data/schemas/questions.schema.json +29 -0
- package/data/schemas/questionsCurriculums.schema.json +34 -0
- package/data/schemas/releaseNotes.schema.json +21 -0
- package/data/schemas/screenshots.schema.json +23 -0
- package/data/schemas/setTranslations.schema.json +70 -0
- package/data/schemas/sets.schema.json +109 -0
- package/data/schemas/topicsCurriculums.schema.json +20 -0
- package/data/screenshots.json +17 -0
- package/data/screenshots.ts +4 -0
- package/data/sets.json +12258 -0
- package/data/sets.ts +4 -0
- package/data/specialIds.json +72 -0
- package/data/specialIds.ts +19 -0
- package/data/timings/som.json +9150 -0
- package/data/topicsCurriculums.json +131 -0
- package/data/topicsCurriculums.ts +4 -0
- package/data/typescript/appTranslations.ts +322 -0
- package/data/typescript/areas.ts +45 -0
- package/data/typescript/aslTimestamps.ts +36 -0
- package/data/typescript/bibleAudioAvailableChapters.ts +35 -0
- package/data/typescript/bibleAudios.ts +32 -0
- package/data/typescript/bibleBookNames.ts +97 -0
- package/data/typescript/bibleBooks.ts +63 -0
- package/data/typescript/bibleChapters.ts +40 -0
- package/data/typescript/bibleStatuses.ts +54 -0
- package/data/typescript/bibleTextAvailableChapters.ts +35 -0
- package/data/typescript/bibleTexts.ts +63 -0
- package/data/typescript/clones.ts +35 -0
- package/data/typescript/countries.ts +152 -0
- package/data/typescript/foundationsCurriculums.ts +15 -0
- package/data/typescript/introductionTranslations.ts +60 -0
- package/data/typescript/languages.ts +369 -0
- package/data/typescript/mediaDurations.ts +89 -0
- package/data/typescript/notification.ts +189 -0
- package/data/typescript/numeralMaps.ts +74 -0
- package/data/typescript/questionTranslations.ts +6 -0
- package/data/typescript/questions.ts +25 -0
- package/data/typescript/questionsCurriculums.ts +26 -0
- package/data/typescript/releaseNotes.ts +10 -0
- package/data/typescript/screenshots.ts +52 -0
- package/data/typescript/setTranslations.ts +39 -0
- package/data/typescript/sets.ts +105 -0
- package/data/typescript/topicsCurriculums.ts +15 -0
- package/data/youtube/playlists.json +28 -0
- package/data/youtube/videos.json +262 -0
- package/data/youtube/videos.ts +2 -0
- package/functions/activeCampaign.ts +127 -0
- package/functions/bibleChapterUtils.ts +241 -0
- package/functions/crowdin.ts +51 -0
- package/functions/languages.ts +284 -0
- package/functions/scripturePassages.ts +368 -0
- package/functions/sets.ts +495 -0
- package/package.json +10 -0
- package/translations/appTranslations.json +10239 -0
- package/translations/appTranslations.ts +4 -0
- package/translations/introductionTranslations.json +422 -0
- package/translations/introductionTranslations.ts +4 -0
- package/translations/questionTranslations.json +1472 -0
- package/translations/questionTranslations.ts +4 -0
- package/translations/setTranslations.json +30257 -0
- package/translations/setTranslations.ts +4 -0
- package/translations/spokenQuestionTranslations.json +1472 -0
- package/types/analytics.ts +147 -0
- package/types/completions.ts +9 -0
- package/types/feedback.ts +27 -0
- package/types/languages.ts +37 -0
- package/types/notifications.ts +37 -0
- package/types/sets.ts +84 -0
- package/types/users.ts +162 -0
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
import mediaDurations from 'shared/data/mediaDurations'
|
|
2
|
+
import type { AppTranslations } from 'shared/data/typescript/appTranslations'
|
|
3
|
+
import { getPassagesString } from 'shared/functions/scripturePassages'
|
|
4
|
+
import questions from '../data/questions'
|
|
5
|
+
import allSets from '../data/sets'
|
|
6
|
+
import specialIds from '../data/specialIds'
|
|
7
|
+
import courseYoutubeVideos from '../data/youtube/videos'
|
|
8
|
+
import type { LanguageInfo, MeetTranslations } from '../types/languages'
|
|
9
|
+
import {
|
|
10
|
+
Chapter,
|
|
11
|
+
Content,
|
|
12
|
+
Lesson,
|
|
13
|
+
LessonInfo,
|
|
14
|
+
Set,
|
|
15
|
+
SetCategory,
|
|
16
|
+
SetInfo,
|
|
17
|
+
type Section,
|
|
18
|
+
} from '../types/sets'
|
|
19
|
+
|
|
20
|
+
export const firebaseUrl =
|
|
21
|
+
'https://firebasestorage.googleapis.com/v0/b/waha-app-db.appspot.com/o/'
|
|
22
|
+
|
|
23
|
+
export function getSetInfo({
|
|
24
|
+
setId,
|
|
25
|
+
meetLanguageId,
|
|
26
|
+
sets,
|
|
27
|
+
t,
|
|
28
|
+
}: {
|
|
29
|
+
setId: string
|
|
30
|
+
meetLanguageId: string
|
|
31
|
+
t: MeetTranslations & AppTranslations[string]
|
|
32
|
+
sets: string[]
|
|
33
|
+
}): SetInfo | undefined {
|
|
34
|
+
const idComponents = setId.split('.')
|
|
35
|
+
const category: SetCategory =
|
|
36
|
+
idComponents[0] === '01'
|
|
37
|
+
? 'Foundations'
|
|
38
|
+
: idComponents[0] === '02'
|
|
39
|
+
? 'Topics'
|
|
40
|
+
: 'WahaTraining'
|
|
41
|
+
|
|
42
|
+
const setNumber = (
|
|
43
|
+
sets
|
|
44
|
+
.filter((set) => set.split('.')[0] === idComponents[0])
|
|
45
|
+
.findIndex((set) => set === setId) + 1
|
|
46
|
+
).toString()
|
|
47
|
+
|
|
48
|
+
const thisSetTranslations = t.sets.find((set) => set.setId === setId)
|
|
49
|
+
const categoryName =
|
|
50
|
+
idComponents[0] === '01'
|
|
51
|
+
? t.foundations
|
|
52
|
+
: idComponents[0] === '02'
|
|
53
|
+
? t.topics
|
|
54
|
+
: t.training
|
|
55
|
+
const set = allSets.find((set) => set.setId === setId) as Set | undefined
|
|
56
|
+
|
|
57
|
+
if (!set) return
|
|
58
|
+
|
|
59
|
+
const toReturn = {
|
|
60
|
+
...set,
|
|
61
|
+
...thisSetTranslations,
|
|
62
|
+
setSubtitle:
|
|
63
|
+
category === 'Topics'
|
|
64
|
+
? (thisSetTranslations?.setTag ?? '')
|
|
65
|
+
: `${categoryName} ${parseInt(setNumber)}`,
|
|
66
|
+
setLink: `https://web.waha.app/set?set-id=${setId}&meet-language=${meetLanguageId}`,
|
|
67
|
+
meetLanguageId,
|
|
68
|
+
setNumber,
|
|
69
|
+
category,
|
|
70
|
+
}
|
|
71
|
+
return toReturn
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function getLessonInfo({
|
|
75
|
+
lessonId,
|
|
76
|
+
meetLanguageInfo,
|
|
77
|
+
setInfo,
|
|
78
|
+
t,
|
|
79
|
+
}: {
|
|
80
|
+
lessonId: Lesson['lessonId'] | undefined
|
|
81
|
+
meetLanguageInfo: LanguageInfo
|
|
82
|
+
setInfo?: SetInfo
|
|
83
|
+
t: MeetTranslations & AppTranslations[string]
|
|
84
|
+
}): LessonInfo | undefined {
|
|
85
|
+
if (!lessonId) return
|
|
86
|
+
else if (lessonId.split('.').length !== 3) return
|
|
87
|
+
|
|
88
|
+
const [category, setNumber, lessonNumber] = lessonId.split('.')
|
|
89
|
+
|
|
90
|
+
const meetLanguageId = meetLanguageInfo.languageId
|
|
91
|
+
|
|
92
|
+
setInfo =
|
|
93
|
+
setInfo ??
|
|
94
|
+
getSetInfo({
|
|
95
|
+
setId: [category, setNumber].join('.'),
|
|
96
|
+
meetLanguageId,
|
|
97
|
+
sets: meetLanguageInfo.sets,
|
|
98
|
+
t,
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
if (!setInfo) {
|
|
102
|
+
console.log('Missing set info for lesson:', lessonId)
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const lesson = setInfo.lessons.find((lesson) => lesson.lessonId === lessonId)
|
|
107
|
+
|
|
108
|
+
if (!lesson) return
|
|
109
|
+
|
|
110
|
+
const thisSetTranslations = t.sets.find((set) => set.setId === setInfo?.setId)
|
|
111
|
+
const lessonTitle = thisSetTranslations?.lessonTitles?.[lessonId]
|
|
112
|
+
|
|
113
|
+
const fellowshipQuestions =
|
|
114
|
+
meetLanguageInfo.questionSets.find(
|
|
115
|
+
(questionSet) => questionSet.questionSetId === lesson.f
|
|
116
|
+
)?.questions ?? []
|
|
117
|
+
|
|
118
|
+
const fellowshipQuestionsText = fellowshipQuestions.map(
|
|
119
|
+
(questionId) => t.questions[questionId]
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
const applicationQuestions =
|
|
123
|
+
meetLanguageInfo.questionSets.find(
|
|
124
|
+
(questionSet) => questionSet.questionSetId === lesson.a
|
|
125
|
+
)?.questions ?? []
|
|
126
|
+
|
|
127
|
+
const applicationQuestionsText = applicationQuestions.map(
|
|
128
|
+
(questionId) => t.questions[questionId]
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
const sections: Section[] = [
|
|
132
|
+
{
|
|
133
|
+
id: 'title',
|
|
134
|
+
isChapter: false,
|
|
135
|
+
header: lessonTitle ?? '',
|
|
136
|
+
index: 0,
|
|
137
|
+
chapter: null,
|
|
138
|
+
indexWithinChapter: 0,
|
|
139
|
+
text: lessonTitle ?? '',
|
|
140
|
+
hasBeep: false,
|
|
141
|
+
},
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
fellowshipQuestions.forEach((questionId, index) => {
|
|
145
|
+
const hasBeep =
|
|
146
|
+
questions.find((question) => question.questionId === questionId)
|
|
147
|
+
?.hasBeep ?? false
|
|
148
|
+
|
|
149
|
+
sections.push({
|
|
150
|
+
id: questionId,
|
|
151
|
+
isChapter: index === 0,
|
|
152
|
+
index: sections.length,
|
|
153
|
+
header: index === 0 ? t.fellowship : null,
|
|
154
|
+
chapter: Chapter.FELLOWSHIP,
|
|
155
|
+
indexWithinChapter: index,
|
|
156
|
+
text: fellowshipQuestionsText[index],
|
|
157
|
+
hasBeep,
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
if (specialIds.evaluationQuestionLessonIds.includes(lesson.lessonId)) {
|
|
162
|
+
sections.push({
|
|
163
|
+
id: 'eq',
|
|
164
|
+
isChapter: false,
|
|
165
|
+
index: sections.length,
|
|
166
|
+
chapter: Chapter.INTRODUCTION,
|
|
167
|
+
indexWithinChapter: 0,
|
|
168
|
+
header: null,
|
|
169
|
+
text: t.introductions.introductions.eq,
|
|
170
|
+
hasBeep: false,
|
|
171
|
+
})
|
|
172
|
+
} else if (specialIds.growingAsDmcSetIds.includes(setInfo.setId)) {
|
|
173
|
+
sections.push({
|
|
174
|
+
id: 'introduction',
|
|
175
|
+
isChapter: false,
|
|
176
|
+
index: sections.length,
|
|
177
|
+
chapter: Chapter.INTRODUCTION,
|
|
178
|
+
indexWithinChapter: 0,
|
|
179
|
+
header: t.introductions.introduction,
|
|
180
|
+
text: t.introductions.introductions[
|
|
181
|
+
lessonId as keyof typeof t.introductions.introductions
|
|
182
|
+
],
|
|
183
|
+
hasBeep: false,
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
lesson.s?.forEach((passageId, index) => {
|
|
188
|
+
sections.push({
|
|
189
|
+
id: passageId,
|
|
190
|
+
isChapter: index === 0,
|
|
191
|
+
hasBeep: false,
|
|
192
|
+
index: sections.length,
|
|
193
|
+
chapter: Chapter.STORY,
|
|
194
|
+
indexWithinChapter: index,
|
|
195
|
+
text: '',
|
|
196
|
+
header: getPassagesString([passageId], meetLanguageInfo),
|
|
197
|
+
})
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
applicationQuestions.forEach((questionId, index) => {
|
|
201
|
+
const hasBeep =
|
|
202
|
+
questions.find((question) => question.questionId === questionId)
|
|
203
|
+
?.hasBeep ?? false
|
|
204
|
+
|
|
205
|
+
sections.push({
|
|
206
|
+
id: questionId,
|
|
207
|
+
isChapter: index === 0,
|
|
208
|
+
hasBeep,
|
|
209
|
+
index: sections.length,
|
|
210
|
+
chapter: Chapter.APPLICATION,
|
|
211
|
+
indexWithinChapter: index,
|
|
212
|
+
header: index === 0 ? t.application : null,
|
|
213
|
+
text: questionId.includes('video')
|
|
214
|
+
? t.training_video
|
|
215
|
+
: applicationQuestionsText[index],
|
|
216
|
+
})
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
const baseInfo = {
|
|
220
|
+
lessonIntroduction: t.introductions.introduction,
|
|
221
|
+
lessonLink: `https://web.waha.app/lesson?lesson-id=${lessonId}&meet-language=${meetLanguageId}`,
|
|
222
|
+
lessonNumber,
|
|
223
|
+
lessonTitle,
|
|
224
|
+
sections,
|
|
225
|
+
...setInfo,
|
|
226
|
+
...lesson,
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (specialIds.evaluationQuestionLessonIds.includes(lesson.lessonId)) {
|
|
230
|
+
const languageId = meetLanguageInfo.introBridge ?? meetLanguageId
|
|
231
|
+
const id = `${languageId}.eq`
|
|
232
|
+
const fileName = `${id}.mp3`
|
|
233
|
+
const path = `${languageId}/introductions/${fileName}`
|
|
234
|
+
|
|
235
|
+
return {
|
|
236
|
+
type: 'eq',
|
|
237
|
+
...baseInfo,
|
|
238
|
+
eq: {
|
|
239
|
+
id,
|
|
240
|
+
languageId,
|
|
241
|
+
localFileName: fileName,
|
|
242
|
+
remoteFileName: fileName,
|
|
243
|
+
path,
|
|
244
|
+
url: firebaseUrl + encodeURIComponent(path) + `?alt=media`,
|
|
245
|
+
},
|
|
246
|
+
}
|
|
247
|
+
} else if (
|
|
248
|
+
setInfo.setId === specialIds.dmCourseSetId ||
|
|
249
|
+
meetLanguageId === 'ase'
|
|
250
|
+
) {
|
|
251
|
+
let video: Content
|
|
252
|
+
|
|
253
|
+
if (meetLanguageInfo.languageId === 'ase') {
|
|
254
|
+
const path = `ase/full_lessons/${setInfo.setId}/ase.${lessonId}.1080.mp4`
|
|
255
|
+
video = {
|
|
256
|
+
id: `ase.${lessonId}`,
|
|
257
|
+
languageId: 'ase',
|
|
258
|
+
path,
|
|
259
|
+
localFileName: `ase.${lessonId}.mp4`,
|
|
260
|
+
remoteFileName: `ase.${lessonId}.1080.mp4`,
|
|
261
|
+
url: firebaseUrl + encodeURIComponent(path) + `?alt=media`,
|
|
262
|
+
}
|
|
263
|
+
} else {
|
|
264
|
+
const id = `${meetLanguageId}.${meetLanguageInfo.trainingVideoLanguage}.${lessonId}`
|
|
265
|
+
const remoteFileName = `${id}.1080.mp4`
|
|
266
|
+
|
|
267
|
+
const localFileName = `${id}.mp4`
|
|
268
|
+
|
|
269
|
+
const path = `${meetLanguageId}/full_lessons/${setInfo?.setId}/${remoteFileName}`
|
|
270
|
+
|
|
271
|
+
video = {
|
|
272
|
+
id,
|
|
273
|
+
languageId: meetLanguageInfo.trainingVideoLanguage,
|
|
274
|
+
path,
|
|
275
|
+
localFileName,
|
|
276
|
+
remoteFileName,
|
|
277
|
+
url: firebaseUrl + encodeURIComponent(path) + `?alt=media`,
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
let youtubeLink: string | undefined
|
|
282
|
+
|
|
283
|
+
if (video.remoteFileName && video.remoteFileName in courseYoutubeVideos)
|
|
284
|
+
youtubeLink =
|
|
285
|
+
'https://www.youtube.com/watch?v=' +
|
|
286
|
+
courseYoutubeVideos[
|
|
287
|
+
video.remoteFileName as keyof typeof courseYoutubeVideos
|
|
288
|
+
]
|
|
289
|
+
|
|
290
|
+
return {
|
|
291
|
+
type: 'video',
|
|
292
|
+
...baseInfo,
|
|
293
|
+
lessonSectionHeader: thisSetTranslations?.sectionHeaders?.[lessonId],
|
|
294
|
+
lessonSectionBody: thisSetTranslations?.sectionBodies?.[lessonId],
|
|
295
|
+
video,
|
|
296
|
+
youtubeLink,
|
|
297
|
+
passagesString: getPassagesString(lesson.s, meetLanguageInfo),
|
|
298
|
+
}
|
|
299
|
+
} else {
|
|
300
|
+
return {
|
|
301
|
+
type: 'dbs',
|
|
302
|
+
...baseInfo,
|
|
303
|
+
full: {
|
|
304
|
+
id: `${meetLanguageId}.${lessonId}`,
|
|
305
|
+
localFileName: `${meetLanguageId}.${lessonId}.mp3`,
|
|
306
|
+
remoteFileName: `${meetLanguageId}.${lessonId}.mp3`,
|
|
307
|
+
languageId: meetLanguageId,
|
|
308
|
+
path: `${meetLanguageId}/full_lessons/${setInfo.setId}/${meetLanguageId}.${lessonId}.mp3`,
|
|
309
|
+
url:
|
|
310
|
+
firebaseUrl +
|
|
311
|
+
encodeURIComponent(
|
|
312
|
+
`${meetLanguageId}/full_lessons/${setInfo.setId}/${meetLanguageId}.${lessonId}.mp3`
|
|
313
|
+
) +
|
|
314
|
+
`?alt=media`,
|
|
315
|
+
},
|
|
316
|
+
dbsCast: {
|
|
317
|
+
remoteFileName: `${meetLanguageId}.${lessonId}.1080.mp4`,
|
|
318
|
+
url:
|
|
319
|
+
firebaseUrl +
|
|
320
|
+
encodeURIComponent(
|
|
321
|
+
`${meetLanguageId}/full_lessons/${setInfo.setId}/${meetLanguageId}.${lessonId}.1080.mp4`
|
|
322
|
+
) +
|
|
323
|
+
`?alt=media`,
|
|
324
|
+
},
|
|
325
|
+
passagesString: getPassagesString(lesson.s, meetLanguageInfo),
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export function convertSToString(time: number): string {
|
|
331
|
+
let secondsNumber: number
|
|
332
|
+
let minutesNumber: number
|
|
333
|
+
let hoursNumber: number
|
|
334
|
+
let secondsString: string
|
|
335
|
+
let minutesString: string
|
|
336
|
+
let hoursString: string
|
|
337
|
+
|
|
338
|
+
if (time > 0) {
|
|
339
|
+
// If the time is greater than an hour, we need to show the hour of the time as well.
|
|
340
|
+
if (time >= 3600) {
|
|
341
|
+
secondsNumber = Math.floor(time % 60)
|
|
342
|
+
minutesNumber = Math.floor((time / 60) % 60)
|
|
343
|
+
hoursNumber = Math.floor((time / (60 * 60)) % 60)
|
|
344
|
+
|
|
345
|
+
secondsString = secondsNumber.toString()
|
|
346
|
+
minutesString =
|
|
347
|
+
minutesNumber < 10
|
|
348
|
+
? '0' + minutesNumber.toString()
|
|
349
|
+
: minutesNumber.toString()
|
|
350
|
+
hoursString =
|
|
351
|
+
hoursNumber < 10 ? '0' + hoursNumber.toString() : hoursNumber.toString()
|
|
352
|
+
|
|
353
|
+
return `${hoursString}:${minutesString}:${secondsString}`
|
|
354
|
+
} else {
|
|
355
|
+
secondsNumber = Math.floor(time % 60)
|
|
356
|
+
minutesNumber = Math.floor((time / 60) % 60)
|
|
357
|
+
|
|
358
|
+
minutesString =
|
|
359
|
+
minutesNumber < 10
|
|
360
|
+
? '0' + minutesNumber.toString()
|
|
361
|
+
: minutesNumber.toString()
|
|
362
|
+
secondsString =
|
|
363
|
+
secondsNumber < 10
|
|
364
|
+
? '0' + secondsNumber.toString()
|
|
365
|
+
: secondsNumber.toString()
|
|
366
|
+
|
|
367
|
+
return `${minutesString}:${secondsString}`
|
|
368
|
+
}
|
|
369
|
+
} // If the time is greater than the max allowed, just show the max.
|
|
370
|
+
else {
|
|
371
|
+
return '00:00'
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/** Determines whether a lesson should be visible in Waha. */
|
|
376
|
+
export function shouldShowLesson(
|
|
377
|
+
lessonInfo: LessonInfo | undefined,
|
|
378
|
+
languageInfo: LanguageInfo
|
|
379
|
+
) {
|
|
380
|
+
if (lessonInfo?.lessonTitle === undefined || lessonInfo.lessonTitle === '') {
|
|
381
|
+
console.log(
|
|
382
|
+
'Missing lesson info or lessonTitle lesson:',
|
|
383
|
+
lessonInfo?.lessonId
|
|
384
|
+
)
|
|
385
|
+
return false
|
|
386
|
+
} else if (
|
|
387
|
+
specialIds.growingAsDmcSetIds.includes(lessonInfo.setId) &&
|
|
388
|
+
(lessonInfo.lessonIntroduction === undefined ||
|
|
389
|
+
lessonInfo.lessonIntroduction === '')
|
|
390
|
+
) {
|
|
391
|
+
console.log('Missing intro for lesson:', lessonInfo.lessonId)
|
|
392
|
+
return false
|
|
393
|
+
} else if (
|
|
394
|
+
lessonInfo.type === 'eq' &&
|
|
395
|
+
!mediaDurations[languageInfo.introBridge ?? languageInfo.languageId]
|
|
396
|
+
.lessons[lessonInfo.eq.remoteFileName]
|
|
397
|
+
) {
|
|
398
|
+
console.log('Missing remote eq file for lesson:', lessonInfo.lessonId)
|
|
399
|
+
return false
|
|
400
|
+
} else if (
|
|
401
|
+
lessonInfo.type === 'dbs' &&
|
|
402
|
+
!mediaDurations[lessonInfo.meetLanguageId].lessons[
|
|
403
|
+
lessonInfo.full.remoteFileName
|
|
404
|
+
]
|
|
405
|
+
) {
|
|
406
|
+
console.log('Missing remote dbs file for lesson:', lessonInfo.lessonId)
|
|
407
|
+
return false
|
|
408
|
+
} else if (
|
|
409
|
+
lessonInfo.type === 'video' &&
|
|
410
|
+
lessonInfo.video &&
|
|
411
|
+
!mediaDurations[lessonInfo.meetLanguageId].lessons[
|
|
412
|
+
lessonInfo.video.remoteFileName
|
|
413
|
+
]
|
|
414
|
+
) {
|
|
415
|
+
console.log(
|
|
416
|
+
'Missing remote video for lesson:',
|
|
417
|
+
lessonInfo.video.remoteFileName
|
|
418
|
+
)
|
|
419
|
+
return false
|
|
420
|
+
} else return true
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Calculate start times for each section based on question durations and total
|
|
425
|
+
* audio duration. Must be called after audio is loaded to get accurate total
|
|
426
|
+
* duration.
|
|
427
|
+
*
|
|
428
|
+
* @param sections - The lesson sections to calculate timings for
|
|
429
|
+
* @param totalDuration - Total duration of the lesson audio in seconds
|
|
430
|
+
* @param languageId - The language ID to look up question durations
|
|
431
|
+
* @returns Map of section ID to start time in seconds
|
|
432
|
+
*/
|
|
433
|
+
export function calculateSectionTimings(
|
|
434
|
+
sections: Section[],
|
|
435
|
+
totalDuration: number,
|
|
436
|
+
languageId: string
|
|
437
|
+
): Map<string, number> {
|
|
438
|
+
const languageDurations = mediaDurations[languageId]
|
|
439
|
+
|
|
440
|
+
const getQuestionDuration = (questionId: string): number => {
|
|
441
|
+
const fileName = `${languageId}.${questionId}.mp3`
|
|
442
|
+
return languageDurations.questions[fileName] ?? 0
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
const timings = new Map<string, number>()
|
|
446
|
+
|
|
447
|
+
// Title section always starts at 0
|
|
448
|
+
timings.set('title', 0)
|
|
449
|
+
|
|
450
|
+
// Calculate fellowship question timings from the start
|
|
451
|
+
let currentTime = 0
|
|
452
|
+
const fellowshipSections = sections.filter(
|
|
453
|
+
(s) => s.chapter === Chapter.FELLOWSHIP
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
fellowshipSections.forEach((section) => {
|
|
457
|
+
timings.set(section.id, currentTime)
|
|
458
|
+
currentTime += getQuestionDuration(section.id)
|
|
459
|
+
})
|
|
460
|
+
|
|
461
|
+
// Story/Scripture section starts after fellowship
|
|
462
|
+
const storySections = sections.filter(
|
|
463
|
+
(s) => s.chapter === Chapter.STORY || s.chapter === Chapter.INTRODUCTION
|
|
464
|
+
)
|
|
465
|
+
const storyStartTime = currentTime
|
|
466
|
+
|
|
467
|
+
storySections.forEach((section) => {
|
|
468
|
+
timings.set(section.id, storyStartTime)
|
|
469
|
+
})
|
|
470
|
+
|
|
471
|
+
// Calculate application question timings by working backwards from total duration
|
|
472
|
+
const applicationSections = sections.filter(
|
|
473
|
+
(s) => s.chapter === Chapter.APPLICATION
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
// Calculate total duration of all application questions
|
|
477
|
+
const totalApplicationDuration = applicationSections.reduce(
|
|
478
|
+
(sum, section) => {
|
|
479
|
+
return sum + getQuestionDuration(section.id)
|
|
480
|
+
},
|
|
481
|
+
0
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
// Application section starts after story ends
|
|
485
|
+
// Story duration = totalDuration - fellowship duration - application duration
|
|
486
|
+
const applicationStartTime = totalDuration - totalApplicationDuration
|
|
487
|
+
|
|
488
|
+
let applicationTime = applicationStartTime
|
|
489
|
+
applicationSections.forEach((section) => {
|
|
490
|
+
timings.set(section.id, applicationTime)
|
|
491
|
+
applicationTime += getQuestionDuration(section.id)
|
|
492
|
+
})
|
|
493
|
+
|
|
494
|
+
return timings
|
|
495
|
+
}
|