diff --git a/console/package-lock.json b/console/package-lock.json
index 19876cb786..e4f541e63d 100644
--- a/console/package-lock.json
+++ b/console/package-lock.json
@@ -37,6 +37,7 @@
"libphonenumber-js": "^1.10.30",
"material-design-icons-iconfont": "^6.1.1",
"moment": "^2.29.4",
+ "opentype.js": "^1.3.4",
"ngx-color": "^9.0.0",
"rxjs": "~7.8.0",
"tinycolor2": "^1.6.0",
@@ -61,6 +62,7 @@
"@types/jasminewd2": "~2.0.10",
"@types/jsonwebtoken": "^9.0.1",
"@types/node": "^18.15.11",
+ "@types/opentype.js": "^1.3.4",
"@types/qrcode": "^1.5.0",
"@types/uuid": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^5.59.11",
@@ -4458,6 +4460,12 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.9.tgz",
"integrity": "sha512-IeB32oIV4oGArLrd7znD2rkHQ6EDCM+2Sr76dJnrHwv9OHBTTM6nuDLK9bmikXzPa0ZlWMWtRGo/Uw4mrzQedA=="
},
+ "node_modules/@types/opentype.js": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@types/opentype.js/-/opentype.js-1.3.4.tgz",
+ "integrity": "sha512-6fbXi67I07ugNM+FExwJnfuui2hD7hraD6nqjr3UnqsbBpxSkrtmO6tBubPdNAjqRT9TVkquVkNS9IkgTtq6/w==",
+ "dev": true
+ },
"node_modules/@types/q": {
"version": "0.0.32",
"resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz",
@@ -12578,6 +12586,21 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/opentype.js": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz",
+ "integrity": "sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw==",
+ "dependencies": {
+ "string.prototype.codepointat": "^0.2.1",
+ "tiny-inflate": "^1.0.3"
+ },
+ "bin": {
+ "ot": "bin/ot"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ }
+ },
"node_modules/optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
@@ -15205,6 +15228,11 @@
"node": ">=8"
}
},
+ "node_modules/string.prototype.codepointat": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
+ "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg=="
+ },
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -15546,6 +15574,11 @@
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
"dev": true
},
+ "node_modules/tiny-inflate": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
+ "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="
+ },
"node_modules/tinycolor2": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz",
diff --git a/console/package.json b/console/package.json
index f1bb3aed4d..f9f1b262ad 100644
--- a/console/package.json
+++ b/console/package.json
@@ -41,6 +41,7 @@
"libphonenumber-js": "^1.10.30",
"material-design-icons-iconfont": "^6.1.1",
"moment": "^2.29.4",
+ "opentype.js": "^1.3.4",
"ngx-color": "^9.0.0",
"rxjs": "~7.8.0",
"tinycolor2": "^1.6.0",
@@ -65,6 +66,7 @@
"@types/jasminewd2": "~2.0.10",
"@types/jsonwebtoken": "^9.0.1",
"@types/node": "^18.15.11",
+ "@types/opentype.js": "^1.3.4",
"@types/qrcode": "^1.5.0",
"@types/uuid": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^5.59.11",
diff --git a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.html b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.html
index cffa8034de..6ec47521a8 100644
--- a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.html
+++ b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.html
@@ -492,7 +492,9 @@
text_fields
-
+ {{
+ fontName
+ }}
diff --git a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.scss b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.scss
index 78a2f7e8d1..c7d1371029 100644
--- a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.scss
+++ b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.scss
@@ -243,8 +243,6 @@
}
.font-preview {
- height: 70px;
- width: 70px;
display: flex;
align-items: center;
justify-content: center;
@@ -252,22 +250,17 @@
margin-bottom: 1rem;
border: 1px solid map-get($foreground, divider);
position: relative;
+ padding: 1rem 0.5rem 1rem 0.75rem;
- .icon {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translateX(-50%) translateY(-50%);
+ .font-name {
+ margin-left: 0.5rem;
+ font-size: 16px;
}
.dl-btn {
z-index: 2;
- position: absolute;
- right: 0;
- top: 0;
cursor: pointer;
visibility: hidden;
- transform: translateX(50%) translateY(-50%);
}
&:hover {
diff --git a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.ts b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.ts
index 6fb17bc86f..6e579352de 100644
--- a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.ts
+++ b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.ts
@@ -31,6 +31,7 @@ import {
} from 'src/app/services/theme.service';
import { ToastService } from 'src/app/services/toast.service';
+import * as opentype from 'opentype.js';
import { InfoSectionType } from '../../info-section/info-section.component';
import { WarnDialogComponent } from '../../warn-dialog/warn-dialog.component';
import { PolicyComponentServiceType } from '../policy-component-types.enum';
@@ -88,6 +89,8 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy {
public ColorType: any = ColorType;
public AssetType: any = AssetType;
+ public fontName = '';
+
public refreshPreview: EventEmitter = new EventEmitter();
public org!: Org.AsObject;
public InfoSectionType: any = InfoSectionType;
@@ -180,6 +183,10 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy {
if (file) {
const formData = new FormData();
formData.append('file', file);
+
+ this.getFontName(file);
+ this.previewNewFont(file);
+
switch (this.serviceType) {
case PolicyComponentServiceType.MGMT:
return this.handleFontUploadPromise(this.assetService.upload(AssetEndpoint.MGMTFONT, formData, this.org.id));
@@ -199,6 +206,7 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy {
this.getPreviewData().then((data) => {
if (data.policy) {
this.previewData = data.policy;
+ this.fontName = '';
}
});
}, 1000);
@@ -374,6 +382,11 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy {
.then((data) => {
if (data.policy) {
this.previewData = data.policy;
+ if (this.previewData?.fontUrl) {
+ this.fetchFontMetadataAndPreview(this.previewData.fontUrl);
+ } else {
+ this.fontName = 'Could not parse font name';
+ }
this.loading = false;
}
})
@@ -385,6 +398,11 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy {
.then((data) => {
if (data.policy) {
this.data = data.policy;
+ if (this.data?.fontUrl) {
+ this.fetchFontMetadataAndPreview(this.data?.fontUrl);
+ } else {
+ this.fontName = 'Could not parse font name';
+ }
this.loading = false;
}
})
@@ -678,6 +696,45 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy {
});
}
+ private fetchFontMetadataAndPreview(url: string): void {
+ fetch(url)
+ .then((res) => res.blob())
+ .then((blob) => {
+ this.getFontName(blob);
+ this.previewNewFont(blob);
+ });
+ }
+
+ private getFontName(blob: Blob): void {
+ const reader = new FileReader();
+ reader.onload = (e) => {
+ if (e.target && e.target.result) {
+ try {
+ const font = opentype.parse(e.target.result);
+ this.fontName = font.names.fullName['en'];
+ } catch (e) {
+ this.fontName = 'Could not parse font name';
+ }
+ }
+ };
+ reader.readAsArrayBuffer(blob);
+ }
+
+ private previewNewFont(blob: Blob): void {
+ const reader = new FileReader();
+
+ reader.onload = (e) => {
+ if (e.target) {
+ let customFont = new FontFace('brandingFont', `url(${e.target.result})`);
+ // typescript complains that add is not found but
+ // indeed it is https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/add
+ // @ts-ignore
+ document.fonts.add(customFont);
+ }
+ };
+ reader.readAsDataURL(blob);
+ }
+
// /**
// * defaults to false because urls are distinct anyway
// */