@vixoniccom/aniversarios 1.2.3-dev.2 → 1.3.0-dev.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/.github/workflows/sonarqube.yml +30 -0
- package/CHANGELOG.md +16 -0
- package/build.zip +0 -0
- package/configuration/dataGroup/DataInputs.ts +10 -0
- package/configuration.json +17 -0
- package/package.json +1 -1
- package/sonar-project.properties +1 -0
- package/src/App.tsx +3 -3
- package/src/components/AnniversaryItem/components/AnniversaryDate/CircleDate/index.tsx +2 -2
- package/src/components/AnniversaryItem/components/AnniversaryDate/FlatDate/index.tsx +4 -4
- package/src/components/AnniversaryItem/components/AnniversaryDate/OutlineDate/index.tsx +4 -5
- package/src/components/AnniversaryItem/components/AnniversaryDate/TextCalendarDate/index.tsx +4 -5
- package/src/components/AnniversaryItem/components/AnniversaryDate/index.tsx +0 -8
- package/src/components/AnniversaryItem/components/AnniversaryImage/index.tsx +2 -1
- package/src/components/AnniversaryItem/components/ClassicItem/index.tsx +4 -4
- package/src/components/AnniversaryItem/components/Separator/Separator.tsx +3 -5
- package/src/components/AnniversaryItem/components/utils.ts +43 -28
- package/src/components/FontLoader/index.tsx +0 -12
- package/src/components/FormattedText/index.tsx +8 -7
- package/src/components/ItemsContainer/components/Item.tsx +15 -7
- package/src/components/ItemsContainer/components/animation.ts +21 -25
- package/src/components/Render/index.tsx +2 -2
- package/src/index.html +1 -1
- package/src/parameters.d.ts +1 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Sonarqube Analysis
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- development
|
|
7
|
+
pull_request:
|
|
8
|
+
types: [opened, synchronize, reopened]
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
sonarqube:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
with:
|
|
16
|
+
# Disabling shallow clone is recommended for improving relevancy of reporting.
|
|
17
|
+
fetch-depth: 0
|
|
18
|
+
|
|
19
|
+
- name: SonarQube Scan
|
|
20
|
+
uses: sonarsource/sonarqube-scan-action@master
|
|
21
|
+
env:
|
|
22
|
+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
23
|
+
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
|
24
|
+
|
|
25
|
+
- name: SonarQube Quality Gate Check
|
|
26
|
+
uses: sonarsource/sonarqube-quality-gate-action@master
|
|
27
|
+
timeout-minutes: 5
|
|
28
|
+
env:
|
|
29
|
+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
30
|
+
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [1.3.0-dev.1](https://github.com/Vixonic/store-aniversarios/compare/v1.3.0-dev.0...v1.3.0-dev.1) (2025-07-14)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* Replace logical OR with nullish coalescing operator for default values in various components ([c9f2bba](https://github.com/Vixonic/store-aniversarios/commit/c9f2bbafcf44f38b1578b6946a19434f41e50f52))
|
|
11
|
+
* Update maskId generation for unique identifiers in AnniversaryImage component ([6f5b452](https://github.com/Vixonic/store-aniversarios/commit/6f5b4525f640d8730488331c56aed5fb68378e56))
|
|
12
|
+
* Update maskId generation for unique identifiers in AnniversaryImage component ([c9a3d43](https://github.com/Vixonic/store-aniversarios/commit/c9a3d43acc57f707a39a31f131fda6266f674f30))
|
|
13
|
+
|
|
14
|
+
## [1.3.0-dev.0](https://github.com/Vixonic/store-aniversarios/compare/v1.2.3-dev.2...v1.3.0-dev.0) (2025-07-14)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* Add support for photo mode in settings and related components ([5eeab44](https://github.com/Vixonic/store-aniversarios/commit/5eeab443f73553239c940941fc6740b41601228b))
|
|
20
|
+
|
|
5
21
|
### [1.2.3-dev.2](https://github.com/Vixonic/store-aniversarios/compare/v1.2.3-dev.1...v1.2.3-dev.2) (2025-07-11)
|
|
6
22
|
|
|
7
23
|
### [1.2.3-dev.1](https://github.com/Vixonic/store-aniversarios/compare/v1.2.3-dev.0...v1.2.3-dev.1) (2025-07-09)
|
package/build.zip
CHANGED
|
Binary file
|
|
@@ -25,6 +25,16 @@ export const dataInputs = [
|
|
|
25
25
|
serviceType: 'RexmasAnniversarieService',
|
|
26
26
|
show: serviceEnabled.rexmasServiceEnabled
|
|
27
27
|
}),
|
|
28
|
+
new SelectInput({
|
|
29
|
+
id: 'photoMode',
|
|
30
|
+
label: 'Modo de fotos',
|
|
31
|
+
items: [
|
|
32
|
+
{ label: 'Zip', value: 'zip' },
|
|
33
|
+
{ label: 'En linea', value: 'online' }
|
|
34
|
+
],
|
|
35
|
+
defaultValue: 'zip',
|
|
36
|
+
description: 'Selecciona el modo de fotos. Por defecto, Zip.'
|
|
37
|
+
}),
|
|
28
38
|
new SelectAssetKna({
|
|
29
39
|
id: 'photosZip',
|
|
30
40
|
label: 'Archivo Zip para fotos',
|
package/configuration.json
CHANGED
|
@@ -40,6 +40,23 @@
|
|
|
40
40
|
"type": "service-input",
|
|
41
41
|
"serviceType": "RexmasAnniversarieService"
|
|
42
42
|
},
|
|
43
|
+
{
|
|
44
|
+
"id": "photoMode",
|
|
45
|
+
"label": "Modo de fotos",
|
|
46
|
+
"type": "select-input",
|
|
47
|
+
"description": "Selecciona el modo de fotos. Por defecto, Zip.",
|
|
48
|
+
"items": [
|
|
49
|
+
{
|
|
50
|
+
"label": "Zip",
|
|
51
|
+
"value": "zip"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"label": "En linea",
|
|
55
|
+
"value": "online"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"defaultValue": "zip"
|
|
59
|
+
},
|
|
43
60
|
{
|
|
44
61
|
"id": "photosZip",
|
|
45
62
|
"label": "Archivo Zip para fotos",
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
sonar.projectKey=Vixonic_store-aniversarios_cb1129c3-491c-4ada-ac60-75ab0fad0c6a
|
package/src/App.tsx
CHANGED
|
@@ -10,7 +10,7 @@ interface Props {
|
|
|
10
10
|
export const App: React.FunctionComponent<Props> = ({ start, appData, anniversaries }) => {
|
|
11
11
|
|
|
12
12
|
const parameters = appData?.parameters
|
|
13
|
-
const [
|
|
13
|
+
const [anniversariesElements, setAnniversariesElements] = useState<Anniversary[]>(anniversaries)
|
|
14
14
|
|
|
15
15
|
useEffect(() => {
|
|
16
16
|
setAnniversariesElements(anniversaries)
|
|
@@ -19,8 +19,8 @@ export const App: React.FunctionComponent<Props> = ({ start, appData, anniversar
|
|
|
19
19
|
if (!appData) return null
|
|
20
20
|
|
|
21
21
|
return (
|
|
22
|
-
(
|
|
22
|
+
(anniversariesElements.length === 0) ?
|
|
23
23
|
<FormattedText text={parameters?.defaultMessage ?? 'No hay ingresos para mostrar'} format={parameters?.defaultMessageFormat} />
|
|
24
|
-
: <Render appData={appData} start={start} anniversaries={
|
|
24
|
+
: <Render appData={appData} start={start} anniversaries={anniversariesElements} />
|
|
25
25
|
)
|
|
26
26
|
}
|
|
@@ -20,8 +20,8 @@ export const CircleDate: React.FunctionComponent<Props> = ({ day, month, data })
|
|
|
20
20
|
<circle fill={datePrimaryColor} cx='200' cy='200' r='200' />
|
|
21
21
|
<foreignObject width='400' height='400'>
|
|
22
22
|
<div style={{ height: 400, width: 400, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
|
|
23
|
-
<FormattedText text={AnniveraryDateUtils.getMonth(month, true)} format={
|
|
24
|
-
<FormattedText text={AnniveraryDateUtils.getZeroLeadedText(day)} format={
|
|
23
|
+
<FormattedText text={AnniveraryDateUtils.getMonth(month, true)} format={{...dateMonthFormat, fontSize: monthSize}} unit='px' />
|
|
24
|
+
<FormattedText text={AnniveraryDateUtils.getZeroLeadedText(day)} format={{...dateDayFormat, fontSize: daySize}} unit='px' />
|
|
25
25
|
</div>
|
|
26
26
|
</foreignObject>
|
|
27
27
|
</g>
|
|
@@ -11,8 +11,8 @@ export const FlatDate: React.FunctionComponent<Props> = ({ month, day, data }: P
|
|
|
11
11
|
const { abbreviatedMonths, dateDayFormat, dateMonthFormat, orientation, datePrimaryColor } = data.parameters
|
|
12
12
|
|
|
13
13
|
const sizeProp = AnniveraryDateUtils.utils(orientation)
|
|
14
|
-
const monthSize = ((dateMonthFormat?.fontSize
|
|
15
|
-
const daySize = ((dateDayFormat?.fontSize
|
|
14
|
+
const monthSize = ((dateMonthFormat?.fontSize ?? 18.5) * 400) / 100
|
|
15
|
+
const daySize = ((dateDayFormat?.fontSize ?? 57.5) * 400) / 100
|
|
16
16
|
|
|
17
17
|
const getFontFamily = (format: any) => {
|
|
18
18
|
if (format?.font?.filename) return format.font.filename.replace('.', '-')
|
|
@@ -29,7 +29,7 @@ export const FlatDate: React.FunctionComponent<Props> = ({ month, day, data }: P
|
|
|
29
29
|
textAnchor='middle'
|
|
30
30
|
alignmentBaseline='central' x='200' y='55'
|
|
31
31
|
fontSize={monthSize} preserveAspectRatio='none'
|
|
32
|
-
fill={dateMonthFormat?.fontColor
|
|
32
|
+
fill={dateMonthFormat?.fontColor ?? '#fff'} fontSizeAdjust=''>
|
|
33
33
|
{AnniveraryDateUtils.getMonth(month, abbreviatedMonths)}
|
|
34
34
|
</text>
|
|
35
35
|
|
|
@@ -37,7 +37,7 @@ export const FlatDate: React.FunctionComponent<Props> = ({ month, day, data }: P
|
|
|
37
37
|
textAnchor='middle'
|
|
38
38
|
alignmentBaseline='central' x='200' y='245'
|
|
39
39
|
fontSize={daySize} preserveAspectRatio='none'
|
|
40
|
-
fill={dateDayFormat?.fontColor
|
|
40
|
+
fill={dateDayFormat?.fontColor ?? '#fff'} fontSizeAdjust=''>
|
|
41
41
|
{AnniveraryDateUtils.getZeroLeadedText(day)}
|
|
42
42
|
</text>
|
|
43
43
|
</g>
|
|
@@ -14,11 +14,10 @@ export const OutlineDate: React.FunctionComponent<Props> = ({ day, month, data }
|
|
|
14
14
|
const sizeProp = AnniveraryDateUtils.utils(orientation)
|
|
15
15
|
|
|
16
16
|
const parseFormat = (format: any, defaultSize: any) => {
|
|
17
|
-
return
|
|
18
|
-
|
|
19
|
-
format
|
|
20
|
-
|
|
21
|
-
)
|
|
17
|
+
return {
|
|
18
|
+
...format,
|
|
19
|
+
fontSize: format.fontSize || defaultSize
|
|
20
|
+
}
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
const [monthFormatState,] = useState(parseFormat(dateMonthFormat, 20))
|
package/src/components/AnniversaryItem/components/AnniversaryDate/TextCalendarDate/index.tsx
CHANGED
|
@@ -13,11 +13,10 @@ export const TextCalendarDate: React.FunctionComponent<Props> = ({ day, month, d
|
|
|
13
13
|
const sizeProp = AnniveraryDateUtils.utils(orientation, '100%')
|
|
14
14
|
|
|
15
15
|
const parseFormat = (format: any, defaultSize: any) => {
|
|
16
|
-
return
|
|
17
|
-
|
|
18
|
-
format
|
|
19
|
-
|
|
20
|
-
)
|
|
16
|
+
return {
|
|
17
|
+
...format,
|
|
18
|
+
fontSize: format.fontSize || defaultSize
|
|
19
|
+
}
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
const [monthFormatState,] = useState(parseFormat(dateMonthFormat, 20))
|
|
@@ -12,14 +12,6 @@ const itemStyles = {
|
|
|
12
12
|
outlines: OutlineDate
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
interface itemStyles {
|
|
16
|
-
calendarFlat: string
|
|
17
|
-
calendarText: string
|
|
18
|
-
circle: string
|
|
19
|
-
text: string
|
|
20
|
-
outlines: string
|
|
21
|
-
}
|
|
22
|
-
|
|
23
15
|
interface Props {
|
|
24
16
|
style: keyof typeof itemStyles,
|
|
25
17
|
day: number,
|
|
@@ -2,6 +2,7 @@ import React, { useEffect, useRef, useState } from 'react'
|
|
|
2
2
|
import { AnniveraryDateUtils } from '../AnniversaryDate/utils'
|
|
3
3
|
|
|
4
4
|
const defaultImg = require('../default-profile.png')
|
|
5
|
+
let idCounter = 0
|
|
5
6
|
const borderStyles = {
|
|
6
7
|
normal: '0',
|
|
7
8
|
rounded: '10',
|
|
@@ -18,7 +19,7 @@ interface Props {
|
|
|
18
19
|
export const AnniversaryImage: React.FunctionComponent<Props> = ({ url, size, borderStyle, orientation }) => {
|
|
19
20
|
const [urlState, setUrlState] = useState(url || defaultImg)
|
|
20
21
|
const input = useRef<SVGImageElement>(null)
|
|
21
|
-
const maskId =
|
|
22
|
+
const maskId = `mask-${Date.now()}-${++idCounter}`
|
|
22
23
|
const imageExist = (url: any) => {
|
|
23
24
|
const isValidImage = url.substr(-3).toLowerCase() === 'png' || url.substr(-3).toLowerCase() === 'jpg' || url.substr(-4).toLowerCase() === 'jpeg'
|
|
24
25
|
return isValidImage ? url : defaultImg
|
|
@@ -14,11 +14,11 @@ export const ClassicItem: React.FunctionComponent<Props> = ({ anniversary, data
|
|
|
14
14
|
const { parameters, downloadsPath } = data
|
|
15
15
|
const { orientation, separatorColor, separatorWidth, imageSize } = parameters
|
|
16
16
|
const [margins, setMargins] = useState(parseBorderMargin(parameters.itemMargins))
|
|
17
|
-
const [state, setState] = useState(
|
|
17
|
+
const [state, setState] = useState({...parseParameters(parameters)})
|
|
18
18
|
|
|
19
19
|
useEffect(() => {
|
|
20
20
|
setMargins(parseBorderMargin(parameters.itemMargins))
|
|
21
|
-
setState(
|
|
21
|
+
setState({...parseParameters(parameters)})
|
|
22
22
|
}, [])
|
|
23
23
|
|
|
24
24
|
const separatorProps = {
|
|
@@ -72,7 +72,7 @@ export const ClassicItem: React.FunctionComponent<Props> = ({ anniversary, data
|
|
|
72
72
|
/>
|
|
73
73
|
{state.descriptionEnabled && (
|
|
74
74
|
<FormattedText
|
|
75
|
-
text={anniversary.position
|
|
75
|
+
text={anniversary.position ?? ''}
|
|
76
76
|
format={parameters.descriptionFormat}
|
|
77
77
|
maxChar={Number(parameters.descriptionMaxChar)}
|
|
78
78
|
lineHeight={1.2}
|
|
@@ -80,7 +80,7 @@ export const ClassicItem: React.FunctionComponent<Props> = ({ anniversary, data
|
|
|
80
80
|
)}
|
|
81
81
|
{state.optionalEnabled && (
|
|
82
82
|
<FormattedText
|
|
83
|
-
text={anniversary.optional
|
|
83
|
+
text={anniversary.optional ?? ''}
|
|
84
84
|
format={parameters.optionalFormat}
|
|
85
85
|
maxChar={Number(parameters.descriptionMaxChar)}
|
|
86
86
|
lineHeight={1.2}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
1
|
interface Props {
|
|
4
2
|
order: number | undefined
|
|
5
3
|
size: number | undefined
|
|
@@ -12,12 +10,12 @@ export const Separator = ({ order, size, color, orientation, margins }: Props) =
|
|
|
12
10
|
const getSizeStyle = (orientation: any, size: any) => {
|
|
13
11
|
if (orientation === 'h') {
|
|
14
12
|
return {
|
|
15
|
-
width: size
|
|
13
|
+
width: size ?? 0,
|
|
16
14
|
height: '100%'
|
|
17
15
|
}
|
|
18
16
|
} else {
|
|
19
17
|
return {
|
|
20
|
-
height: size
|
|
18
|
+
height: size ?? 0,
|
|
21
19
|
width: '100%'
|
|
22
20
|
}
|
|
23
21
|
}
|
|
@@ -29,7 +27,7 @@ export const Separator = ({ order, size, color, orientation, margins }: Props) =
|
|
|
29
27
|
<div style={{
|
|
30
28
|
flexShrink: 0,
|
|
31
29
|
order: order,
|
|
32
|
-
backgroundColor: color
|
|
30
|
+
backgroundColor: color ?? '',
|
|
33
31
|
margin: margins,
|
|
34
32
|
...sizeStyle
|
|
35
33
|
}} />
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
export const utils = (orientation: string, size: number) => {
|
|
2
2
|
const sizeAttr = orientation === 'v' ? 'width' : 'height'
|
|
3
|
-
|
|
3
|
+
let percentage: string
|
|
4
|
+
if (size) {
|
|
5
|
+
percentage = `${size}%`
|
|
6
|
+
} else {
|
|
7
|
+
percentage = orientation === 'v' ? '40%' : '80%'
|
|
8
|
+
}
|
|
4
9
|
return { [sizeAttr]: percentage }
|
|
5
10
|
}
|
|
6
11
|
|
|
7
12
|
export const parseBorderMargin = (marginString: any) => {
|
|
8
|
-
const
|
|
13
|
+
const numberPattern = '[+-]?[0-9]+\\.?[0-9]*'
|
|
14
|
+
const unitPattern = '(px|em|ex|%|in|cm|mm|pt|pc)'
|
|
15
|
+
const spacePattern = '( )?'
|
|
16
|
+
const fullPattern = `(${spacePattern}${numberPattern}${unitPattern})?`
|
|
17
|
+
const pattern = new RegExp(fullPattern, 'g')
|
|
9
18
|
const match = marginString ? marginString.match(pattern) : ['']
|
|
10
19
|
|
|
11
20
|
switch (match.length) {
|
|
@@ -22,11 +31,11 @@ const parseElementStyles = (margin: string, position: number, defaultPosition: n
|
|
|
22
31
|
const { orientation, separator } = parameters
|
|
23
32
|
const marginAttr = orientation === 'v' ? 'marginBottom' : 'marginRight'
|
|
24
33
|
const sizeAttr = orientation === 'v' ? 'width' : 'height'
|
|
25
|
-
const pos =
|
|
34
|
+
const pos = position ?? defaultPosition
|
|
26
35
|
return {
|
|
27
36
|
order: pos,
|
|
28
37
|
[sizeAttr]: '100%',
|
|
29
|
-
[marginAttr]: margin
|
|
38
|
+
[marginAttr]: getMarginValue(margin, pos, separator)
|
|
30
39
|
}
|
|
31
40
|
}
|
|
32
41
|
|
|
@@ -37,39 +46,45 @@ export const parseParameters = (parameters: any) => {
|
|
|
37
46
|
|
|
38
47
|
return {
|
|
39
48
|
imageEnabled: parameters.imageEnabled,
|
|
40
|
-
imageStyle:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
parseElementStyles(parameters.imageMargin, parameters.imagePosition, 1, parameters)
|
|
48
|
-
),
|
|
49
|
+
imageStyle: {
|
|
50
|
+
flexShrink: 0,
|
|
51
|
+
display: 'flex',
|
|
52
|
+
justifyContent: imageAlignment,
|
|
53
|
+
alignItems: imageAlignment,
|
|
54
|
+
...parseElementStyles(parameters.imageMargin, parameters.imagePosition, 1, parameters)
|
|
55
|
+
},
|
|
49
56
|
descriptionEnabled: parameters.descriptionEnabled,
|
|
50
57
|
optionalEnabled: parameters.optionalEnabled,
|
|
51
|
-
textStyle:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
textStyle: {
|
|
59
|
+
display: 'flex',
|
|
60
|
+
flexDirection: 'column',
|
|
61
|
+
justifyContent: textAlignment,
|
|
62
|
+
flex: 1,
|
|
63
|
+
...parseElementStyles(parameters.textMargin, parameters.textPosition, 2, parameters)
|
|
64
|
+
},
|
|
55
65
|
dateEnabled: parameters.dateEnabled,
|
|
56
|
-
dateStyle:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
parseElementStyles(parameters.dateMargin, parameters.datePosition, 3, parameters)
|
|
64
|
-
),
|
|
66
|
+
dateStyle: {
|
|
67
|
+
display: 'flex',
|
|
68
|
+
justifyContent: dateAlignment,
|
|
69
|
+
alignItems: dateAlignment,
|
|
70
|
+
flexShrink: 0,
|
|
71
|
+
...parseElementStyles(parameters.dateMargin, parameters.datePosition, 3, parameters)
|
|
72
|
+
},
|
|
65
73
|
}
|
|
66
74
|
}
|
|
67
75
|
|
|
68
76
|
export const getPhotoUrl = (filename: string, parameters: VixonicParameters, downloadsPath: string) => {
|
|
69
|
-
const mode = parameters.
|
|
70
|
-
if (mode === 'zip' && parameters.photosZip
|
|
77
|
+
const mode = parameters.photoMode
|
|
78
|
+
if (mode === 'zip' && parameters.photosZip?.filename !== undefined) {
|
|
71
79
|
return downloadsPath + '/' + parameters.photosZip.filename.replace('.zip', '/') + filename
|
|
72
80
|
} else {
|
|
73
81
|
return filename
|
|
74
82
|
}
|
|
75
83
|
}
|
|
84
|
+
|
|
85
|
+
const getMarginValue = (margin: string, pos: number, separator?: boolean): string | number => {
|
|
86
|
+
if (margin !== undefined && margin !== '') {
|
|
87
|
+
return `${margin}%`;
|
|
88
|
+
}
|
|
89
|
+
return pos === 3 || separator === true ? 0 : '4%';
|
|
90
|
+
};
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import PropTypes from 'prop-types'
|
|
2
|
-
|
|
3
1
|
interface Props {
|
|
4
2
|
paths: Array<string>
|
|
5
3
|
data: VixonicData
|
|
@@ -40,13 +38,3 @@ export const FontLoader = ({ paths, data }: Props) => {
|
|
|
40
38
|
<style>{fonts}</style>
|
|
41
39
|
)
|
|
42
40
|
}
|
|
43
|
-
|
|
44
|
-
FontLoader.defaultProps = {
|
|
45
|
-
paths: []
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
FontLoader.propTypes = {
|
|
49
|
-
paths: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
50
|
-
data: PropTypes.object.isRequired
|
|
51
|
-
}
|
|
52
|
-
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { CSSProperties } from 'react'
|
|
2
2
|
|
|
3
3
|
const alignments = {
|
|
4
4
|
center: 'center',
|
|
@@ -15,7 +15,7 @@ interface Props {
|
|
|
15
15
|
format?: any
|
|
16
16
|
lineHeight?: number
|
|
17
17
|
maxChar?: number
|
|
18
|
-
style?:
|
|
18
|
+
style?: CSSProperties
|
|
19
19
|
text: string
|
|
20
20
|
unit?: string
|
|
21
21
|
paddingBottom?: string
|
|
@@ -25,7 +25,7 @@ interface Props {
|
|
|
25
25
|
export const FormattedText: React.FunctionComponent<Props> = ({ text, format, maxChar, lineHeight, style, unit, paddingBottom, paddingTop }) => {
|
|
26
26
|
const trimText = (text: any, maxChar: any) => {
|
|
27
27
|
const isValid = maxChar && maxChar >= 3
|
|
28
|
-
if (isValid && (text && text.length > maxChar)
|
|
28
|
+
if (isValid && (text && text.length > maxChar)) {
|
|
29
29
|
const returnText = text.substring(0, maxChar - 3)
|
|
30
30
|
returnText.substr(-1, 3)
|
|
31
31
|
return `${returnText.trim()}...`
|
|
@@ -35,7 +35,7 @@ export const FormattedText: React.FunctionComponent<Props> = ({ text, format, ma
|
|
|
35
35
|
|
|
36
36
|
const checkNested = (obj: any, path: string): boolean => {
|
|
37
37
|
return path.split('.').every(segment => {
|
|
38
|
-
if (obj
|
|
38
|
+
if (obj?.hasOwnProperty(segment)) {
|
|
39
39
|
obj = obj[segment]
|
|
40
40
|
return true
|
|
41
41
|
}
|
|
@@ -52,10 +52,11 @@ export const FormattedText: React.FunctionComponent<Props> = ({ text, format, ma
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
const renderText = maxChar ? trimText(text, maxChar) : text
|
|
55
|
-
const containerStyle =
|
|
55
|
+
const containerStyle = {
|
|
56
56
|
display: 'inline-flex',
|
|
57
|
-
justifyContent: getHorizontalAlignment(format.alignment)
|
|
58
|
-
|
|
57
|
+
justifyContent: getHorizontalAlignment(format.alignment),
|
|
58
|
+
...style
|
|
59
|
+
}
|
|
59
60
|
|
|
60
61
|
return (
|
|
61
62
|
<div style={containerStyle}>
|
|
@@ -16,9 +16,21 @@ interface Props {
|
|
|
16
16
|
style: any
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
|
|
20
|
+
|
|
19
21
|
export const Item = ({ width, height, containerData, verticalGap, horizontalGap, children, style }: Props) => {
|
|
20
22
|
const itemRef = useRef(null)
|
|
21
23
|
|
|
24
|
+
let topPosition = '0';
|
|
25
|
+
if (containerData.ic_rowIndex !== 0) {
|
|
26
|
+
topPosition = verticalGap ? `${verticalGap * containerData.ic_rowIndex}%` : '0';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let leftPadding = '0'
|
|
30
|
+
if (containerData.ic_columnIndex !== 0) {
|
|
31
|
+
leftPadding = horizontalGap ? `${horizontalGap}%` : '0';
|
|
32
|
+
}
|
|
33
|
+
|
|
22
34
|
return (
|
|
23
35
|
<div ref={itemRef}
|
|
24
36
|
style={{
|
|
@@ -29,13 +41,9 @@ export const Item = ({ width, height, containerData, verticalGap, horizontalGap,
|
|
|
29
41
|
justifyContent: aligments['center'],
|
|
30
42
|
width: width,
|
|
31
43
|
height: height,
|
|
32
|
-
top:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
paddingLeft: containerData.ic_columnIndex === 0
|
|
36
|
-
? '0'
|
|
37
|
-
: horizontalGap ? `${horizontalGap}%` : '0'
|
|
38
|
-
, ...style
|
|
44
|
+
top: topPosition,
|
|
45
|
+
paddingLeft: leftPadding,
|
|
46
|
+
...style
|
|
39
47
|
}}
|
|
40
48
|
>
|
|
41
49
|
{React.cloneElement(children, containerData)}
|
|
@@ -75,10 +75,10 @@ export class AnimationController {
|
|
|
75
75
|
|
|
76
76
|
configure(options: Partial<Options>) {
|
|
77
77
|
this.mode = options.mode && animationModes.hasOwnProperty(options.mode) ? animationModes[options.mode] : animationModes.fade
|
|
78
|
-
this.duration = options.duration
|
|
79
|
-
this.speed = 1000 * (options.speed
|
|
80
|
-
this.stagger = this.speed / (options.stagger
|
|
81
|
-
this.reverse = options.reverse
|
|
78
|
+
this.duration = options.duration ?? 10000
|
|
79
|
+
this.speed = 1000 * (options.speed ?? 1)
|
|
80
|
+
this.stagger = this.speed / (options.stagger ?? 4)
|
|
81
|
+
this.reverse = options.reverse ?? true
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
getInitialStyle() {
|
|
@@ -96,31 +96,27 @@ export class AnimationController {
|
|
|
96
96
|
autoplay: false,
|
|
97
97
|
})
|
|
98
98
|
animation.add(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return i * self.stagger
|
|
105
|
-
},
|
|
99
|
+
{
|
|
100
|
+
targets: els,
|
|
101
|
+
duration: this.speed,
|
|
102
|
+
delay: function (_el: any, i: any, _l: any) {
|
|
103
|
+
return i * self.stagger
|
|
106
104
|
},
|
|
107
|
-
this.mode.in
|
|
108
|
-
|
|
105
|
+
...this.mode.in
|
|
106
|
+
}
|
|
109
107
|
)
|
|
110
108
|
animation.add(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return _i * self.stagger
|
|
117
|
-
},
|
|
118
|
-
complete: () => {
|
|
119
|
-
finished()
|
|
120
|
-
},
|
|
109
|
+
{
|
|
110
|
+
targets: els,
|
|
111
|
+
duration: this.speed,
|
|
112
|
+
delay: function (_el: any, _i: any, _l: any) {
|
|
113
|
+
return _i * self.stagger
|
|
121
114
|
},
|
|
122
|
-
|
|
123
|
-
|
|
115
|
+
complete: () => {
|
|
116
|
+
finished()
|
|
117
|
+
},
|
|
118
|
+
...this.mode.out
|
|
119
|
+
},
|
|
124
120
|
`+=${offset}`
|
|
125
121
|
)
|
|
126
122
|
animation.play()
|
|
@@ -21,11 +21,11 @@ export const Render = ({ start, appData, anniversaries }: Props) => {
|
|
|
21
21
|
animationTime,
|
|
22
22
|
} = parameters
|
|
23
23
|
|
|
24
|
-
const backgroundImageState = backgroundImage
|
|
24
|
+
const backgroundImageState = backgroundImage?.filename
|
|
25
25
|
? `url("${downloadsPath}/${backgroundImage.filename}")` : ''
|
|
26
26
|
|
|
27
27
|
const anniversaryItems = anniversaries.map((anniversary: Anniversary) => {
|
|
28
|
-
return <AnniversaryItem style={'standard'} anniversary={anniversary} data={appData} />
|
|
28
|
+
return <AnniversaryItem style={'standard'} anniversary={anniversary} data={appData} key={anniversary?.name} />
|
|
29
29
|
})
|
|
30
30
|
|
|
31
31
|
return (
|
package/src/index.html
CHANGED
package/src/parameters.d.ts
CHANGED
|
@@ -5,5 +5,5 @@ declare type VixonicData = {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
declare type VixonicParameters = Partial<{
|
|
8
|
-
displayService: 'AnniversaryAppService' | 'RexmasAnniversarieService', documentService: { id: string }, rexmasService: { id: string }, photosZip: {id?: string, filename?: string, extension?: string}, updateTime: 600000 | 1800000 | 3600000 | 21600000 | 43200000 | 86400000 | 604800000, defaultMessage: string, defaultMessageFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, orientation: 'h' | 'v', animationMode: 'fade' | 'slideRight' | 'slideLeft', animationSpeed: 2 | 1.5 | 1, animationOrder: boolean, animationTime: number, containerColumns: number, containerColumnsGap: number, containerRows: number, containerRowsGap: number, backgroundImage: {id?: string, filename?: string, extension?: string}, padding: string, textPosition: 1 | 2 | 3, textAlignment: 'start' | 'center' | 'end', nameFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, nameMaxChar: number, textMargin: string, descriptionEnabled: boolean, descriptionFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, descriptionMaxChar: number, optionalEnabled: boolean, optionalFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, imageEnabled: boolean, imagePosition: 1 | 2 | 3, imageAlignment: 'start' | 'center' | 'end', imageStyle: 'normal' | 'rounded' | 'circle', imageMargin: string, imageSize: number, dateEnabled: boolean, datePosition: 1 | 2 | 3, dateAlignment: 'start' | 'center' | 'end', dateStyle: 'calendarFlat' | 'calendarText' | 'circle' | 'text' | 'outlines', dateDayFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, dateMonthFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, abbreviatedMonths: boolean, datePrimaryColor: string, dateMargin: string, separator: boolean, separatorWidth: number, separatorColor: string, itemMargins: string
|
|
8
|
+
displayService: 'AnniversaryAppService' | 'RexmasAnniversarieService', documentService: { id: string }, rexmasService: { id: string }, photoMode: 'zip' | 'online', photosZip: {id?: string, filename?: string, extension?: string}, updateTime: 600000 | 1800000 | 3600000 | 21600000 | 43200000 | 86400000 | 604800000, defaultMessage: string, defaultMessageFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, orientation: 'h' | 'v', animationMode: 'fade' | 'slideRight' | 'slideLeft', animationSpeed: 2 | 1.5 | 1, animationOrder: boolean, animationTime: number, containerColumns: number, containerColumnsGap: number, containerRows: number, containerRowsGap: number, backgroundImage: {id?: string, filename?: string, extension?: string}, padding: string, textPosition: 1 | 2 | 3, textAlignment: 'start' | 'center' | 'end', nameFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, nameMaxChar: number, textMargin: string, descriptionEnabled: boolean, descriptionFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, descriptionMaxChar: number, optionalEnabled: boolean, optionalFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, imageEnabled: boolean, imagePosition: 1 | 2 | 3, imageAlignment: 'start' | 'center' | 'end', imageStyle: 'normal' | 'rounded' | 'circle', imageMargin: string, imageSize: number, dateEnabled: boolean, datePosition: 1 | 2 | 3, dateAlignment: 'start' | 'center' | 'end', dateStyle: 'calendarFlat' | 'calendarText' | 'circle' | 'text' | 'outlines', dateDayFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, dateMonthFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, abbreviatedMonths: boolean, datePrimaryColor: string, dateMargin: string, separator: boolean, separatorWidth: number, separatorColor: string, itemMargins: string
|
|
9
9
|
}>
|