Skip to content

Commit 72771ec

Browse files
classes(project-data): implement new methods for screen, area objects
and cover with documentation. - fixes #141 - fixes #142
1 parent ca97867 commit 72771ec

File tree

1 file changed

+92
-6
lines changed

1 file changed

+92
-6
lines changed

src/classes/project-data.js

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,18 @@
88

99
const PackageJson = require('../../package.json')
1010

11-
const { MissingOrderError } = require('../util/error')
11+
const {
12+
CharacterBasedDurationError,
13+
DurationGreaterThanMaxPossibleError,
14+
IconAdjustableError,
15+
MissingOrderError,
16+
ScreenHasVideoAreaError
17+
} = require('../util/error')
18+
const screenDurationUtil = require('../util/screen-duration')
1219
const projectDataUtil = require('../util/project-data')
1320

21+
const { AVERAGE_CHARS_IN_WORD } = require('../config/config')
22+
1423
class ProjectData {
1524
/**
1625
* @constructor
@@ -218,14 +227,18 @@ class ProjectData {
218227
/**
219228
* @param {Object} screen
220229
* @returns {Object}
221-
* @description Construct screen.
230+
* @description Construct screen, adds methods to `screen` object.
222231
*/
223232
constructScreen (screen) {
224233
const {
225234
id, characterBasedDuration, compositionName, duration, extraVideoSecond, gifBigPath, gifPath, gifThumbnailPath,
226235
hidden, iconAdjustable, isFull, maxDuration, order, path, tags, title, type, areas
227236
} = screen
228237

238+
/**
239+
* @namespace screen
240+
* @description The screen object with it's methods.
241+
*/
229242
return {
230243
id,
231244
characterBasedDuration,
@@ -245,10 +258,81 @@ class ProjectData {
245258
title,
246259
type,
247260
areas,
248-
getAreas: () => {
249-
return areas.map((area) => {
250-
return this.constructArea(area)
251-
})
261+
/**
262+
* @returns {Object}
263+
* @description Maps through areas array and adds it's methods.
264+
*/
265+
getAreas: () => areas.map((area) => this.constructArea(area)),
266+
/**
267+
* @throws {ScreenHasVideoAreaError}
268+
* @return {Object.characterBasedDuration}
269+
* @description Checks if `screen` has video area, then throws error.
270+
* Otherwise returns `characterBasedDuration`.
271+
*/
272+
isDurationAdjustable: () => {
273+
const videoAreas = areas.filter((area) => area.type === 'video')
274+
275+
if (videoAreas.length > 0) {
276+
throw new ScreenHasVideoAreaError('The screen has video area.')
277+
}
278+
279+
return characterBasedDuration
280+
},
281+
/**
282+
* @return {number}
283+
* @description Calculates screen duration using screen duration utility.
284+
* Detailed description can be found in screen duration util.
285+
*/
286+
calculateScreenDuration: () => screenDurationUtil.getScreenDuration(screen),
287+
/**
288+
* @returns {number}
289+
* @description Filters ares to find only video ones.
290+
* Checks if count of video areas is more than 0, then counts sum of `wordCount`s.
291+
* Otherwise returns `maxDuration` or `duration`.
292+
*/
293+
getMaxPossibleDuration: () => {
294+
const videoAreas = areas.filter((area) => area.type === 'video')
295+
296+
if (videoAreas.length > 0) {
297+
return videoAreas.reduce((acc, videoArea) => acc + videoArea.wordCount, 0)
298+
}
299+
300+
return maxDuration || duration
301+
},
302+
/**
303+
* @param {number} duration - The new duration to set.
304+
* @throws {CharacterBasedDurationError, DurationGreaterThanMaxPossibleError}
305+
* @description Checks if `characterBasedDuration` is falsy, then throws error.
306+
* If `duration` is more than maximum possible duration, then throws error.
307+
* Otherwise sets `selectedDuration`.
308+
*/
309+
setDuration: function (duration) {
310+
if (!characterBasedDuration) {
311+
throw new CharacterBasedDurationError('Current screen\'s duration is not adjustable.')
312+
}
313+
314+
if (duration > this.getMaxPossibleDuration()) {
315+
throw new DurationGreaterThanMaxPossibleError('Given `value` is greater than maximum possible duration.')
316+
}
317+
318+
this.selectedDuration = duration
319+
},
320+
/**
321+
* @return {boolean}
322+
* @description Checks if icon position is adjustable by double negation.
323+
*/
324+
isIconPositionAdjustable: () => iconAdjustable,
325+
/**
326+
* @throws {IconAdjustableError}
327+
* @description Checks if icon position is not adjustable then throws error.
328+
* Otherwise does `xor` bitwise operation with `iconAdjustable` and 3.
329+
* Number `3` stands for converting 1->2 and 2->1.
330+
*/
331+
changeIconPosition: function () {
332+
if (!this.isIconPositionAdjustable()) {
333+
throw new IconAdjustableError('Icon position is not adjustable.')
334+
}
335+
this.iconAdjustable ^= 3
252336
}
253337
}
254338
}
@@ -271,6 +355,8 @@ class ProjectData {
271355
area.value = text
272356
this.patchProperties.push('screens')
273357
}
358+
359+
result.getRecommendedCharacterCount = () => Math.floor(parseInt(wordCount) * AVERAGE_CHARS_IN_WORD)
274360
}
275361

276362
if (area.type === 'image') {

0 commit comments

Comments
 (0)