@smileid/web-components 10.0.3 → 10.0.5
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/dist/esm/{DocumentCaptureScreens-CkWKSrqy.js → DocumentCaptureScreens-BIJUlWLB.js} +98 -56
- package/dist/esm/DocumentCaptureScreens-BIJUlWLB.js.map +1 -0
- package/dist/esm/{EndUserConsent-CMHp-34-.js → EndUserConsent-D4fd1ovG.js} +2 -2
- package/dist/esm/{EndUserConsent-CMHp-34-.js.map → EndUserConsent-D4fd1ovG.js.map} +1 -1
- package/dist/esm/{Navigation-juBE4qOw.js → Navigation-CTjK6tLU.js} +6 -6
- package/dist/esm/{Navigation-juBE4qOw.js.map → Navigation-CTjK6tLU.js.map} +1 -1
- package/dist/esm/SelfieCaptureScreens-CnMaKUmP.js +11361 -0
- package/dist/esm/SelfieCaptureScreens-CnMaKUmP.js.map +1 -0
- package/dist/esm/document.js +1 -1
- package/dist/esm/end-user-consent.js +1 -1
- package/dist/esm/main.js +4 -4
- package/dist/esm/navigation.js +1 -1
- package/dist/esm/{package-CmYr0HUS.js → package-PZvRbm5J.js} +2 -2
- package/dist/esm/{package-CmYr0HUS.js.map → package-PZvRbm5J.js.map} +1 -1
- package/dist/esm/selfie.js +1 -1
- package/dist/esm/smart-camera-web.js +12 -6
- package/dist/esm/smart-camera-web.js.map +1 -1
- package/dist/esm/{styles-D2i3GFLK.js → styles-BOEZtbuc.js} +19 -5
- package/dist/esm/{styles-D2i3GFLK.js.map → styles-BOEZtbuc.js.map} +1 -1
- package/dist/smart-camera-web.js +278 -290
- package/dist/smart-camera-web.js.map +1 -1
- package/lib/components/document/src/DocumentCaptureScreens.js +1 -1
- package/lib/components/document/src/document-capture/DocumentCapture.js +2 -1
- package/lib/components/document/src/document-capture-instructions/DocumentCaptureInstructions.js +54 -8
- package/lib/components/document/src/document-capture-review/DocumentCaptureReview.js +2 -3
- package/lib/components/navigation/src/Navigation.js +5 -5
- package/lib/components/selfie/src/SelfieCaptureScreens.js +116 -118
- package/lib/components/selfie/src/selfie-capture/SelfieCapture.js +54 -10
- package/lib/components/selfie/src/selfie-capture-instructions/SelfieCaptureInstructions.js +91 -58
- package/lib/components/selfie/src/selfie-capture-review/SelfieCaptureReview.js +23 -154
- package/lib/components/selfie/src/selfie-capture-wrapper/SelfieCaptureWrapper.tsx +13 -0
- package/lib/components/selfie/src/smartselfie-capture/SmartSelfieCapture.tsx +66 -6
- package/lib/components/selfie/src/smartselfie-capture/components/CaptureControls.tsx +2 -0
- package/lib/components/selfie/src/smartselfie-capture/hooks/useCamera.ts +165 -21
- package/lib/components/selfie/src/smartselfie-capture/hooks/useFaceCapture.ts +82 -23
- package/lib/components/selfie/src/smartselfie-capture/utils/alertMessages.ts +2 -1
- package/lib/components/selfie/src/smartselfie-capture/utils/mediapipeManager.ts +18 -1
- package/lib/components/signature-pad/package.json +1 -1
- package/lib/components/smart-camera-web/src/SmartCameraWeb.js +7 -1
- package/lib/styles/src/styles.js +18 -4
- package/package.json +3 -1
- package/dist/esm/DocumentCaptureScreens-CkWKSrqy.js.map +0 -1
- package/dist/esm/SelfieCaptureScreens-BF1keQ0h.js +0 -7619
- package/dist/esm/SelfieCaptureScreens-BF1keQ0h.js.map +0 -1
|
@@ -50,7 +50,7 @@ class DocumentCaptureScreens extends HTMLElement {
|
|
|
50
50
|
connectedCallback() {
|
|
51
51
|
this.innerHTML = `
|
|
52
52
|
${styles(this.themeColor)}
|
|
53
|
-
<div>
|
|
53
|
+
<div style="height: 100%;">
|
|
54
54
|
<document-capture-instructions theme-color='${this.themeColor}' id='document-capture-instructions-front' ${this.title}
|
|
55
55
|
${this.documentCaptureModes} ${this.showNavigation} ${this.hideInstructions ? 'hidden' : ''}
|
|
56
56
|
${this.hideAttribution}
|
|
@@ -60,11 +60,11 @@ function templateString() {
|
|
|
60
60
|
|
|
61
61
|
#document-capture-screen,
|
|
62
62
|
#back-of-document-capture-screen {
|
|
63
|
-
block-size: 45rem;
|
|
64
63
|
display: flex;
|
|
65
64
|
flex-direction: column;
|
|
66
65
|
max-block-size: 100%;
|
|
67
66
|
max-inline-size: 40ch;
|
|
67
|
+
padding: 1rem;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
#document-capture-screen header p {
|
|
@@ -121,6 +121,7 @@ function templateString() {
|
|
|
121
121
|
inset: -1px;
|
|
122
122
|
}
|
|
123
123
|
canvas {
|
|
124
|
+
width: 100%;
|
|
124
125
|
border-width: 0.25rem;
|
|
125
126
|
border-color: #9394ab;
|
|
126
127
|
border-style: solid;
|
package/lib/components/document/src/document-capture-instructions/DocumentCaptureInstructions.js
CHANGED
|
@@ -155,12 +155,51 @@ function backDocumentIcon() {
|
|
|
155
155
|
|
|
156
156
|
function templateString() {
|
|
157
157
|
return `
|
|
158
|
+
<style>
|
|
159
|
+
h1 {
|
|
160
|
+
font-size: 1.25rem;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.controls {
|
|
164
|
+
width: 100%;
|
|
165
|
+
margin-top: 1rem;
|
|
166
|
+
display: flex;
|
|
167
|
+
flex-direction: column;
|
|
168
|
+
gap: 0.5rem;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.content-root {
|
|
172
|
+
height: 100%;
|
|
173
|
+
display: flex;
|
|
174
|
+
align-items: center;
|
|
175
|
+
flex-direction: column;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.content-header, .content-body, .content-footer {
|
|
179
|
+
width: 100%;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.content-body {
|
|
183
|
+
height: 100%;
|
|
184
|
+
display: flex;
|
|
185
|
+
flex-direction: column;
|
|
186
|
+
align-items: center;
|
|
187
|
+
justify-content: space-between;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.content-body header {
|
|
191
|
+
margin-top: 1rem;
|
|
192
|
+
}
|
|
193
|
+
</style>
|
|
158
194
|
<div id="document-capture-instructions-screen" class="flow center">
|
|
159
|
-
<
|
|
195
|
+
<div class="content-root">
|
|
196
|
+
<div class="content-header">
|
|
160
197
|
<smileid-navigation theme-color='${this.themeColor}' ${this.showNavigation ? 'show-navigation' : ''} ${this.hideBack ? 'hide-back' : ''}></smileid-navigation>
|
|
198
|
+
</div>
|
|
199
|
+
<div class="content-body">
|
|
161
200
|
<header>
|
|
162
201
|
${this.isFrontOfId ? frontDocumentIcon() : backDocumentIcon()}
|
|
163
|
-
<h1 class='
|
|
202
|
+
<h1 class='title-color font-bold'>${this.title}</h1>
|
|
164
203
|
<p class="description text-sm font-normal">
|
|
165
204
|
We'll use it to verify your identity.
|
|
166
205
|
</p>
|
|
@@ -168,7 +207,7 @@ function templateString() {
|
|
|
168
207
|
Please follow the instructions below.
|
|
169
208
|
</p>
|
|
170
209
|
</header>
|
|
171
|
-
<div class="
|
|
210
|
+
<div class="instructions-wrapper">
|
|
172
211
|
<div class="instructions">
|
|
173
212
|
<svg
|
|
174
213
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -342,9 +381,7 @@ function templateString() {
|
|
|
342
381
|
<div id="error" class='color-red'>
|
|
343
382
|
</div>
|
|
344
383
|
</div>
|
|
345
|
-
|
|
346
|
-
<section className="footer">
|
|
347
|
-
<div class='flow'>
|
|
384
|
+
<div class='controls'>
|
|
348
385
|
${
|
|
349
386
|
this.supportBothCaptureModes || this.documentCaptureModes === 'camera'
|
|
350
387
|
? `
|
|
@@ -367,9 +404,18 @@ function templateString() {
|
|
|
367
404
|
: ''
|
|
368
405
|
}
|
|
369
406
|
</div>
|
|
370
|
-
${
|
|
371
|
-
|
|
407
|
+
${
|
|
408
|
+
this.hideAttribution
|
|
409
|
+
? ''
|
|
410
|
+
: `
|
|
411
|
+
<div class="content-footer">
|
|
412
|
+
<powered-by-smile-id></powered-by-smile-id>
|
|
372
413
|
</div>
|
|
414
|
+
`
|
|
415
|
+
}
|
|
416
|
+
</div>
|
|
417
|
+
</div>
|
|
418
|
+
</div>
|
|
373
419
|
${styles(this.themeColor)}
|
|
374
420
|
`;
|
|
375
421
|
}
|
|
@@ -17,7 +17,6 @@ function templateString() {
|
|
|
17
17
|
|
|
18
18
|
.section {
|
|
19
19
|
width: 100%;
|
|
20
|
-
height: 100vh;
|
|
21
20
|
justify-content: center;
|
|
22
21
|
}
|
|
23
22
|
}
|
|
@@ -125,11 +124,11 @@ function templateString() {
|
|
|
125
124
|
}
|
|
126
125
|
|
|
127
126
|
#document-capture-review-screen {
|
|
128
|
-
block-size: 45rem;
|
|
129
127
|
display: flex;
|
|
130
128
|
flex-direction: column;
|
|
131
129
|
max-block-size: 100%;
|
|
132
130
|
max-inline-size: 40ch;
|
|
131
|
+
padding: 1rem;
|
|
133
132
|
}
|
|
134
133
|
|
|
135
134
|
#document-capture-review-screen .id-image-container.landscape {
|
|
@@ -194,7 +193,7 @@ function templateString() {
|
|
|
194
193
|
text-align: center;
|
|
195
194
|
|
|
196
195
|
/* h1 */
|
|
197
|
-
font-size: 1.
|
|
196
|
+
font-size: 1.25rem;
|
|
198
197
|
font-style: normal;
|
|
199
198
|
font-weight: 700;
|
|
200
199
|
line-height: 36px; /* 150% */
|
|
@@ -23,7 +23,7 @@ button {
|
|
|
23
23
|
color: #ffffff;
|
|
24
24
|
cursor: pointer;
|
|
25
25
|
display: inline-flex;
|
|
26
|
-
font-size:
|
|
26
|
+
font-size: 1rem;
|
|
27
27
|
font-weight: 500;
|
|
28
28
|
inline-size: 100%;
|
|
29
29
|
justify-content: center;
|
|
@@ -76,8 +76,8 @@ button[data-type="icon"] {
|
|
|
76
76
|
backButton.innerHTML = `
|
|
77
77
|
<svg
|
|
78
78
|
xmlns="http://www.w3.org/2000/svg"
|
|
79
|
-
width="
|
|
80
|
-
height="
|
|
79
|
+
width="24"
|
|
80
|
+
height="24"
|
|
81
81
|
viewBox="0 0 24 24"
|
|
82
82
|
fill="none"
|
|
83
83
|
>
|
|
@@ -103,8 +103,8 @@ button[data-type="icon"] {
|
|
|
103
103
|
<svg
|
|
104
104
|
xmlns="http://www.w3.org/2000/svg"
|
|
105
105
|
viewBox="0 0 24 24"
|
|
106
|
-
width="
|
|
107
|
-
height="
|
|
106
|
+
width="24"
|
|
107
|
+
height="24"
|
|
108
108
|
fill="none"
|
|
109
109
|
>
|
|
110
110
|
<path
|
|
@@ -9,34 +9,6 @@ const COMPONENTS_VERSION = packageJson.version;
|
|
|
9
9
|
|
|
10
10
|
const smartCameraWeb = document.querySelector('smart-camera-web');
|
|
11
11
|
|
|
12
|
-
async function getPermissions(captureScreen, facingMode = 'user') {
|
|
13
|
-
try {
|
|
14
|
-
const stream = await SmartCamera.getMedia({
|
|
15
|
-
audio: false,
|
|
16
|
-
video: { facingMode },
|
|
17
|
-
});
|
|
18
|
-
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
19
|
-
const videoDevice = devices.find(
|
|
20
|
-
(device) =>
|
|
21
|
-
device.kind === 'videoinput' &&
|
|
22
|
-
stream.getVideoTracks()[0].getSettings().deviceId === device.deviceId,
|
|
23
|
-
);
|
|
24
|
-
smartCameraWeb?.dispatchEvent(
|
|
25
|
-
new CustomEvent('metadata.camera-name', {
|
|
26
|
-
detail: { cameraName: videoDevice?.label },
|
|
27
|
-
}),
|
|
28
|
-
);
|
|
29
|
-
captureScreen.removeAttribute('data-camera-error');
|
|
30
|
-
captureScreen.setAttribute('data-camera-ready', true);
|
|
31
|
-
} catch (error) {
|
|
32
|
-
captureScreen.removeAttribute('data-camera-ready');
|
|
33
|
-
captureScreen.setAttribute(
|
|
34
|
-
'data-camera-error',
|
|
35
|
-
SmartCamera.handleCameraError(error),
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
12
|
const cropImageFromDataUri = (
|
|
41
13
|
dataUri,
|
|
42
14
|
cropPercentX = 0,
|
|
@@ -113,7 +85,7 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
113
85
|
connectedCallback() {
|
|
114
86
|
this.innerHTML = `
|
|
115
87
|
${styles(this.themeColor)}
|
|
116
|
-
<div>
|
|
88
|
+
<div style="height: 100%;">
|
|
117
89
|
<selfie-capture-instructions theme-color='${this.themeColor}' ${this.showNavigation} ${this.hideAttribution} ${this.hideBack} hidden></selfie-capture-instructions>
|
|
118
90
|
<selfie-capture-wrapper theme-color='${this.themeColor}' ${this.showNavigation} ${this.allowAgentMode} ${this.allowAgentModeTests} ${this.hideAttribution} ${this.disableImageTests} key="${this._remountKey}" start-countdown="false" hidden></selfie-capture-wrapper>
|
|
119
91
|
<selfie-capture-review theme-color='${this.themeColor}' ${this.showNavigation} ${this.hideAttribution} hidden></selfie-capture-review>
|
|
@@ -130,16 +102,10 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
130
102
|
this.selfieCapture = this.querySelector('selfie-capture-wrapper');
|
|
131
103
|
this.selfieReview = this.querySelector('selfie-capture-review');
|
|
132
104
|
|
|
133
|
-
if (
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
// If the initial screen is selfie-capture, we need to get permissions
|
|
138
|
-
if (this.getAttribute('initial-screen') === 'selfie-capture') {
|
|
139
|
-
getPermissions(this.selfieCapture, this.getAgentMode()).then(() =>
|
|
140
|
-
this.setActiveScreen(this.selfieCapture),
|
|
141
|
-
);
|
|
142
|
-
} else if (this.hideInstructions) {
|
|
105
|
+
if (
|
|
106
|
+
this.getAttribute('initial-screen') === 'selfie-capture' ||
|
|
107
|
+
this.hideInstructions
|
|
108
|
+
) {
|
|
143
109
|
this.setActiveScreen(this.selfieCapture);
|
|
144
110
|
} else {
|
|
145
111
|
this.setActiveScreen(this.selfieInstruction);
|
|
@@ -154,6 +120,14 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
154
120
|
|
|
155
121
|
disconnectedCallback() {
|
|
156
122
|
SmartCamera.stopMedia();
|
|
123
|
+
|
|
124
|
+
if (this._selfieWrapperListeners) {
|
|
125
|
+
this._selfieWrapperListeners.forEach(({ event, handler }) => {
|
|
126
|
+
window.removeEventListener(event, handler);
|
|
127
|
+
});
|
|
128
|
+
this._selfieWrapperListeners = null;
|
|
129
|
+
}
|
|
130
|
+
|
|
157
131
|
if (this.activeScreen) {
|
|
158
132
|
this.activeScreen.removeAttribute('hidden');
|
|
159
133
|
}
|
|
@@ -165,22 +139,25 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
165
139
|
this.selfieInstruction.addEventListener(
|
|
166
140
|
'selfie-capture-instructions.capture',
|
|
167
141
|
async () => {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
142
|
+
this.setActiveScreen(this.selfieCapture);
|
|
143
|
+
|
|
144
|
+
const selfieCapture =
|
|
145
|
+
this.selfieCapture.querySelector('selfie-capture');
|
|
146
|
+
if (selfieCapture) {
|
|
147
|
+
smartCameraWeb?.dispatchEvent(
|
|
148
|
+
new CustomEvent('metadata.selfie-capture-start'),
|
|
149
|
+
);
|
|
150
|
+
smartCameraWeb?.dispatchEvent(
|
|
151
|
+
new CustomEvent('metadata.selfie-origin', {
|
|
152
|
+
detail: {
|
|
153
|
+
imageOrigin: {
|
|
154
|
+
environment: 'back_camera',
|
|
155
|
+
user: 'front_camera',
|
|
156
|
+
}[this.getAgentMode()],
|
|
157
|
+
},
|
|
158
|
+
}),
|
|
159
|
+
);
|
|
160
|
+
}
|
|
184
161
|
},
|
|
185
162
|
);
|
|
186
163
|
this.selfieInstruction.addEventListener(
|
|
@@ -189,7 +166,6 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
189
166
|
this.handleBackEvents();
|
|
190
167
|
},
|
|
191
168
|
);
|
|
192
|
-
// Setup selfie-wrapper event listeners
|
|
193
169
|
this.setupSelfieWrapperEventListeners();
|
|
194
170
|
|
|
195
171
|
this.selfieReview.addEventListener(
|
|
@@ -199,17 +175,12 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
199
175
|
new CustomEvent('metadata.selfie-capture-retry'),
|
|
200
176
|
);
|
|
201
177
|
this.selfieReview.removeAttribute('data-image');
|
|
178
|
+
this.selfieReview.removeAttribute('mirror-image');
|
|
202
179
|
this._data.images = [];
|
|
203
180
|
|
|
204
|
-
|
|
205
|
-
this.forceWrapperRemount();
|
|
181
|
+
await this.forceWrapperRemount();
|
|
206
182
|
|
|
207
|
-
|
|
208
|
-
this.setActiveScreen(this.selfieCapture);
|
|
209
|
-
await getPermissions(this.selfieCapture, this.getAgentMode());
|
|
210
|
-
} else {
|
|
211
|
-
this.setActiveScreen(this.selfieInstruction);
|
|
212
|
-
}
|
|
183
|
+
this.setActiveScreen(this.selfieCapture);
|
|
213
184
|
},
|
|
214
185
|
);
|
|
215
186
|
|
|
@@ -233,52 +204,66 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
233
204
|
}
|
|
234
205
|
|
|
235
206
|
// Force remount of selfie-capture-wrapper component for clean state
|
|
236
|
-
forceWrapperRemount() {
|
|
207
|
+
async forceWrapperRemount() {
|
|
208
|
+
SmartCamera.stopMedia();
|
|
209
|
+
|
|
237
210
|
this._remountKey++;
|
|
211
|
+
|
|
238
212
|
const container = this.querySelector('div');
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
213
|
+
const oldWrapper = this.selfieCapture;
|
|
214
|
+
|
|
215
|
+
if (oldWrapper && container) {
|
|
216
|
+
// recreate wrapper element
|
|
217
|
+
const newWrapper = document.createElement('selfie-capture-wrapper');
|
|
218
|
+
|
|
219
|
+
// copy attributes from old wrapper, but skip key and start-countdown
|
|
220
|
+
const attributesToCopy = Array.from(oldWrapper.attributes);
|
|
221
|
+
|
|
222
|
+
attributesToCopy.forEach((attr) => {
|
|
223
|
+
newWrapper.setAttribute(attr.name, attr.value);
|
|
224
|
+
});
|
|
225
|
+
oldWrapper.remove();
|
|
226
|
+
await new Promise((resolve) => {
|
|
227
|
+
setTimeout(resolve, 50);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
newWrapper.setAttribute('key', this._remountKey.toString());
|
|
231
|
+
newWrapper.setAttribute('start-countdown', 'false');
|
|
232
|
+
newWrapper.setAttribute('hidden', '');
|
|
233
|
+
|
|
234
|
+
const reviewElement = container.querySelector('selfie-capture-review');
|
|
235
|
+
if (reviewElement) {
|
|
236
|
+
container.insertBefore(newWrapper, reviewElement);
|
|
237
|
+
} else {
|
|
238
|
+
container.appendChild(newWrapper);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
this.selfieCapture = newWrapper;
|
|
242
|
+
|
|
243
|
+
this.setupSelfieWrapperEventListeners();
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// give time for the new component to initialize
|
|
247
|
+
return new Promise((resolve) => {
|
|
248
|
+
setTimeout(() => {
|
|
249
|
+
resolve();
|
|
250
|
+
}, 200);
|
|
251
|
+
});
|
|
270
252
|
}
|
|
271
253
|
|
|
272
254
|
// Override setActiveScreen to enable countdown when selfie-capture is active
|
|
273
255
|
setActiveScreen(screen) {
|
|
256
|
+
if (this.activeScreen === screen) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
|
|
274
260
|
this.activeScreen?.setAttribute('hidden', '');
|
|
275
261
|
screen.removeAttribute('hidden');
|
|
276
262
|
this.activeScreen = screen;
|
|
277
263
|
|
|
278
|
-
// If activating selfie-capture-wrapper, enable the countdown
|
|
264
|
+
// If activating selfie-capture-wrapper, enable the countdown
|
|
279
265
|
if (screen === this.selfieCapture) {
|
|
280
266
|
screen.setAttribute('start-countdown', 'true');
|
|
281
|
-
getPermissions(this.selfieCapture, this.getAgentMode());
|
|
282
267
|
} else if (this.selfieCapture) {
|
|
283
268
|
// Disable countdown when not on capture screen
|
|
284
269
|
this.selfieCapture.setAttribute('start-countdown', 'false');
|
|
@@ -286,11 +271,19 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
286
271
|
}
|
|
287
272
|
|
|
288
273
|
setupSelfieWrapperEventListeners() {
|
|
289
|
-
|
|
274
|
+
// Remove existing event listeners if they exist
|
|
275
|
+
if (this._selfieWrapperListeners) {
|
|
276
|
+
this._selfieWrapperListeners.forEach(({ event, handler }) => {
|
|
277
|
+
window.removeEventListener(event, handler);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Create new event handlers
|
|
282
|
+
const cancelledHandler = async () => {
|
|
290
283
|
SmartCamera.stopMedia();
|
|
291
284
|
|
|
292
285
|
// Force remount of selfie-capture-wrapper for clean state on next visit
|
|
293
|
-
this.forceWrapperRemount();
|
|
286
|
+
await this.forceWrapperRemount();
|
|
294
287
|
|
|
295
288
|
if (this.hideInstructions) {
|
|
296
289
|
this.handleBackEvents();
|
|
@@ -298,19 +291,18 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
298
291
|
}
|
|
299
292
|
|
|
300
293
|
this.setActiveScreen(this.selfieInstruction);
|
|
301
|
-
}
|
|
294
|
+
};
|
|
302
295
|
|
|
303
|
-
|
|
304
|
-
window.addEventListener('selfie-capture.close', () => {
|
|
296
|
+
const closeHandler = async () => {
|
|
305
297
|
SmartCamera.stopMedia();
|
|
306
298
|
|
|
307
299
|
// Force remount of selfie-capture-wrapper for clean state on next visit
|
|
308
|
-
this.forceWrapperRemount();
|
|
300
|
+
await this.forceWrapperRemount();
|
|
309
301
|
|
|
310
302
|
this.handleCloseEvent();
|
|
311
|
-
}
|
|
303
|
+
};
|
|
312
304
|
|
|
313
|
-
|
|
305
|
+
const publishHandler = async (event) => {
|
|
314
306
|
smartCameraWeb?.dispatchEvent(
|
|
315
307
|
new CustomEvent('metadata.selfie-capture-end'),
|
|
316
308
|
);
|
|
@@ -318,25 +310,31 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
318
310
|
'data-image',
|
|
319
311
|
await cropImageFromDataUri(event.detail.referenceImage, 20, 20),
|
|
320
312
|
);
|
|
313
|
+
const shouldMirror = event.detail.facingMode === 'user';
|
|
314
|
+
this.selfieReview.setAttribute(
|
|
315
|
+
'mirror-image',
|
|
316
|
+
shouldMirror ? 'true' : 'false',
|
|
317
|
+
);
|
|
321
318
|
this._data.images = event.detail.images;
|
|
322
319
|
SmartCamera.stopMedia();
|
|
323
320
|
this.setActiveScreen(this.selfieReview);
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// Store references to remove them later
|
|
324
|
+
this._selfieWrapperListeners = [
|
|
325
|
+
{ event: 'selfie-capture.cancelled', handler: cancelledHandler },
|
|
326
|
+
{ event: 'selfie-capture.close', handler: closeHandler },
|
|
327
|
+
{ event: 'selfie-capture.publish', handler: publishHandler },
|
|
328
|
+
];
|
|
329
|
+
|
|
330
|
+
// Add event listeners
|
|
331
|
+
this._selfieWrapperListeners.forEach(({ event, handler }) => {
|
|
332
|
+
window.addEventListener(event, handler);
|
|
324
333
|
});
|
|
325
334
|
|
|
326
335
|
// Also listen for the publish event on the parent SelfieCaptureScreens element
|
|
327
336
|
// in case smartselfie-capture dispatches it there
|
|
328
|
-
this.addEventListener('selfie-capture.publish',
|
|
329
|
-
smartCameraWeb?.dispatchEvent(
|
|
330
|
-
new CustomEvent('metadata.selfie-capture-end'),
|
|
331
|
-
);
|
|
332
|
-
this.selfieReview.setAttribute(
|
|
333
|
-
'data-image',
|
|
334
|
-
await cropImageFromDataUri(event.detail.referenceImage, 20, 20),
|
|
335
|
-
);
|
|
336
|
-
this._data.images = event.detail.images;
|
|
337
|
-
SmartCamera.stopMedia();
|
|
338
|
-
this.setActiveScreen(this.selfieReview);
|
|
339
|
-
});
|
|
337
|
+
this.addEventListener('selfie-capture.publish', publishHandler);
|
|
340
338
|
}
|
|
341
339
|
|
|
342
340
|
_publishSelectedImages() {
|
|
@@ -351,6 +351,7 @@ function templateString() {
|
|
|
351
351
|
position: relative;
|
|
352
352
|
z-index: 1;
|
|
353
353
|
width: 100%;
|
|
354
|
+
overflow: hidden;
|
|
354
355
|
}
|
|
355
356
|
|
|
356
357
|
.video-container video,
|
|
@@ -467,11 +468,12 @@ function templateString() {
|
|
|
467
468
|
|
|
468
469
|
#selfie-capture-screen,
|
|
469
470
|
#back-of-id-entry-screen {
|
|
470
|
-
|
|
471
|
+
box-sizing: border-box;
|
|
471
472
|
display: flex;
|
|
472
473
|
flex-direction: column;
|
|
473
474
|
max-block-size: 100%;
|
|
474
475
|
max-inline-size: 40ch;
|
|
476
|
+
padding: 1rem;
|
|
475
477
|
}
|
|
476
478
|
|
|
477
479
|
#selfie-capture-screen header p {
|
|
@@ -574,7 +576,8 @@ async function getPermissions(
|
|
|
574
576
|
device.kind === 'videoinput' &&
|
|
575
577
|
stream.getVideoTracks()[0].getSettings().deviceId === device.deviceId,
|
|
576
578
|
);
|
|
577
|
-
|
|
579
|
+
const smartCameraWeb = document.querySelector('smart-camera-web');
|
|
580
|
+
smartCameraWeb?.dispatchEvent(
|
|
578
581
|
new CustomEvent('metadata.camera-name', {
|
|
579
582
|
detail: { cameraName: videoDevice?.label },
|
|
580
583
|
}),
|
|
@@ -669,7 +672,7 @@ class SelfieCaptureScreen extends HTMLElement {
|
|
|
669
672
|
|
|
670
673
|
setTimeout(() => {
|
|
671
674
|
this.smileCTABox.style.opacity = 1;
|
|
672
|
-
this.smileCTA.textContent = '
|
|
675
|
+
this.smileCTA.textContent = 'WIDER SMILE';
|
|
673
676
|
this.mouth.setAttribute(
|
|
674
677
|
'd',
|
|
675
678
|
'm 213.88314,319.4551 c -1.58,0.97 -0.35309,9.33393 1.50671,9.30586 6.05679,-0.0914 16.11631,0.17227 34.57066,0.13346 18.45435,-0.0388 28.15778,-0.0418 31.09964,-0.79956 1.80122,-0.46394 2.75061,-7.48365 1.16061,-8.45365 -1.6,-1.74874 -2.96432,-0.94348 -6.77747,-1.56441 -12.83012,0.04 -36.52534,0.50197 -41.29469,0.43262 -2.51525,-0.0713 -18.41588,-0.61 -20.01588,0.35 z m 57.29363,1.36599 c -9.24417,-2.23757 -8.08363,-2.42362 -20.78363,-2.42362 -12.7,0 -17.77931,2.69528 -26.84042,5.36549 12.57883,3.28731 33.57775,-4.29887 49.70067,2.24964 z',
|
|
@@ -794,9 +797,14 @@ class SelfieCaptureScreen extends HTMLElement {
|
|
|
794
797
|
}
|
|
795
798
|
|
|
796
799
|
_publishImages() {
|
|
800
|
+
const eventDetail = {
|
|
801
|
+
...this._data,
|
|
802
|
+
facingMode: this.facingMode,
|
|
803
|
+
};
|
|
804
|
+
|
|
797
805
|
this.dispatchEvent(
|
|
798
806
|
new CustomEvent('selfie-capture.publish', {
|
|
799
|
-
detail:
|
|
807
|
+
detail: eventDetail,
|
|
800
808
|
}),
|
|
801
809
|
);
|
|
802
810
|
}
|
|
@@ -839,6 +847,11 @@ class SelfieCaptureScreen extends HTMLElement {
|
|
|
839
847
|
|
|
840
848
|
handleStream(stream) {
|
|
841
849
|
try {
|
|
850
|
+
const videoContainer = this.shadowRoot.querySelector('.video');
|
|
851
|
+
if (!videoContainer) {
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
|
|
842
855
|
const videoExists = this.shadowRoot.querySelector('video');
|
|
843
856
|
let video = null;
|
|
844
857
|
if (videoExists) {
|
|
@@ -862,9 +875,6 @@ class SelfieCaptureScreen extends HTMLElement {
|
|
|
862
875
|
};
|
|
863
876
|
|
|
864
877
|
this._video = video;
|
|
865
|
-
const videoContainer = this.shadowRoot.querySelector(
|
|
866
|
-
'.video-container > .video',
|
|
867
|
-
);
|
|
868
878
|
this._data.permissionGranted = true;
|
|
869
879
|
|
|
870
880
|
if (!videoExists) {
|
|
@@ -914,7 +924,10 @@ class SelfieCaptureScreen extends HTMLElement {
|
|
|
914
924
|
|
|
915
925
|
if (SmartCamera.stream) {
|
|
916
926
|
this.handleStream(SmartCamera.stream);
|
|
917
|
-
} else if (
|
|
927
|
+
} else if (
|
|
928
|
+
this.hasAttribute('data-camera-ready') ||
|
|
929
|
+
!this.hasAttribute('data-camera-error')
|
|
930
|
+
) {
|
|
918
931
|
getPermissions(this, { facingMode: this.facingMode });
|
|
919
932
|
}
|
|
920
933
|
|
|
@@ -1005,13 +1018,44 @@ class SelfieCaptureScreen extends HTMLElement {
|
|
|
1005
1018
|
attributeChangedCallback(name) {
|
|
1006
1019
|
switch (name) {
|
|
1007
1020
|
case 'data-camera-error':
|
|
1008
|
-
case 'data-camera-ready':
|
|
1009
1021
|
case 'hidden':
|
|
1010
1022
|
case 'title':
|
|
1011
|
-
case 'allow-agent-mode':
|
|
1012
1023
|
this.shadowRoot.innerHTML = this.render();
|
|
1013
1024
|
this.init();
|
|
1014
1025
|
break;
|
|
1026
|
+
case 'allow-agent-mode':
|
|
1027
|
+
// only re-render if the shadowRoot is empty or not initialized
|
|
1028
|
+
if (!this.shadowRoot.innerHTML.trim()) {
|
|
1029
|
+
this.shadowRoot.innerHTML = this.render();
|
|
1030
|
+
this.init();
|
|
1031
|
+
} else {
|
|
1032
|
+
// update the setupAgentMode
|
|
1033
|
+
this.setupAgentMode();
|
|
1034
|
+
}
|
|
1035
|
+
break;
|
|
1036
|
+
case 'show-navigation':
|
|
1037
|
+
// update the navigation element if it exists
|
|
1038
|
+
if (this.shadowRoot.innerHTML.trim()) {
|
|
1039
|
+
const navigation =
|
|
1040
|
+
this.shadowRoot.querySelector('smileid-navigation');
|
|
1041
|
+
if (navigation) {
|
|
1042
|
+
if (this.showNavigation) {
|
|
1043
|
+
navigation.setAttribute('show-navigation', '');
|
|
1044
|
+
} else {
|
|
1045
|
+
navigation.removeAttribute('show-navigation');
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
} else {
|
|
1049
|
+
this.shadowRoot.innerHTML = this.render();
|
|
1050
|
+
this.init();
|
|
1051
|
+
}
|
|
1052
|
+
break;
|
|
1053
|
+
case 'data-camera-ready':
|
|
1054
|
+
// don't re-render, just handle the stream
|
|
1055
|
+
if (this.hasAttribute('data-camera-ready') && SmartCamera.stream) {
|
|
1056
|
+
this.handleStream(SmartCamera.stream);
|
|
1057
|
+
}
|
|
1058
|
+
break;
|
|
1015
1059
|
default:
|
|
1016
1060
|
break;
|
|
1017
1061
|
}
|