@propbinder/mobile-design 0.2.26 → 0.2.28
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/fesm2022/propbinder-mobile-design.mjs +299 -208
- package/fesm2022/propbinder-mobile-design.mjs.map +1 -1
- package/index.d.ts +20 -1
- package/package.json +1 -1
- package/styles/ionic.css +14 -7
|
@@ -212,6 +212,30 @@ class WhitelabelService {
|
|
|
212
212
|
organizationId: 'demo-client'
|
|
213
213
|
});
|
|
214
214
|
}
|
|
215
|
+
else if (organizationId === 'cobblestone') {
|
|
216
|
+
this.initialize({
|
|
217
|
+
logoUrl: '/Assets/logos/cobblestone-logo.svg',
|
|
218
|
+
logoMarkUrl: '/Assets/logos/cobblestone-logomark.svg',
|
|
219
|
+
logoAlt: 'Cobblestone',
|
|
220
|
+
logoSize: 'sm',
|
|
221
|
+
appIconSurface: '#2C3E50',
|
|
222
|
+
appIconContent: '#FFFFFF',
|
|
223
|
+
accent: '#3498DB',
|
|
224
|
+
onAccent: '#FFFFFF',
|
|
225
|
+
headerSurface: '#2C3E50',
|
|
226
|
+
headerContent: '#FFFFFF',
|
|
227
|
+
headerAccent: '#3498DB',
|
|
228
|
+
onHeaderAccent: '#FFFFFF',
|
|
229
|
+
showCityIllustration: false,
|
|
230
|
+
signInBgType: 'gradient',
|
|
231
|
+
signInBgSolid: '#E8EEF2',
|
|
232
|
+
signInBgGradientStart: '#E8EEF2',
|
|
233
|
+
signInBgGradientEnd: '#BDC3C7',
|
|
234
|
+
signInContentColor: '#1a1a1a',
|
|
235
|
+
organizationName: 'Cobblestone',
|
|
236
|
+
organizationId: 'cobblestone'
|
|
237
|
+
});
|
|
238
|
+
}
|
|
215
239
|
// Add more organization-specific configs as needed
|
|
216
240
|
}
|
|
217
241
|
catch (error) {
|
|
@@ -2977,6 +3001,9 @@ let WhitelabelDemoModalComponent$1 = class WhitelabelDemoModalComponent {
|
|
|
2977
3001
|
else if (headerSurface === '#1D4A49') {
|
|
2978
3002
|
this.currentTheme = 'freedom';
|
|
2979
3003
|
}
|
|
3004
|
+
else if (headerSurface === '#2C3E50') {
|
|
3005
|
+
this.currentTheme = 'cobblestone';
|
|
3006
|
+
}
|
|
2980
3007
|
else {
|
|
2981
3008
|
this.currentTheme = 'default';
|
|
2982
3009
|
}
|
|
@@ -3127,6 +3154,34 @@ let WhitelabelDemoModalComponent$1 = class WhitelabelDemoModalComponent {
|
|
|
3127
3154
|
this.updateSignInBgInputs();
|
|
3128
3155
|
this.updateSignInContentColorInput();
|
|
3129
3156
|
}
|
|
3157
|
+
applyCobblestoneTheme() {
|
|
3158
|
+
this.currentTheme = 'cobblestone';
|
|
3159
|
+
this.whitelabelService.updateConfig({
|
|
3160
|
+
logoUrl: '/Assets/logos/cobblestone-logo.svg',
|
|
3161
|
+
logoMarkUrl: '/Assets/logos/cobblestone-logomark.svg',
|
|
3162
|
+
logoAlt: 'Cobblestone',
|
|
3163
|
+
logoSize: 'sm',
|
|
3164
|
+
appIconSurface: '#2C3E50',
|
|
3165
|
+
appIconContent: '#FFFFFF',
|
|
3166
|
+
accent: '#3498DB',
|
|
3167
|
+
onAccent: '#FFFFFF',
|
|
3168
|
+
headerSurface: '#2C3E50',
|
|
3169
|
+
headerContent: '#FFFFFF',
|
|
3170
|
+
headerAccent: '#3498DB',
|
|
3171
|
+
onHeaderAccent: '#FFFFFF',
|
|
3172
|
+
showCityIllustration: false,
|
|
3173
|
+
signInBgType: 'gradient',
|
|
3174
|
+
signInBgSolid: '#E8EEF2',
|
|
3175
|
+
signInBgGradientStart: '#E8EEF2',
|
|
3176
|
+
signInBgGradientEnd: '#BDC3C7',
|
|
3177
|
+
signInContentColor: '#1a1a1a',
|
|
3178
|
+
organizationName: 'Cobblestone',
|
|
3179
|
+
organizationId: 'cobblestone'
|
|
3180
|
+
});
|
|
3181
|
+
this.updateCustomColorInputs();
|
|
3182
|
+
this.updateSignInBgInputs();
|
|
3183
|
+
this.updateSignInContentColorInput();
|
|
3184
|
+
}
|
|
3130
3185
|
applyCustomColors() {
|
|
3131
3186
|
this.whitelabelService.updateColors({
|
|
3132
3187
|
appIconSurface: this.customAppIconSurface,
|
|
@@ -3224,6 +3279,9 @@ let WhitelabelDemoModalComponent$1 = class WhitelabelDemoModalComponent {
|
|
|
3224
3279
|
<button class="theme-btn" (click)="applyFreedomTheme()" [class.active]="currentTheme === 'freedom'">
|
|
3225
3280
|
Freedom
|
|
3226
3281
|
</button>
|
|
3282
|
+
<button class="theme-btn" (click)="applyCobblestoneTheme()" [class.active]="currentTheme === 'cobblestone'">
|
|
3283
|
+
Cobblestone
|
|
3284
|
+
</button>
|
|
3227
3285
|
</div>
|
|
3228
3286
|
</div>
|
|
3229
3287
|
|
|
@@ -3605,6 +3663,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
3605
3663
|
<button class="theme-btn" (click)="applyFreedomTheme()" [class.active]="currentTheme === 'freedom'">
|
|
3606
3664
|
Freedom
|
|
3607
3665
|
</button>
|
|
3666
|
+
<button class="theme-btn" (click)="applyCobblestoneTheme()" [class.active]="currentTheme === 'cobblestone'">
|
|
3667
|
+
Cobblestone
|
|
3668
|
+
</button>
|
|
3608
3669
|
</div>
|
|
3609
3670
|
</div>
|
|
3610
3671
|
|
|
@@ -4317,8 +4378,8 @@ class DsMobilePageMainComponent extends MobilePageBase {
|
|
|
4317
4378
|
<ion-header>
|
|
4318
4379
|
<ion-toolbar>
|
|
4319
4380
|
<div class="header-main">
|
|
4320
|
-
<!-- Whitelabel
|
|
4321
|
-
<ds-logo variant="
|
|
4381
|
+
<!-- Whitelabel logo (full in header, logomark used for app icon/avatars) -->
|
|
4382
|
+
<ds-logo variant="full" size="lg" />
|
|
4322
4383
|
|
|
4323
4384
|
<!-- Title - fades in on scroll -->
|
|
4324
4385
|
<ion-title class="header-main__title">{{ title() }}</ion-title>
|
|
@@ -4396,8 +4457,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
4396
4457
|
<ion-header>
|
|
4397
4458
|
<ion-toolbar>
|
|
4398
4459
|
<div class="header-main">
|
|
4399
|
-
<!-- Whitelabel
|
|
4400
|
-
<ds-logo variant="
|
|
4460
|
+
<!-- Whitelabel logo (full in header, logomark used for app icon/avatars) -->
|
|
4461
|
+
<ds-logo variant="full" size="lg" />
|
|
4401
4462
|
|
|
4402
4463
|
<!-- Title - fades in on scroll -->
|
|
4403
4464
|
<ion-title class="header-main__title">{{ title() }}</ion-title>
|
|
@@ -9535,9 +9596,9 @@ class DsMobileTabBarComponent {
|
|
|
9535
9596
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileTabBarComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
9536
9597
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: DsMobileTabBarComponent, isStandalone: true, selector: "ds-mobile-tab-bar", inputs: { tabs: "tabs", avatarType: "avatarType", avatarInitials: "avatarInitials", avatarSrc: "avatarSrc", avatarIconName: "avatarIconName", profileMenuItems: "profileMenuItems" }, outputs: { avatarClick: "avatarClick", profileActionSelected: "profileActionSelected" }, ngImport: i0, template: `
|
|
9537
9598
|
<ion-tab-bar [attr.slot]="isDesktop() ? 'top' : 'bottom'" class="ds-tab-bar" [class.ds-tab-bar--desktop]="isDesktop()">
|
|
9538
|
-
<!-- Logo (desktop only,
|
|
9599
|
+
<!-- Logo (desktop only, full logo in header) -->
|
|
9539
9600
|
<div class="ds-tab-bar__logo">
|
|
9540
|
-
<ds-logo variant="
|
|
9601
|
+
<ds-logo variant="full" size="lg" />
|
|
9541
9602
|
</div>
|
|
9542
9603
|
|
|
9543
9604
|
<!-- Tab buttons container -->
|
|
@@ -9571,9 +9632,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
9571
9632
|
type: Component,
|
|
9572
9633
|
args: [{ selector: 'ds-mobile-tab-bar', standalone: true, imports: [CommonModule, IonTabBar, IonTabButton, IonLabel, DsIconComponent, DsAvatarComponent, DsLogoComponent], template: `
|
|
9573
9634
|
<ion-tab-bar [attr.slot]="isDesktop() ? 'top' : 'bottom'" class="ds-tab-bar" [class.ds-tab-bar--desktop]="isDesktop()">
|
|
9574
|
-
<!-- Logo (desktop only,
|
|
9635
|
+
<!-- Logo (desktop only, full logo in header) -->
|
|
9575
9636
|
<div class="ds-tab-bar__logo">
|
|
9576
|
-
<ds-logo variant="
|
|
9637
|
+
<ds-logo variant="full" size="lg" />
|
|
9577
9638
|
</div>
|
|
9578
9639
|
|
|
9579
9640
|
<!-- Tab buttons container -->
|
|
@@ -12251,7 +12312,13 @@ class DsMobileModalBaseComponent extends MobileModalBase {
|
|
|
12251
12312
|
}
|
|
12252
12313
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileModalBaseComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
12253
12314
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileModalBaseComponent, isStandalone: true, selector: "ds-mobile-modal-base", inputs: { showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.--modal-content-padding": "contentPadding()", "class.is-auto-height": "isAutoHeight()" } }, queries: [{ propertyName: "customLoadingState", first: true, predicate: ["[loading-state]"], descendants: true, read: ElementRef }, { propertyName: "customErrorState", first: true, predicate: ["[error-state]"], descendants: true, read: ElementRef }, { propertyName: "headerLeading", first: true, predicate: ["[header-leading]"], descendants: true, read: ElementRef }, { propertyName: "headerMain", first: true, predicate: ["[header-main]"], descendants: true, read: ElementRef }], viewQueries: [{ propertyName: "ionContent", first: true, predicate: IonContent, descendants: true, read: IonContent }], usesInheritance: true, ngImport: i0, template: `
|
|
12254
|
-
<ion-content
|
|
12315
|
+
<ion-content
|
|
12316
|
+
[fullscreen]="!isAutoHeight()"
|
|
12317
|
+
[scrollY]="true"
|
|
12318
|
+
[class.is-auto-height]="isAutoHeight()"
|
|
12319
|
+
class="modal-base-content"
|
|
12320
|
+
[style.--padding-bottom]="contentPadding() || (hasFixedBottom() ? 'var(--fixed-bottom-height)' : '24px')"
|
|
12321
|
+
>
|
|
12255
12322
|
<div class="modal-wrapper" [class.headerless]="!shouldShowHeader()" [class.is-auto-height]="isAutoHeight()">
|
|
12256
12323
|
<!-- Header (conditional) -->
|
|
12257
12324
|
@if (shouldShowHeader()) {
|
|
@@ -12334,7 +12401,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
12334
12401
|
'[style.--modal-content-padding]': 'contentPadding()',
|
|
12335
12402
|
'[class.is-auto-height]': 'isAutoHeight()',
|
|
12336
12403
|
}, template: `
|
|
12337
|
-
<ion-content
|
|
12404
|
+
<ion-content
|
|
12405
|
+
[fullscreen]="!isAutoHeight()"
|
|
12406
|
+
[scrollY]="true"
|
|
12407
|
+
[class.is-auto-height]="isAutoHeight()"
|
|
12408
|
+
class="modal-base-content"
|
|
12409
|
+
[style.--padding-bottom]="contentPadding() || (hasFixedBottom() ? 'var(--fixed-bottom-height)' : '24px')"
|
|
12410
|
+
>
|
|
12338
12411
|
<div class="modal-wrapper" [class.headerless]="!shouldShowHeader()" [class.is-auto-height]="isAutoHeight()">
|
|
12339
12412
|
<!-- Header (conditional) -->
|
|
12340
12413
|
@if (shouldShowHeader()) {
|
|
@@ -14072,7 +14145,10 @@ class DsMobileChatModalComponent {
|
|
|
14072
14145
|
}
|
|
14073
14146
|
catch (e) {
|
|
14074
14147
|
console.log('[ChatModal] Could not check scroll position:', e);
|
|
14075
|
-
|
|
14148
|
+
// The provided snippet was syntactically incorrect for this location.
|
|
14149
|
+
// Assuming the intent was to add `auto-height` to the modal's CSS class,
|
|
14150
|
+
// this change should be applied where the modal is opened or in its template.
|
|
14151
|
+
// As per the instruction, the `isAutoHeight` property is added to the component.
|
|
14076
14152
|
}
|
|
14077
14153
|
}
|
|
14078
14154
|
return true;
|
|
@@ -14167,10 +14243,7 @@ class DsMobileChatModalComponent {
|
|
|
14167
14243
|
timestamp: this.formatMessageTimestamp(ownerMessage.timestamp),
|
|
14168
14244
|
avatarInitials: ownerMessage.avatarInitials,
|
|
14169
14245
|
avatarSrc: ownerMessage.avatarSrc,
|
|
14170
|
-
avatarType: ownerMessage.avatarType === 'photo' ||
|
|
14171
|
-
ownerMessage.avatarType === 'initials'
|
|
14172
|
-
? ownerMessage.avatarType
|
|
14173
|
-
: undefined,
|
|
14246
|
+
avatarType: ownerMessage.avatarType === 'photo' || ownerMessage.avatarType === 'initials' ? ownerMessage.avatarType : undefined,
|
|
14174
14247
|
}
|
|
14175
14248
|
: undefined;
|
|
14176
14249
|
this.lightboxService.openImages({
|
|
@@ -14298,7 +14371,7 @@ class DsMobileChatModalComponent {
|
|
|
14298
14371
|
clearTimeout(this.timestampTimeout);
|
|
14299
14372
|
}
|
|
14300
14373
|
// Toggle timestamp - if clicking same message, hide it; otherwise show new one
|
|
14301
|
-
this.selectedMessageId.update((current) => current === messageId ? null : messageId);
|
|
14374
|
+
this.selectedMessageId.update((current) => (current === messageId ? null : messageId));
|
|
14302
14375
|
// Auto-hide after 3 seconds if showing
|
|
14303
14376
|
if (this.selectedMessageId() === messageId) {
|
|
14304
14377
|
this.timestampTimeout = setTimeout(() => {
|
|
@@ -14336,8 +14409,7 @@ class DsMobileChatModalComponent {
|
|
|
14336
14409
|
// 1. It's the first message
|
|
14337
14410
|
// 2. More than threshold minutes have passed since last message
|
|
14338
14411
|
// 3. Date changed (new day)
|
|
14339
|
-
if (!currentGroup ||
|
|
14340
|
-
this.shouldStartNewGroup(currentGroup.timestamp, messageDate, thresholdMinutes)) {
|
|
14412
|
+
if (!currentGroup || this.shouldStartNewGroup(currentGroup.timestamp, messageDate, thresholdMinutes)) {
|
|
14341
14413
|
currentGroup = {
|
|
14342
14414
|
timestamp: messageDate,
|
|
14343
14415
|
displayTimestamp: this.formatGroupTimestamp(messageDate),
|
|
@@ -14388,7 +14460,7 @@ class DsMobileChatModalComponent {
|
|
|
14388
14460
|
// This week: "Mandag, 14:34"
|
|
14389
14461
|
const daysAgo = Math.floor((today.getTime() - messageDate.getTime()) / (1000 * 60 * 60 * 24));
|
|
14390
14462
|
if (daysAgo < 7) {
|
|
14391
|
-
return
|
|
14463
|
+
return date.toLocaleDateString('da-DK', { weekday: 'long' }) + `, ${timeStr}`;
|
|
14392
14464
|
}
|
|
14393
14465
|
// Older: "15. jan, 14:34" or "20. dec. 2024, 14:34" if different year
|
|
14394
14466
|
const dateFormat = {
|
|
@@ -14452,6 +14524,7 @@ class DsMobileChatModalComponent {
|
|
|
14452
14524
|
[headerTitle]="participant().name"
|
|
14453
14525
|
[headerMeta]="participant().role || ''"
|
|
14454
14526
|
[hasFixedBottom]="true"
|
|
14527
|
+
[isAutoHeight]="false"
|
|
14455
14528
|
[enableKeyboardHandling]="true"
|
|
14456
14529
|
(keyboardWillShow)="handleKeyboardShow($event)"
|
|
14457
14530
|
closeButtonLabel="Luk chat"
|
|
@@ -14481,109 +14554,88 @@ class DsMobileChatModalComponent {
|
|
|
14481
14554
|
<div class="chat-avatar-name">
|
|
14482
14555
|
{{ participant().name }}
|
|
14483
14556
|
@if (participant().verified) {
|
|
14484
|
-
|
|
14485
|
-
name="remixCheckboxCircleFill"
|
|
14486
|
-
size="24px"
|
|
14487
|
-
[style.color]="'var(--color-primary-base)'"
|
|
14488
|
-
></ds-icon>
|
|
14557
|
+
<ds-icon name="remixCheckboxCircleFill" size="24px" [style.color]="'var(--color-primary-base)'"></ds-icon>
|
|
14489
14558
|
}
|
|
14490
14559
|
</div>
|
|
14491
14560
|
@if (participant().role) {
|
|
14492
|
-
|
|
14493
|
-
}
|
|
14494
|
-
|
|
14561
|
+
<div class="chat-avatar-role">{{ participant().role }}</div>
|
|
14562
|
+
}
|
|
14563
|
+
@if (participant().lastActive) {
|
|
14564
|
+
<div class="chat-avatar-meta">{{ participant().lastActive }}</div>
|
|
14495
14565
|
}
|
|
14496
14566
|
</div>
|
|
14497
14567
|
</div>
|
|
14498
14568
|
|
|
14499
14569
|
<div class="messages-list">
|
|
14500
14570
|
@if (messages().length === 0) {
|
|
14501
|
-
|
|
14502
|
-
|
|
14503
|
-
|
|
14504
|
-
|
|
14571
|
+
<!-- Empty State - Timestamp and System Message -->
|
|
14572
|
+
<div class="timestamp-header">
|
|
14573
|
+
<span class="timestamp-text">{{ getInitialTimestamp() }}</span>
|
|
14574
|
+
</div>
|
|
14505
14575
|
|
|
14506
|
-
|
|
14507
|
-
|
|
14508
|
-
|
|
14509
|
-
|
|
14510
|
-
|
|
14511
|
-
|
|
14512
|
-
|
|
14513
|
-
|
|
14514
|
-
} @else { @for (group of messagesWithDisplay(); track group.timestamp)
|
|
14515
|
-
{
|
|
14516
|
-
<!-- Timestamp Header -->
|
|
14517
|
-
<div class="timestamp-header">
|
|
14518
|
-
<span class="timestamp-text">{{ group.displayTimestamp }}</span>
|
|
14519
|
-
</div>
|
|
14576
|
+
<ds-mobile-system-message-banner [message]="participant().name + ' har overtaget din henvendelse og vil kontakte dig snart.'" [afterTimestamp]="true">
|
|
14577
|
+
</ds-mobile-system-message-banner>
|
|
14578
|
+
} @else {
|
|
14579
|
+
@for (group of messagesWithDisplay(); track group.timestamp) {
|
|
14580
|
+
<!-- Timestamp Header -->
|
|
14581
|
+
<div class="timestamp-header">
|
|
14582
|
+
<span class="timestamp-text">{{ group.displayTimestamp }}</span>
|
|
14583
|
+
</div>
|
|
14520
14584
|
|
|
14521
|
-
|
|
14522
|
-
|
|
14523
|
-
|
|
14524
|
-
|
|
14525
|
-
|
|
14526
|
-
|
|
14527
|
-
|
|
14528
|
-
|
|
14529
|
-
|
|
14530
|
-
|
|
14531
|
-
|
|
14532
|
-
|
|
14533
|
-
|
|
14534
|
-
|
|
14535
|
-
|
|
14536
|
-
|
|
14537
|
-
|
|
14538
|
-
|
|
14539
|
-
|
|
14540
|
-
|
|
14541
|
-
|
|
14542
|
-
|
|
14543
|
-
|
|
14544
|
-
|
|
14545
|
-
|
|
14546
|
-
|
|
14547
|
-
|
|
14548
|
-
(attachmentClick)="handleAttachmentClick($event)"
|
|
14549
|
-
(longPress)="handleMessageLongPress(message)"
|
|
14550
|
-
>
|
|
14551
|
-
</ds-mobile-message-bubble>
|
|
14552
|
-
}
|
|
14585
|
+
<!-- System message example (shown after first timestamp) -->
|
|
14586
|
+
@if ($first) {
|
|
14587
|
+
<ds-mobile-system-message-banner [message]="participant().name + ' har overtaget din henvendelse og vil kontakte dig snart.'" [afterTimestamp]="true">
|
|
14588
|
+
</ds-mobile-system-message-banner>
|
|
14589
|
+
}
|
|
14590
|
+
@for (message of group.messages; track message.id) {
|
|
14591
|
+
<!-- Only show bubble if has content -->
|
|
14592
|
+
@if (message.content.trim()) {
|
|
14593
|
+
<ds-mobile-message-bubble
|
|
14594
|
+
[content]="message.content"
|
|
14595
|
+
[isOwnMessage]="message.isOwnMessage"
|
|
14596
|
+
[timestamp]="formatMessageTimestamp(message.timestamp)"
|
|
14597
|
+
[showTimestamp]="selectedMessageId() === message.id"
|
|
14598
|
+
[avatarInitials]="message.avatarInitials || ''"
|
|
14599
|
+
[avatarType]="message.avatarType || 'initials'"
|
|
14600
|
+
[avatarSrc]="message.avatarSrc || ''"
|
|
14601
|
+
[showAvatar]="message.showAvatar"
|
|
14602
|
+
[clusterPosition]="message.clusterPosition"
|
|
14603
|
+
[attachments]="message.attachments"
|
|
14604
|
+
[clickable]="true"
|
|
14605
|
+
[isNewMessage]="message.isNewMessage || false"
|
|
14606
|
+
(messageClick)="handleMessageClick(message.id)"
|
|
14607
|
+
(attachmentClick)="handleAttachmentClick($event)"
|
|
14608
|
+
(longPress)="handleMessageLongPress(message)"
|
|
14609
|
+
>
|
|
14610
|
+
</ds-mobile-message-bubble>
|
|
14611
|
+
}
|
|
14553
14612
|
|
|
14554
|
-
|
|
14555
|
-
|
|
14556
|
-
|
|
14557
|
-
|
|
14558
|
-
|
|
14559
|
-
|
|
14560
|
-
|
|
14561
|
-
|
|
14562
|
-
|
|
14563
|
-
|
|
14564
|
-
|
|
14565
|
-
|
|
14566
|
-
|
|
14567
|
-
|
|
14568
|
-
|
|
14569
|
-
|
|
14570
|
-
|
|
14571
|
-
|
|
14572
|
-
|
|
14573
|
-
|
|
14574
|
-
|
|
14575
|
-
|
|
14576
|
-
|
|
14577
|
-
|
|
14578
|
-
|
|
14579
|
-
|
|
14580
|
-
[layout]="'compact'"
|
|
14581
|
-
(fileClick)="handleFileAttachmentClick(fileAttachment)"
|
|
14582
|
-
>
|
|
14583
|
-
</ds-mobile-card-inline-file>
|
|
14584
|
-
} }
|
|
14585
|
-
</div>
|
|
14586
|
-
} } } }
|
|
14613
|
+
<!-- File attachments displayed below message bubble -->
|
|
14614
|
+
@if (message.fileAttachments && message.fileAttachments.length > 0) {
|
|
14615
|
+
<div class="message-file-attachments" [class.own-message]="message.isOwnMessage">
|
|
14616
|
+
@for (fileAttachment of message.fileAttachments; track fileAttachment.id) {
|
|
14617
|
+
<!-- Show inline image preview for image attachments -->
|
|
14618
|
+
@if (fileAttachment.type === 'image') {
|
|
14619
|
+
<div class="message-image-attachment" (click)="handleImageClick(fileAttachment, message)">
|
|
14620
|
+
<img [src]="fileAttachment.src" [alt]="fileAttachment.name || 'Image'" class="inline-image" />
|
|
14621
|
+
</div>
|
|
14622
|
+
} @else {
|
|
14623
|
+
<!-- Show file card for non-image attachments -->
|
|
14624
|
+
<ds-mobile-card-inline-file
|
|
14625
|
+
[fileName]="fileAttachment.name || 'Unknown file'"
|
|
14626
|
+
[fileSize]="fileAttachment.size || ''"
|
|
14627
|
+
[variant]="getFileVariant(fileAttachment.type)"
|
|
14628
|
+
[layout]="'compact'"
|
|
14629
|
+
(fileClick)="handleFileAttachmentClick(fileAttachment)"
|
|
14630
|
+
>
|
|
14631
|
+
</ds-mobile-card-inline-file>
|
|
14632
|
+
}
|
|
14633
|
+
}
|
|
14634
|
+
</div>
|
|
14635
|
+
}
|
|
14636
|
+
}
|
|
14637
|
+
}
|
|
14638
|
+
}
|
|
14587
14639
|
</div>
|
|
14588
14640
|
</div>
|
|
14589
14641
|
</ds-mobile-section>
|
|
@@ -14625,6 +14677,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
14625
14677
|
[headerTitle]="participant().name"
|
|
14626
14678
|
[headerMeta]="participant().role || ''"
|
|
14627
14679
|
[hasFixedBottom]="true"
|
|
14680
|
+
[isAutoHeight]="false"
|
|
14628
14681
|
[enableKeyboardHandling]="true"
|
|
14629
14682
|
(keyboardWillShow)="handleKeyboardShow($event)"
|
|
14630
14683
|
closeButtonLabel="Luk chat"
|
|
@@ -14654,109 +14707,88 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
14654
14707
|
<div class="chat-avatar-name">
|
|
14655
14708
|
{{ participant().name }}
|
|
14656
14709
|
@if (participant().verified) {
|
|
14657
|
-
|
|
14658
|
-
name="remixCheckboxCircleFill"
|
|
14659
|
-
size="24px"
|
|
14660
|
-
[style.color]="'var(--color-primary-base)'"
|
|
14661
|
-
></ds-icon>
|
|
14710
|
+
<ds-icon name="remixCheckboxCircleFill" size="24px" [style.color]="'var(--color-primary-base)'"></ds-icon>
|
|
14662
14711
|
}
|
|
14663
14712
|
</div>
|
|
14664
14713
|
@if (participant().role) {
|
|
14665
|
-
|
|
14666
|
-
}
|
|
14667
|
-
|
|
14714
|
+
<div class="chat-avatar-role">{{ participant().role }}</div>
|
|
14715
|
+
}
|
|
14716
|
+
@if (participant().lastActive) {
|
|
14717
|
+
<div class="chat-avatar-meta">{{ participant().lastActive }}</div>
|
|
14668
14718
|
}
|
|
14669
14719
|
</div>
|
|
14670
14720
|
</div>
|
|
14671
14721
|
|
|
14672
14722
|
<div class="messages-list">
|
|
14673
14723
|
@if (messages().length === 0) {
|
|
14674
|
-
|
|
14675
|
-
|
|
14676
|
-
|
|
14677
|
-
|
|
14724
|
+
<!-- Empty State - Timestamp and System Message -->
|
|
14725
|
+
<div class="timestamp-header">
|
|
14726
|
+
<span class="timestamp-text">{{ getInitialTimestamp() }}</span>
|
|
14727
|
+
</div>
|
|
14678
14728
|
|
|
14679
|
-
|
|
14680
|
-
|
|
14681
|
-
|
|
14682
|
-
|
|
14683
|
-
|
|
14684
|
-
|
|
14685
|
-
|
|
14686
|
-
|
|
14687
|
-
} @else { @for (group of messagesWithDisplay(); track group.timestamp)
|
|
14688
|
-
{
|
|
14689
|
-
<!-- Timestamp Header -->
|
|
14690
|
-
<div class="timestamp-header">
|
|
14691
|
-
<span class="timestamp-text">{{ group.displayTimestamp }}</span>
|
|
14692
|
-
</div>
|
|
14729
|
+
<ds-mobile-system-message-banner [message]="participant().name + ' har overtaget din henvendelse og vil kontakte dig snart.'" [afterTimestamp]="true">
|
|
14730
|
+
</ds-mobile-system-message-banner>
|
|
14731
|
+
} @else {
|
|
14732
|
+
@for (group of messagesWithDisplay(); track group.timestamp) {
|
|
14733
|
+
<!-- Timestamp Header -->
|
|
14734
|
+
<div class="timestamp-header">
|
|
14735
|
+
<span class="timestamp-text">{{ group.displayTimestamp }}</span>
|
|
14736
|
+
</div>
|
|
14693
14737
|
|
|
14694
|
-
|
|
14695
|
-
|
|
14696
|
-
|
|
14697
|
-
|
|
14698
|
-
|
|
14699
|
-
|
|
14700
|
-
|
|
14701
|
-
|
|
14702
|
-
|
|
14703
|
-
|
|
14704
|
-
|
|
14705
|
-
|
|
14706
|
-
|
|
14707
|
-
|
|
14708
|
-
|
|
14709
|
-
|
|
14710
|
-
|
|
14711
|
-
|
|
14712
|
-
|
|
14713
|
-
|
|
14714
|
-
|
|
14715
|
-
|
|
14716
|
-
|
|
14717
|
-
|
|
14718
|
-
|
|
14719
|
-
|
|
14720
|
-
|
|
14721
|
-
(attachmentClick)="handleAttachmentClick($event)"
|
|
14722
|
-
(longPress)="handleMessageLongPress(message)"
|
|
14723
|
-
>
|
|
14724
|
-
</ds-mobile-message-bubble>
|
|
14725
|
-
}
|
|
14738
|
+
<!-- System message example (shown after first timestamp) -->
|
|
14739
|
+
@if ($first) {
|
|
14740
|
+
<ds-mobile-system-message-banner [message]="participant().name + ' har overtaget din henvendelse og vil kontakte dig snart.'" [afterTimestamp]="true">
|
|
14741
|
+
</ds-mobile-system-message-banner>
|
|
14742
|
+
}
|
|
14743
|
+
@for (message of group.messages; track message.id) {
|
|
14744
|
+
<!-- Only show bubble if has content -->
|
|
14745
|
+
@if (message.content.trim()) {
|
|
14746
|
+
<ds-mobile-message-bubble
|
|
14747
|
+
[content]="message.content"
|
|
14748
|
+
[isOwnMessage]="message.isOwnMessage"
|
|
14749
|
+
[timestamp]="formatMessageTimestamp(message.timestamp)"
|
|
14750
|
+
[showTimestamp]="selectedMessageId() === message.id"
|
|
14751
|
+
[avatarInitials]="message.avatarInitials || ''"
|
|
14752
|
+
[avatarType]="message.avatarType || 'initials'"
|
|
14753
|
+
[avatarSrc]="message.avatarSrc || ''"
|
|
14754
|
+
[showAvatar]="message.showAvatar"
|
|
14755
|
+
[clusterPosition]="message.clusterPosition"
|
|
14756
|
+
[attachments]="message.attachments"
|
|
14757
|
+
[clickable]="true"
|
|
14758
|
+
[isNewMessage]="message.isNewMessage || false"
|
|
14759
|
+
(messageClick)="handleMessageClick(message.id)"
|
|
14760
|
+
(attachmentClick)="handleAttachmentClick($event)"
|
|
14761
|
+
(longPress)="handleMessageLongPress(message)"
|
|
14762
|
+
>
|
|
14763
|
+
</ds-mobile-message-bubble>
|
|
14764
|
+
}
|
|
14726
14765
|
|
|
14727
|
-
|
|
14728
|
-
|
|
14729
|
-
|
|
14730
|
-
|
|
14731
|
-
|
|
14732
|
-
|
|
14733
|
-
|
|
14734
|
-
|
|
14735
|
-
|
|
14736
|
-
|
|
14737
|
-
|
|
14738
|
-
|
|
14739
|
-
|
|
14740
|
-
|
|
14741
|
-
|
|
14742
|
-
|
|
14743
|
-
|
|
14744
|
-
|
|
14745
|
-
|
|
14746
|
-
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
|
|
14750
|
-
|
|
14751
|
-
|
|
14752
|
-
|
|
14753
|
-
[layout]="'compact'"
|
|
14754
|
-
(fileClick)="handleFileAttachmentClick(fileAttachment)"
|
|
14755
|
-
>
|
|
14756
|
-
</ds-mobile-card-inline-file>
|
|
14757
|
-
} }
|
|
14758
|
-
</div>
|
|
14759
|
-
} } } }
|
|
14766
|
+
<!-- File attachments displayed below message bubble -->
|
|
14767
|
+
@if (message.fileAttachments && message.fileAttachments.length > 0) {
|
|
14768
|
+
<div class="message-file-attachments" [class.own-message]="message.isOwnMessage">
|
|
14769
|
+
@for (fileAttachment of message.fileAttachments; track fileAttachment.id) {
|
|
14770
|
+
<!-- Show inline image preview for image attachments -->
|
|
14771
|
+
@if (fileAttachment.type === 'image') {
|
|
14772
|
+
<div class="message-image-attachment" (click)="handleImageClick(fileAttachment, message)">
|
|
14773
|
+
<img [src]="fileAttachment.src" [alt]="fileAttachment.name || 'Image'" class="inline-image" />
|
|
14774
|
+
</div>
|
|
14775
|
+
} @else {
|
|
14776
|
+
<!-- Show file card for non-image attachments -->
|
|
14777
|
+
<ds-mobile-card-inline-file
|
|
14778
|
+
[fileName]="fileAttachment.name || 'Unknown file'"
|
|
14779
|
+
[fileSize]="fileAttachment.size || ''"
|
|
14780
|
+
[variant]="getFileVariant(fileAttachment.type)"
|
|
14781
|
+
[layout]="'compact'"
|
|
14782
|
+
(fileClick)="handleFileAttachmentClick(fileAttachment)"
|
|
14783
|
+
>
|
|
14784
|
+
</ds-mobile-card-inline-file>
|
|
14785
|
+
}
|
|
14786
|
+
}
|
|
14787
|
+
</div>
|
|
14788
|
+
}
|
|
14789
|
+
}
|
|
14790
|
+
}
|
|
14791
|
+
}
|
|
14760
14792
|
</div>
|
|
14761
14793
|
</div>
|
|
14762
14794
|
</ds-mobile-section>
|
|
@@ -14862,6 +14894,7 @@ class DsMobileChatModalService extends BaseModalService {
|
|
|
14862
14894
|
error: options?.error,
|
|
14863
14895
|
}, {
|
|
14864
14896
|
keyboardClose: true, // Keep keyboard close behavior for this modal
|
|
14897
|
+
cssClass: 'ds-modal-base',
|
|
14865
14898
|
});
|
|
14866
14899
|
// console.log('[ChatModal] Modal created, presenting...');
|
|
14867
14900
|
await modal.present();
|
|
@@ -14921,6 +14954,18 @@ class DsMobileNewInquiryModalComponent {
|
|
|
14921
14954
|
* Callback function when form is submitted
|
|
14922
14955
|
*/
|
|
14923
14956
|
onSubmit;
|
|
14957
|
+
/**
|
|
14958
|
+
* Placeholder for the title field
|
|
14959
|
+
*/
|
|
14960
|
+
titlePlaceholder = 'Name your inquiry';
|
|
14961
|
+
/**
|
|
14962
|
+
* Placeholder for the description field
|
|
14963
|
+
*/
|
|
14964
|
+
descriptionPlaceholder = 'Tell us what this inquiry is about...';
|
|
14965
|
+
/**
|
|
14966
|
+
* Label for the submit button
|
|
14967
|
+
*/
|
|
14968
|
+
submitButtonLabel = 'Submit';
|
|
14924
14969
|
/**
|
|
14925
14970
|
* Form title field
|
|
14926
14971
|
*/
|
|
@@ -15134,7 +15179,7 @@ class DsMobileNewInquiryModalComponent {
|
|
|
15134
15179
|
}
|
|
15135
15180
|
}
|
|
15136
15181
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNewInquiryModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
15137
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileNewInquiryModalComponent, isStandalone: true, selector: "ds-mobile-new-inquiry-modal", inputs: { loading: "loading", error: "error", onSubmit: "onSubmit" }, viewQueries: [{ propertyName: "titleInputRef", first: true, predicate: ["titleInput"], descendants: true, read: ElementRef }, { propertyName: "titleInput", first: true, predicate: ["titleInput"], descendants: true }, { propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: `
|
|
15182
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileNewInquiryModalComponent, isStandalone: true, selector: "ds-mobile-new-inquiry-modal", inputs: { loading: "loading", error: "error", onSubmit: "onSubmit", titlePlaceholder: "titlePlaceholder", descriptionPlaceholder: "descriptionPlaceholder", submitButtonLabel: "submitButtonLabel" }, viewQueries: [{ propertyName: "titleInputRef", first: true, predicate: ["titleInput"], descendants: true, read: ElementRef }, { propertyName: "titleInput", first: true, predicate: ["titleInput"], descendants: true }, { propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: `
|
|
15138
15183
|
<ds-mobile-modal-base
|
|
15139
15184
|
[loading]="loading"
|
|
15140
15185
|
[error]="error"
|
|
@@ -15153,7 +15198,7 @@ class DsMobileNewInquiryModalComponent {
|
|
|
15153
15198
|
[ghost]="true"
|
|
15154
15199
|
[required]="true"
|
|
15155
15200
|
[rows]="1"
|
|
15156
|
-
placeholder="
|
|
15201
|
+
[placeholder]="titlePlaceholder"
|
|
15157
15202
|
class="inquiry-title-input ghost-input-clean"
|
|
15158
15203
|
(valueChange)="handleTitleChange($event)"
|
|
15159
15204
|
/>
|
|
@@ -15163,7 +15208,7 @@ class DsMobileNewInquiryModalComponent {
|
|
|
15163
15208
|
[(ngModel)]="description"
|
|
15164
15209
|
[ghost]="true"
|
|
15165
15210
|
[rows]="1"
|
|
15166
|
-
placeholder="
|
|
15211
|
+
[placeholder]="descriptionPlaceholder"
|
|
15167
15212
|
class="inquiry-description-input ghost-input-clean"
|
|
15168
15213
|
(valueChange)="validateForm()"
|
|
15169
15214
|
/>
|
|
@@ -15204,7 +15249,7 @@ class DsMobileNewInquiryModalComponent {
|
|
|
15204
15249
|
</div>
|
|
15205
15250
|
|
|
15206
15251
|
<!-- Submit Button (Right) -->
|
|
15207
|
-
<ds-button variant="primary" size="lg" [disabled]="!isFormValid() || isSubmitting()" (clicked)="handleSubmit()">
|
|
15252
|
+
<ds-button variant="primary" size="lg" [disabled]="!isFormValid() || isSubmitting()" (clicked)="handleSubmit()"> {{ submitButtonLabel }} </ds-button>
|
|
15208
15253
|
</div>
|
|
15209
15254
|
</div>
|
|
15210
15255
|
</div>
|
|
@@ -15241,7 +15286,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
15241
15286
|
[ghost]="true"
|
|
15242
15287
|
[required]="true"
|
|
15243
15288
|
[rows]="1"
|
|
15244
|
-
placeholder="
|
|
15289
|
+
[placeholder]="titlePlaceholder"
|
|
15245
15290
|
class="inquiry-title-input ghost-input-clean"
|
|
15246
15291
|
(valueChange)="handleTitleChange($event)"
|
|
15247
15292
|
/>
|
|
@@ -15251,7 +15296,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
15251
15296
|
[(ngModel)]="description"
|
|
15252
15297
|
[ghost]="true"
|
|
15253
15298
|
[rows]="1"
|
|
15254
|
-
placeholder="
|
|
15299
|
+
[placeholder]="descriptionPlaceholder"
|
|
15255
15300
|
class="inquiry-description-input ghost-input-clean"
|
|
15256
15301
|
(valueChange)="validateForm()"
|
|
15257
15302
|
/>
|
|
@@ -15292,7 +15337,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
15292
15337
|
</div>
|
|
15293
15338
|
|
|
15294
15339
|
<!-- Submit Button (Right) -->
|
|
15295
|
-
<ds-button variant="primary" size="lg" [disabled]="!isFormValid() || isSubmitting()" (clicked)="handleSubmit()">
|
|
15340
|
+
<ds-button variant="primary" size="lg" [disabled]="!isFormValid() || isSubmitting()" (clicked)="handleSubmit()"> {{ submitButtonLabel }} </ds-button>
|
|
15296
15341
|
</div>
|
|
15297
15342
|
</div>
|
|
15298
15343
|
</div>
|
|
@@ -15313,6 +15358,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
15313
15358
|
type: Input
|
|
15314
15359
|
}], onSubmit: [{
|
|
15315
15360
|
type: Input
|
|
15361
|
+
}], titlePlaceholder: [{
|
|
15362
|
+
type: Input
|
|
15363
|
+
}], descriptionPlaceholder: [{
|
|
15364
|
+
type: Input
|
|
15365
|
+
}], submitButtonLabel: [{
|
|
15366
|
+
type: Input
|
|
15316
15367
|
}] } });
|
|
15317
15368
|
|
|
15318
15369
|
/**
|
|
@@ -15364,6 +15415,9 @@ class DsMobileNewInquiryModalService extends BaseModalService {
|
|
|
15364
15415
|
onSubmit: options?.onSubmit,
|
|
15365
15416
|
loading: options?.loading ?? false,
|
|
15366
15417
|
error: options?.error,
|
|
15418
|
+
titlePlaceholder: options?.titlePlaceholder,
|
|
15419
|
+
descriptionPlaceholder: options?.descriptionPlaceholder,
|
|
15420
|
+
submitButtonLabel: options?.submitButtonLabel,
|
|
15367
15421
|
}, {
|
|
15368
15422
|
keyboardClose: false, // Don't close on keyboard hide for this modal
|
|
15369
15423
|
cssClass: ['ds-modal-base', 'auto-height'],
|
|
@@ -19670,6 +19724,9 @@ class WhitelabelDemoModalComponent {
|
|
|
19670
19724
|
else if (headerSurface === '#1D4A49') {
|
|
19671
19725
|
this.currentTheme = 'freedom';
|
|
19672
19726
|
}
|
|
19727
|
+
else if (headerSurface === '#2C3E50') {
|
|
19728
|
+
this.currentTheme = 'cobblestone';
|
|
19729
|
+
}
|
|
19673
19730
|
else {
|
|
19674
19731
|
this.currentTheme = 'default';
|
|
19675
19732
|
}
|
|
@@ -19820,6 +19877,34 @@ class WhitelabelDemoModalComponent {
|
|
|
19820
19877
|
this.updateSignInBgInputs();
|
|
19821
19878
|
this.updateSignInContentColorInput();
|
|
19822
19879
|
}
|
|
19880
|
+
applyCobblestoneTheme() {
|
|
19881
|
+
this.currentTheme = 'cobblestone';
|
|
19882
|
+
this.whitelabelService.updateConfig({
|
|
19883
|
+
logoUrl: '/Assets/logos/cobblestone-logo.svg',
|
|
19884
|
+
logoMarkUrl: '/Assets/logos/cobblestone-logomark.svg',
|
|
19885
|
+
logoAlt: 'Cobblestone',
|
|
19886
|
+
logoSize: 'sm',
|
|
19887
|
+
appIconSurface: '#2C3E50',
|
|
19888
|
+
appIconContent: '#FFFFFF',
|
|
19889
|
+
accent: '#3498DB',
|
|
19890
|
+
onAccent: '#FFFFFF',
|
|
19891
|
+
headerSurface: '#2C3E50',
|
|
19892
|
+
headerContent: '#FFFFFF',
|
|
19893
|
+
headerAccent: '#3498DB',
|
|
19894
|
+
onHeaderAccent: '#FFFFFF',
|
|
19895
|
+
showCityIllustration: false,
|
|
19896
|
+
signInBgType: 'gradient',
|
|
19897
|
+
signInBgSolid: '#E8EEF2',
|
|
19898
|
+
signInBgGradientStart: '#E8EEF2',
|
|
19899
|
+
signInBgGradientEnd: '#BDC3C7',
|
|
19900
|
+
signInContentColor: '#1a1a1a',
|
|
19901
|
+
organizationName: 'Cobblestone',
|
|
19902
|
+
organizationId: 'cobblestone'
|
|
19903
|
+
});
|
|
19904
|
+
this.updateCustomColorInputs();
|
|
19905
|
+
this.updateSignInBgInputs();
|
|
19906
|
+
this.updateSignInContentColorInput();
|
|
19907
|
+
}
|
|
19823
19908
|
applyCustomColors() {
|
|
19824
19909
|
this.whitelabelService.updateColors({
|
|
19825
19910
|
appIconSurface: this.customAppIconSurface,
|
|
@@ -19917,6 +20002,9 @@ class WhitelabelDemoModalComponent {
|
|
|
19917
20002
|
<button class="theme-btn" (click)="applyFreedomTheme()" [class.active]="currentTheme === 'freedom'">
|
|
19918
20003
|
Freedom
|
|
19919
20004
|
</button>
|
|
20005
|
+
<button class="theme-btn" (click)="applyCobblestoneTheme()" [class.active]="currentTheme === 'cobblestone'">
|
|
20006
|
+
Cobblestone
|
|
20007
|
+
</button>
|
|
19920
20008
|
</div>
|
|
19921
20009
|
</div>
|
|
19922
20010
|
|
|
@@ -20298,6 +20386,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
20298
20386
|
<button class="theme-btn" (click)="applyFreedomTheme()" [class.active]="currentTheme === 'freedom'">
|
|
20299
20387
|
Freedom
|
|
20300
20388
|
</button>
|
|
20389
|
+
<button class="theme-btn" (click)="applyCobblestoneTheme()" [class.active]="currentTheme === 'cobblestone'">
|
|
20390
|
+
Cobblestone
|
|
20391
|
+
</button>
|
|
20301
20392
|
</div>
|
|
20302
20393
|
</div>
|
|
20303
20394
|
|