diff --git a/apps/nextapp/next.config.ts b/apps/nextapp/next.config.ts index e9ffa30..5e891cf 100644 --- a/apps/nextapp/next.config.ts +++ b/apps/nextapp/next.config.ts @@ -1,4 +1,4 @@ -import type { NextConfig } from "next"; +import type { NextConfig } from 'next'; const nextConfig: NextConfig = { /* config options here */ diff --git a/apps/nextapp/package.json b/apps/nextapp/package.json index 1bdab96..3e3164b 100644 --- a/apps/nextapp/package.json +++ b/apps/nextapp/package.json @@ -10,6 +10,7 @@ "dependencies": { "@next/env": "^16.1.7", "@tanstack/react-query": "^5.91.0", + "@azify/aziface-web": "1.3.0", "axios": "1.13.6", "next": "16.1.7", "react": "19.2.3", diff --git a/apps/viteapp/package.json b/apps/viteapp/package.json index 0a1bc39..6b35fb0 100644 --- a/apps/viteapp/package.json +++ b/apps/viteapp/package.json @@ -10,7 +10,7 @@ "preview": "vite preview" }, "dependencies": { - "@azify/aziface-web": "1.1.0", + "@azify/aziface-web": "1.3.0", "@tailwindcss/vite": "^4.3.3", "@tanstack/react-query": "5.91.0", "axios": "1.13.6", diff --git a/package-lock.json b/package-lock.json index cd200b0..e7256aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "apps/nextapp": { "version": "0.1.0", "dependencies": { + "@azify/aziface-web": "1.3.0", "@next/env": "^16.1.7", "@tanstack/react-query": "^5.91.0", "axios": "1.13.6", @@ -48,10 +49,18 @@ "typescript": "5" } }, + "apps/nextapp/node_modules/@azify/aziface-web": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azify/aziface-web/-/aziface-web-1.3.0.tgz", + "integrity": "sha512-QlTAhkpTJLy/K/2SEiwcelNquO+BdcLMfUvQJKgCBCxDWbRNxSM1AVZr/dOU2hebVIgJx3LSCSRz1ucLtw9haA==", + "peerDependencies": { + "react": "*" + } + }, "apps/viteapp": { "version": "0.0.0", "dependencies": { - "@azify/aziface-web": "1.1.0", + "@azify/aziface-web": "1.3.0", "@tailwindcss/vite": "^4.3.3", "@tanstack/react-query": "5.91.0", "axios": "1.13.6", @@ -82,9 +91,12 @@ } }, "apps/viteapp/node_modules/@azify/aziface-web": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@azify/aziface-web/-/aziface-web-1.1.0.tgz", - "integrity": "sha512-4WADKjxkVpChooh/hKs4pAW+5wWdZvlPfGbwPykx8PiCtUg8IoRT9mtanqkfmvvgmwhVP7bpcBYpgGKGJWIzqA==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azify/aziface-web/-/aziface-web-1.3.0.tgz", + "integrity": "sha512-QlTAhkpTJLy/K/2SEiwcelNquO+BdcLMfUvQJKgCBCxDWbRNxSM1AVZr/dOU2hebVIgJx3LSCSRz1ucLtw9haA==", + "peerDependencies": { + "react": "*" + } }, "apps/viteapp/node_modules/@eslint/config-array": { "version": "0.23.5", @@ -250,7 +262,6 @@ "integrity": "sha512-nuKKvN+oIBO0koN7Tm7dlkmnkc21mtt0QJLwAKzjLq14y6lRTdVG36MZHJ8eQHwdJMwZbQNMlPOYedMq/oVJvQ==", "dev": true, "license": "MIT", - "peer": true, "workspaces": [ "packages/*" ], @@ -486,7 +497,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -578,7 +588,6 @@ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", @@ -2248,7 +2257,6 @@ "integrity": "sha512-kIU8SLQkYWGp3pVKiYzA5OSaNF5EE03P/R8zEmmrG6XwOg5oBjXyQVVIauQ0dgau4zYhpZEhJrvIYt6oM+zZZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@octokit/auth-token": "^5.0.0", "@octokit/graphql": "^8.2.2", @@ -4286,7 +4294,6 @@ "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -4336,7 +4343,6 @@ "integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.65.0", "@typescript-eslint/types": "8.65.0", @@ -4875,7 +4881,6 @@ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5253,7 +5258,6 @@ "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/types": "^7.26.0" } @@ -5335,7 +5339,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.44", "caniuse-lite": "^1.0.30001806", @@ -5893,8 +5896,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -6515,7 +6517,6 @@ "devOptional": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -6580,7 +6581,6 @@ "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -6766,7 +6766,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -11574,7 +11573,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -12885,7 +12883,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -12895,7 +12892,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -13169,7 +13165,6 @@ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", "license": "MIT", - "peer": true, "dependencies": { "@oxc-project/types": "=0.139.0", "@rolldown/pluginutils": "^1.0.0" @@ -13355,7 +13350,6 @@ "integrity": "sha512-qqJDBhbtHsjUEMsojWKGuL5lQFCJuPtiXKEIlFKyTzDDGTAE/oyvznaP8GeOr5PvcqBJ6LQz4JCENWPLeehSpA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@semantic-release/commit-analyzer": "^12.0.0", "@semantic-release/error": "^4.0.0", @@ -14679,7 +14673,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -14948,7 +14941,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -15193,7 +15185,6 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.5.tgz", "integrity": "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==", "license": "MIT", - "peer": true, "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.5", @@ -15524,7 +15515,6 @@ "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "dev": true, "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -15573,7 +15563,7 @@ }, "packages/aziface": { "name": "@azify/aziface-web", - "version": "1.0.11", + "version": "1.3.0", "peerDependencies": { "react": "*" } diff --git a/packages/aziface/src/module/aziface.ts b/packages/aziface/src/module/aziface.ts index e75bd1c..e48e914 100644 --- a/packages/aziface/src/module/aziface.ts +++ b/packages/aziface/src/module/aziface.ts @@ -7,10 +7,7 @@ import { FaceTecSDK as FaceTecSDKType } from '../types/FaceTecSDK'; import { SessionError } from '../errors/errors'; import { SessionRequestProcessor } from '../services/request-processor'; import { applyTheme, getBackgroundColor } from '../styles/theme'; -import { - getInitializationErrorCauseByCode, - applyResponsiveStyles, -} from '../utils'; +import { getInitializationErrorCauseByCode } from '../utils'; import { Controller, DisposeCallback, @@ -43,7 +40,6 @@ export class AzifaceController implements Controller { public static baseUrl: string = ''; public static headers: InitializeHeaders = {} as InitializeHeaders; private faceTecSDKInstance: FaceTecSDKInstance | null = null; - private internalID: number | undefined = undefined; public static subscribe(listener: VoidFunction): VoidFunction { AzifaceController.listeners.add(listener); @@ -237,15 +233,22 @@ export class AzifaceController implements Controller { error: undefined, }; - window.removeEventListener('click', applyResponsiveStyles); - window.clearInterval(this.internalID); - this.withTheme(); this.onStateChange(); }; - private generateExternalDatabaseRefID = (): string => - `aziface_web_${crypto.randomUUID()}`; + private generateExternalDatabaseRefID = (): string => { + const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace( + /[xy]/g, + char => { + const random = (Math.random() * 16) | 0; + const value = char === 'x' ? random : (random & 0x3) | 0x8; + return value.toString(16); + }, + ); + + return `aziface_web_${uuid}`; + }; private onInitializationSuccess = ( newFaceTecSdkInstance: FaceTecSDKInstance, @@ -257,9 +260,6 @@ export class AzifaceController implements Controller { private onInitializationError = (): void => this.cleanup(); private onComplete = (faceTecSessionStatus: FaceTecSessionStatus): void => { - window.removeEventListener('click', applyResponsiveStyles); - window.clearInterval(this.internalID); - const isError = faceTecSessionStatus !== FaceTecSDK.FaceTecSessionStatus.SessionCompleted; @@ -298,18 +298,6 @@ export class AzifaceController implements Controller { } else { throw new SessionError(MethodError.NotInitialized); } - - window.addEventListener('click', applyResponsiveStyles); - - const windowClickEvent = new MouseEvent('click', { - bubbles: true, - cancelable: true, - view: window, - }); - - this.internalID = window.setInterval(() => { - window.dispatchEvent(windowClickEvent); - }, 250); }; } diff --git a/packages/aziface/src/styles/aziface.css b/packages/aziface/src/styles/aziface.css index 31ae617..3f9e662 100644 --- a/packages/aziface/src/styles/aziface.css +++ b/packages/aziface/src/styles/aziface.css @@ -8,24 +8,6 @@ #DOM_FT_mainInterfaceNonOverlayContainer { @media (max-width: 768px) { - border: none !important; - } -} - -#DOM_FT_readyScreenHeaderElement { - @media (max-width: 768px) { - font-size: 1rem !important; - } -} - -#DOM_FT_readyScreenSubtextElement { - @media (max-width: 768px) { - font-size: 0.75rem !important; - } -} - -#DOM_FT_yourAppLogoContainer { - @media (max-width: 768px) { - height: calc(100% - 360px) !important; + border: 2px solid white !important; } } diff --git a/packages/aziface/src/utils/styles.ts b/packages/aziface/src/utils/styles.ts index 29fa60b..e923e4a 100644 --- a/packages/aziface/src/utils/styles.ts +++ b/packages/aziface/src/utils/styles.ts @@ -1,169 +1,12 @@ import { CancelLocation } from '../types/aziface'; import type { FaceTecCancelButtonLocation } from '../types/FaceTecCustomization'; -const PREFIX = 'DOM_FT_'; -const SAFE_MARGIN = 48; const CANCEL_BUTTON_LOCATION = { Disabled: 0 as FaceTecCancelButtonLocation, TopLeft: 1 as FaceTecCancelButtonLocation, TopRight: 2 as FaceTecCancelButtonLocation, } as const; -function getElementById(id: string): HTMLElement | null { - return document.getElementById(id); -} - -function getStyle(id: string): string { - const element = getElementById(id); - return element ? element.getAttribute('style') || '' : ''; -} - -function setStyle(id: string, style: string): void { - const element = getElementById(id); - if (element) element.setAttribute('style', style); -} - -function isMobile(): boolean { - return window.innerWidth <= 768; -} - -function isRequestingPermission(): boolean { - const id = `${PREFIX}cameraPermissionsScreen`; - const currentStyle = getStyle(id); - return currentStyle.includes('display: flex;'); -} - -function adjustFrameContainer(): void { - if (!isMobile()) return; - - const id = `${PREFIX}frameContainer`; - if (!!getElementById(id)) { - const currentStyle = getStyle(id); - const newStyle = 'top: 0px !important; left: 0px !important;'; - const isRequesting = isRequestingPermission(); - const hasStyle = currentStyle.includes(newStyle); - - if (!hasStyle && !isRequesting) { - setStyle(id, `${currentStyle} ${newStyle}`); - } else if (hasStyle && isRequesting) { - const replatedStyle = currentStyle.replace( - newStyle, - 'top: -2px !important; left: -2px !important;', - ); - setStyle(id, replatedStyle); - } - } -} - -function adjustCancelButtonElementBase(id: string, style: string): void { - if (!isMobile() || !getElementById(id)) return; - - if (isRequestingPermission()) { - setStyle(id, style); - } else { - const left = window.innerWidth > 400 ? '20%' : '22%'; - const newStyle = `left: ${left} !important;`; - const currentStyle = getStyle(id); - if (!currentStyle.includes(newStyle)) { - setStyle(id, `${currentStyle} ${newStyle}`); - } - } -} - -function adjustCancelButtonElement(): void { - adjustCancelButtonElementBase( - `${PREFIX}cancelButtonElement`, - 'left: 0px !important; height: 16px; width: 16px; padding: 15px; margin: 0px; opacity: 1; display: block; transition: opacity 500ms;', - ); - adjustCancelButtonElementBase( - `${PREFIX}idScanCancelButtonElement`, - 'height: 16px; width: 16px; padding: 8px; margin: 8px; top: 0px; left: 0px; opacity: 1; display: flex; transition: opacity 2000ms;', - ); -} - -function adjustIdScanMask(): void { - if (!isMobile()) return; - - const startY = '12px'; - const mask = getElementById(`${PREFIX}idScanCaptureFrameMask`); - if (mask) { - const [, rect] = mask.children; - rect.setAttribute('style', ''); - rect.setAttribute('y', startY); - } - - const rectId = `${PREFIX}idScanCaptureFrameRect`; - const rect = getElementById(rectId); - if (rect) { - setStyle(rectId, ''); - rect.setAttribute('y', startY); - } -} - -function adjustOCRFormContainer(): void { - if (!isMobile()) return; - - const id = `${PREFIX}ocrFormContainer`; - const element = getElementById(id); - if (element) { - const [form] = element.children; - - for (const child of form.children) { - if (child.tagName === 'SECTION') { - for (const sectionChild of child.children) { - if (sectionChild.tagName === 'DIV') { - const width = window.innerWidth - SAFE_MARGIN; - const currentStyle = sectionChild.getAttribute('style') || ''; - const newStyle = `margin: 0px auto; display: block; width: ${width}px;`; - if (!currentStyle.includes(newStyle)) { - sectionChild.setAttribute('style', newStyle); - } - } - } - } - } - } -} - -function generateDPath(): string | null { - if (!isMobile()) return null; - - const VIEW_BOX = 640; - const OVAL = 158; - const displacement = OVAL.toFixed(1); - const rx = (79).toFixed(1); - const ry = (116).toFixed(1); - const width = (VIEW_BOX / 2 - OVAL / 2).toFixed(1); - - return `m${width} 180 a${rx} ${ry} 0 1 0 ${displacement} 0 a${rx} ${ry} 0 1 0 -${displacement} 0`; -} - -function removeElementById(id: string): void { - if (!isMobile()) return; - - const element = getElementById(id); - if (element) element.remove(); -} - -function setDPath(id: string): void { - const element = getElementById(id); - const d = generateDPath(); - if (element && d) element.setAttribute('d', d); -} - -export function applyResponsiveStyles(): void { - removeElementById(`${PREFIX}ovalSpinner1`); - removeElementById(`${PREFIX}ovalSpinner2`); - - adjustCancelButtonElement(); - adjustFrameContainer(); - adjustIdScanMask(); - adjustOCRFormContainer(); - - setDPath(`${PREFIX}frameGetReadyOvalPath`); - setDPath(`${PREFIX}frameOvalPath`); -} - export function resolveCancelLocation( location?: CancelLocation, ): FaceTecCancelButtonLocation {