@propbinder/mobile-design 0.2.35 → 0.2.37
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.
|
@@ -7164,6 +7164,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
7164
7164
|
* ```
|
|
7165
7165
|
*/
|
|
7166
7166
|
class DsMobileMessageComposerComponent {
|
|
7167
|
+
cdr;
|
|
7168
|
+
constructor(cdr) {
|
|
7169
|
+
this.cdr = cdr;
|
|
7170
|
+
}
|
|
7167
7171
|
/**
|
|
7168
7172
|
* Avatar initials
|
|
7169
7173
|
*/
|
|
@@ -7258,41 +7262,40 @@ class DsMobileMessageComposerComponent {
|
|
|
7258
7262
|
const users = this.mentionUsers();
|
|
7259
7263
|
if (!query)
|
|
7260
7264
|
return users;
|
|
7261
|
-
return users.filter(user => user.name.toLowerCase().includes(query));
|
|
7265
|
+
return users.filter((user) => user.name.toLowerCase().includes(query));
|
|
7262
7266
|
}, ...(ngDevMode ? [{ debugName: "filteredUsers" }] : []));
|
|
7263
7267
|
/**
|
|
7264
7268
|
* Convert filtered users to dropdown items
|
|
7265
7269
|
*/
|
|
7266
7270
|
mentionDropdownItems = computed(() => {
|
|
7267
|
-
return this.filteredUsers().map(user => ({
|
|
7271
|
+
return this.filteredUsers().map((user) => ({
|
|
7268
7272
|
id: user.name,
|
|
7269
7273
|
label: user.name,
|
|
7270
7274
|
data: {
|
|
7271
7275
|
name: user.name,
|
|
7272
7276
|
initials: user.initials,
|
|
7273
|
-
role: user.role
|
|
7274
|
-
}
|
|
7277
|
+
role: user.role,
|
|
7278
|
+
},
|
|
7275
7279
|
}));
|
|
7276
7280
|
}, ...(ngDevMode ? [{ debugName: "mentionDropdownItems" }] : []));
|
|
7277
7281
|
/**
|
|
7278
7282
|
* Attachment menu items
|
|
7283
|
+
* Static list to prevent change detection loops
|
|
7279
7284
|
*/
|
|
7280
|
-
attachmentMenuItems =
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7294
|
-
];
|
|
7295
|
-
}, ...(ngDevMode ? [{ debugName: "attachmentMenuItems" }] : []));
|
|
7285
|
+
attachmentMenuItems = [
|
|
7286
|
+
{
|
|
7287
|
+
id: 'photo',
|
|
7288
|
+
leadingIcon: 'remixImageLine',
|
|
7289
|
+
label: 'Photo',
|
|
7290
|
+
action: () => this.handleAddPhoto(),
|
|
7291
|
+
},
|
|
7292
|
+
{
|
|
7293
|
+
id: 'file',
|
|
7294
|
+
leadingIcon: 'remixFile3Line',
|
|
7295
|
+
label: 'File',
|
|
7296
|
+
action: () => this.handleAddFile(),
|
|
7297
|
+
},
|
|
7298
|
+
];
|
|
7296
7299
|
/**
|
|
7297
7300
|
* Emits when a message is sent
|
|
7298
7301
|
*/
|
|
@@ -7328,6 +7331,8 @@ class DsMobileMessageComposerComponent {
|
|
|
7328
7331
|
}
|
|
7329
7332
|
// Set up keyboard listeners
|
|
7330
7333
|
this.setupKeyboardListeners();
|
|
7334
|
+
// Explicitly trigger change detection to avoid NG0100 with ViewChild bindings
|
|
7335
|
+
this.cdr.detectChanges();
|
|
7331
7336
|
}
|
|
7332
7337
|
ngOnDestroy() {
|
|
7333
7338
|
// Clean up keyboard listeners
|
|
@@ -7339,22 +7344,22 @@ class DsMobileMessageComposerComponent {
|
|
|
7339
7344
|
setupKeyboardListeners() {
|
|
7340
7345
|
Keyboard.addListener('keyboardWillShow', (info) => {
|
|
7341
7346
|
document.documentElement.style.setProperty('--keyboard-height', `${info.keyboardHeight}px`);
|
|
7342
|
-
}).catch(
|
|
7347
|
+
}).catch(() => { });
|
|
7343
7348
|
Keyboard.addListener('keyboardWillHide', () => {
|
|
7344
7349
|
document.documentElement.style.setProperty('--keyboard-height', '0px');
|
|
7345
|
-
}).catch(
|
|
7350
|
+
}).catch(() => { });
|
|
7346
7351
|
}
|
|
7347
7352
|
/**
|
|
7348
7353
|
* Clean up keyboard event listeners
|
|
7349
7354
|
*/
|
|
7350
7355
|
cleanupKeyboardListeners() {
|
|
7351
|
-
Keyboard.removeAllListeners().catch(
|
|
7356
|
+
Keyboard.removeAllListeners().catch(() => { });
|
|
7352
7357
|
}
|
|
7353
7358
|
/**
|
|
7354
7359
|
* Show the keyboard when user interacts with input
|
|
7355
7360
|
*/
|
|
7356
7361
|
showKeyboard() {
|
|
7357
|
-
Keyboard.show().catch(
|
|
7362
|
+
Keyboard.show().catch(() => { });
|
|
7358
7363
|
}
|
|
7359
7364
|
/**
|
|
7360
7365
|
* Handle keyboard shortcuts (Shift+Enter to send)
|
|
@@ -7527,7 +7532,7 @@ class DsMobileMessageComposerComponent {
|
|
|
7527
7532
|
event.preventDefault();
|
|
7528
7533
|
event.stopPropagation();
|
|
7529
7534
|
}
|
|
7530
|
-
this.isAttachmentMenuOpen.update(open => !open);
|
|
7535
|
+
this.isAttachmentMenuOpen.update((open) => !open);
|
|
7531
7536
|
}
|
|
7532
7537
|
/**
|
|
7533
7538
|
* Close attachment menu
|
|
@@ -7573,15 +7578,13 @@ class DsMobileMessageComposerComponent {
|
|
|
7573
7578
|
type: 'image',
|
|
7574
7579
|
name: `Photo ${this.attachments().length + 1}`,
|
|
7575
7580
|
size: '',
|
|
7576
|
-
isLoading: true
|
|
7581
|
+
isLoading: true,
|
|
7577
7582
|
};
|
|
7578
|
-
this.attachments.update(attachments => [...attachments, loadingAttachment]);
|
|
7583
|
+
this.attachments.update((attachments) => [...attachments, loadingAttachment]);
|
|
7579
7584
|
// Simulate processing time (in real app, this would be actual image processing)
|
|
7580
7585
|
// TODO: Reduce to 300ms or remove in production
|
|
7581
7586
|
setTimeout(() => {
|
|
7582
|
-
this.attachments.update(attachments => attachments.map(a => a.id === attachmentId
|
|
7583
|
-
? { ...a, isLoading: false }
|
|
7584
|
-
: a));
|
|
7587
|
+
this.attachments.update((attachments) => attachments.map((a) => (a.id === attachmentId ? { ...a, isLoading: false } : a)));
|
|
7585
7588
|
}, 1500); // 1.5s for testing - shows loading overlay clearly
|
|
7586
7589
|
}
|
|
7587
7590
|
console.log('[MessageComposer] All photos added successfully');
|
|
@@ -7653,7 +7656,7 @@ class DsMobileMessageComposerComponent {
|
|
|
7653
7656
|
const k = 1024;
|
|
7654
7657
|
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
7655
7658
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
7656
|
-
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
|
|
7659
|
+
return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];
|
|
7657
7660
|
}
|
|
7658
7661
|
/**
|
|
7659
7662
|
* Handle file selection from file input
|
|
@@ -7668,7 +7671,7 @@ class DsMobileMessageComposerComponent {
|
|
|
7668
7671
|
// Process each selected file (up to 6 total)
|
|
7669
7672
|
const remainingSlots = 6 - this.attachments().length;
|
|
7670
7673
|
const filesToProcess = Array.from(files).slice(0, remainingSlots);
|
|
7671
|
-
filesToProcess.forEach(file => {
|
|
7674
|
+
filesToProcess.forEach((file) => {
|
|
7672
7675
|
const fileType = this.detectFileType(file);
|
|
7673
7676
|
const attachmentId = `file-${Date.now()}-${Math.random()}`;
|
|
7674
7677
|
// Add attachment with loading state immediately
|
|
@@ -7678,9 +7681,9 @@ class DsMobileMessageComposerComponent {
|
|
|
7678
7681
|
type: fileType,
|
|
7679
7682
|
name: file.name,
|
|
7680
7683
|
size: this.formatFileSize(file.size),
|
|
7681
|
-
isLoading: true
|
|
7684
|
+
isLoading: true,
|
|
7682
7685
|
};
|
|
7683
|
-
this.attachments.update(attachments => [...attachments, loadingAttachment]);
|
|
7686
|
+
this.attachments.update((attachments) => [...attachments, loadingAttachment]);
|
|
7684
7687
|
// Create a data URL for preview
|
|
7685
7688
|
const reader = new FileReader();
|
|
7686
7689
|
reader.onload = (e) => {
|
|
@@ -7690,9 +7693,7 @@ class DsMobileMessageComposerComponent {
|
|
|
7690
7693
|
// TODO: Remove setTimeout in production (use actual FileReader timing)
|
|
7691
7694
|
setTimeout(() => {
|
|
7692
7695
|
// Update attachment with actual data and remove loading state
|
|
7693
|
-
this.attachments.update(attachments => attachments.map(a => a.id === attachmentId
|
|
7694
|
-
? { ...a, src: result, isLoading: false }
|
|
7695
|
-
: a));
|
|
7696
|
+
this.attachments.update((attachments) => attachments.map((a) => (a.id === attachmentId ? { ...a, src: result, isLoading: false } : a)));
|
|
7696
7697
|
// Notify parent that attachments changed so it can scroll
|
|
7697
7698
|
setTimeout(() => {
|
|
7698
7699
|
this.attachmentsChanged.emit();
|
|
@@ -7711,12 +7712,12 @@ class DsMobileMessageComposerComponent {
|
|
|
7711
7712
|
* Keeps keyboard open by maintaining focus
|
|
7712
7713
|
*/
|
|
7713
7714
|
removeAttachment(attachmentId) {
|
|
7714
|
-
this.attachments.update(attachments => attachments.filter(a => a.id !== attachmentId));
|
|
7715
|
+
this.attachments.update((attachments) => attachments.filter((a) => a.id !== attachmentId));
|
|
7715
7716
|
// Immediately refocus input to prevent keyboard from closing
|
|
7716
7717
|
setTimeout(() => {
|
|
7717
7718
|
if (this.messageInputRef?.nativeElement) {
|
|
7718
7719
|
this.messageInputRef.nativeElement.focus();
|
|
7719
|
-
Keyboard.show().catch(e => console.log('Keyboard.show() not available:', e));
|
|
7720
|
+
Keyboard.show().catch((e) => console.log('Keyboard.show() not available:', e));
|
|
7720
7721
|
}
|
|
7721
7722
|
}, 0);
|
|
7722
7723
|
// Notify parent that attachments changed so it can scroll
|
|
@@ -7736,13 +7737,11 @@ class DsMobileMessageComposerComponent {
|
|
|
7736
7737
|
const isReply = !!this.replyingTo();
|
|
7737
7738
|
// Emit message sent event
|
|
7738
7739
|
this.messageSent.emit({
|
|
7739
|
-
content: isReply && this.replyingTo()
|
|
7740
|
-
? `@${this.replyingTo().authorName} ${text}`
|
|
7741
|
-
: text,
|
|
7740
|
+
content: isReply && this.replyingTo() ? `@${this.replyingTo().authorName} ${text}` : text,
|
|
7742
7741
|
isReply,
|
|
7743
7742
|
replyTo: this.replyingTo()?.authorName,
|
|
7744
7743
|
isEdit,
|
|
7745
|
-
attachments: hasAttachments ? [...this.attachments()] : undefined
|
|
7744
|
+
attachments: hasAttachments ? [...this.attachments()] : undefined,
|
|
7746
7745
|
});
|
|
7747
7746
|
// Keep keyboard open by explicitly showing it before clearing
|
|
7748
7747
|
// This prevents the keyboard from starting to close during the clear operation
|
|
@@ -7757,7 +7756,7 @@ class DsMobileMessageComposerComponent {
|
|
|
7757
7756
|
this.messageInputRef.nativeElement.focus();
|
|
7758
7757
|
}
|
|
7759
7758
|
}
|
|
7760
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileMessageComposerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7759
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileMessageComposerComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
7761
7760
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileMessageComposerComponent, isStandalone: true, selector: "ds-mobile-message-composer", inputs: { avatarInitials: { classPropertyName: "avatarInitials", publicName: "avatarInitials", isSignal: true, isRequired: false, transformFunction: null }, avatarType: { classPropertyName: "avatarType", publicName: "avatarType", isSignal: true, isRequired: false, transformFunction: null }, avatarSrc: { classPropertyName: "avatarSrc", publicName: "avatarSrc", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, sendButtonLabel: { classPropertyName: "sendButtonLabel", publicName: "sendButtonLabel", isSignal: true, isRequired: false, transformFunction: null }, attachmentButtonLabel: { classPropertyName: "attachmentButtonLabel", publicName: "attachmentButtonLabel", isSignal: true, isRequired: false, transformFunction: null }, showAttachmentButton: { classPropertyName: "showAttachmentButton", publicName: "showAttachmentButton", isSignal: true, isRequired: false, transformFunction: null }, editIndicatorText: { classPropertyName: "editIndicatorText", publicName: "editIndicatorText", isSignal: true, isRequired: false, transformFunction: null }, replyIndicatorText: { classPropertyName: "replyIndicatorText", publicName: "replyIndicatorText", isSignal: true, isRequired: false, transformFunction: null }, enableMentions: { classPropertyName: "enableMentions", publicName: "enableMentions", isSignal: true, isRequired: false, transformFunction: null }, mentionUsers: { classPropertyName: "mentionUsers", publicName: "mentionUsers", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { messageSent: "messageSent", editCancelled: "editCancelled", replyCancelled: "replyCancelled", mentionSelected: "mentionSelected", attachmentClicked: "attachmentClicked", attachmentsChanged: "attachmentsChanged" }, viewQueries: [{ propertyName: "messageInputRef", first: true, predicate: ["messageInputEl"], descendants: true }, { propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: `
|
|
7762
7761
|
<div class="message-composer">
|
|
7763
7762
|
<!-- Edit indicator (optional) -->
|
|
@@ -7772,7 +7771,7 @@ class DsMobileMessageComposerComponent {
|
|
|
7772
7771
|
</button>
|
|
7773
7772
|
</div>
|
|
7774
7773
|
}
|
|
7775
|
-
|
|
7774
|
+
|
|
7776
7775
|
<!-- Reply indicator (optional) -->
|
|
7777
7776
|
@if (replyingTo() && !editingMessage()) {
|
|
7778
7777
|
<div class="reply-indicator">
|
|
@@ -7787,21 +7786,18 @@ class DsMobileMessageComposerComponent {
|
|
|
7787
7786
|
</button>
|
|
7788
7787
|
</div>
|
|
7789
7788
|
}
|
|
7790
|
-
|
|
7789
|
+
|
|
7791
7790
|
<!-- Attachment Previews (if any) -->
|
|
7792
7791
|
@if (attachments().length > 0) {
|
|
7793
7792
|
<div class="attachment-previews-section">
|
|
7794
7793
|
<div class="attachment-previews">
|
|
7795
7794
|
@for (attachment of attachments(); track attachment.id) {
|
|
7796
|
-
<ds-mobile-attachment-preview
|
|
7797
|
-
[attachment]="attachment"
|
|
7798
|
-
(remove)="removeAttachment($event)"
|
|
7799
|
-
/>
|
|
7795
|
+
<ds-mobile-attachment-preview [attachment]="attachment" (remove)="removeAttachment($event)" />
|
|
7800
7796
|
}
|
|
7801
7797
|
</div>
|
|
7802
7798
|
</div>
|
|
7803
7799
|
}
|
|
7804
|
-
|
|
7800
|
+
|
|
7805
7801
|
<div class="composer-content">
|
|
7806
7802
|
<!-- Attachment button replacing avatar (left side) -->
|
|
7807
7803
|
@if (showAttachmentButton()) {
|
|
@@ -7812,34 +7808,30 @@ class DsMobileMessageComposerComponent {
|
|
|
7812
7808
|
icon="remixAddLine"
|
|
7813
7809
|
variant="secondary"
|
|
7814
7810
|
size="lg"
|
|
7815
|
-
(
|
|
7816
|
-
(mousedown)="toggleAttachmentMenu($event)"
|
|
7811
|
+
(clicked)="toggleAttachmentMenu($event)"
|
|
7817
7812
|
[attr.aria-label]="attachmentButtonLabel()"
|
|
7818
|
-
[attr.aria-expanded]="isAttachmentMenuOpen()"
|
|
7813
|
+
[attr.aria-expanded]="isAttachmentMenuOpen()"
|
|
7814
|
+
>
|
|
7819
7815
|
</ds-icon-button>
|
|
7820
|
-
|
|
7816
|
+
|
|
7821
7817
|
<!-- Attachment menu using dropdown -->
|
|
7822
7818
|
<ds-mobile-dropdown
|
|
7823
|
-
[items]="attachmentMenuItems
|
|
7819
|
+
[items]="attachmentMenuItems"
|
|
7824
7820
|
[isOpen]="isAttachmentMenuOpen()"
|
|
7825
7821
|
[trigger]="'attachment-trigger'"
|
|
7826
7822
|
[keepFocusOn]="messageInputRef"
|
|
7827
7823
|
position="above"
|
|
7828
7824
|
align="start"
|
|
7829
7825
|
(itemSelected)="handleAttachmentMenuSelect($event)"
|
|
7830
|
-
(closed)="closeAttachmentMenu()"
|
|
7826
|
+
(closed)="closeAttachmentMenu()"
|
|
7827
|
+
>
|
|
7831
7828
|
</ds-mobile-dropdown>
|
|
7832
7829
|
</div>
|
|
7833
7830
|
} @else {
|
|
7834
7831
|
<!-- Avatar (only shown when attachment button is hidden) -->
|
|
7835
|
-
<ds-avatar
|
|
7836
|
-
[initials]="avatarInitials()"
|
|
7837
|
-
[type]="avatarType()"
|
|
7838
|
-
[src]="avatarSrc()"
|
|
7839
|
-
size="lg"
|
|
7840
|
-
/>
|
|
7832
|
+
<ds-avatar [initials]="avatarInitials()" [type]="avatarType()" [src]="avatarSrc()" size="lg" />
|
|
7841
7833
|
}
|
|
7842
|
-
|
|
7834
|
+
|
|
7843
7835
|
<div class="composer-input-wrapper">
|
|
7844
7836
|
<textarea
|
|
7845
7837
|
#messageInputEl
|
|
@@ -7852,8 +7844,9 @@ class DsMobileMessageComposerComponent {
|
|
|
7852
7844
|
(focus)="showKeyboard()"
|
|
7853
7845
|
(click)="showKeyboard()"
|
|
7854
7846
|
rows="1"
|
|
7855
|
-
>
|
|
7856
|
-
|
|
7847
|
+
>
|
|
7848
|
+
</textarea>
|
|
7849
|
+
|
|
7857
7850
|
<!-- Mention menu using dropdown (only render if mentions are enabled) -->
|
|
7858
7851
|
@if (enableMentions()) {
|
|
7859
7852
|
<ds-mobile-dropdown
|
|
@@ -7864,12 +7857,10 @@ class DsMobileMessageComposerComponent {
|
|
|
7864
7857
|
align="start"
|
|
7865
7858
|
[maxHeight]="200"
|
|
7866
7859
|
(itemSelected)="handleMentionSelect($event)"
|
|
7867
|
-
(closed)="closeMentionMenu()"
|
|
7860
|
+
(closed)="closeMentionMenu()"
|
|
7861
|
+
>
|
|
7868
7862
|
<ng-template #itemTemplate let-item>
|
|
7869
|
-
<ds-avatar
|
|
7870
|
-
[initials]="item.data.initials"
|
|
7871
|
-
[type]="'initials'"
|
|
7872
|
-
size="sm" />
|
|
7863
|
+
<ds-avatar [initials]="item.data.initials" [type]="'initials'" size="sm" />
|
|
7873
7864
|
<div class="mention-user-info">
|
|
7874
7865
|
<span class="mention-user-name">{{ item.data.name }}</span>
|
|
7875
7866
|
<span class="mention-user-role">{{ item.data.role }}</span>
|
|
@@ -7877,7 +7868,7 @@ class DsMobileMessageComposerComponent {
|
|
|
7877
7868
|
</ng-template>
|
|
7878
7869
|
</ds-mobile-dropdown>
|
|
7879
7870
|
}
|
|
7880
|
-
|
|
7871
|
+
|
|
7881
7872
|
<!-- Send button (absolute positioned in top right, always rendered) -->
|
|
7882
7873
|
<ds-icon-button
|
|
7883
7874
|
icon="remixCheckLine"
|
|
@@ -7886,11 +7877,12 @@ class DsMobileMessageComposerComponent {
|
|
|
7886
7877
|
(clicked)="sendMessage()"
|
|
7887
7878
|
[attr.aria-label]="sendButtonLabel()"
|
|
7888
7879
|
[class.send-button-inline]="true"
|
|
7889
|
-
[class.show]="messageText().trim().length > 0 || attachments().length > 0"
|
|
7880
|
+
[class.show]="messageText().trim().length > 0 || attachments().length > 0"
|
|
7881
|
+
>
|
|
7890
7882
|
</ds-icon-button>
|
|
7891
7883
|
</div>
|
|
7892
7884
|
</div>
|
|
7893
|
-
|
|
7885
|
+
|
|
7894
7886
|
<!-- Hidden file input -->
|
|
7895
7887
|
<input
|
|
7896
7888
|
#fileInput
|
|
@@ -7902,19 +7894,11 @@ class DsMobileMessageComposerComponent {
|
|
|
7902
7894
|
(change)="handleFileSelect($event)"
|
|
7903
7895
|
/>
|
|
7904
7896
|
</div>
|
|
7905
|
-
`, isInline: true, styles: [":host{display:block}.message-composer{background:var(--color-background-neutral-primary, #ffffff);border-top:1px solid var(--border-color-default);border-bottom-left-radius:0;border-bottom-right-radius:0;padding:12px 16px;width:100%;display:flex;flex-direction:column;gap:8px}.edit-indicator{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--color-background-brand-subtle, #f0edfe);border-radius:8px;animation:slideDown .2s ease-out}.edit-indicator-content{display:flex;align-items:center;gap:8px;color:var(--color-accent, #
|
|
7897
|
+
`, isInline: true, styles: [":host{display:block}.message-composer{background:var(--color-background-neutral-primary, #ffffff);border-top:1px solid var(--border-color-default);border-bottom-left-radius:0;border-bottom-right-radius:0;padding:12px 16px;width:100%;display:flex;flex-direction:column;gap:8px}.edit-indicator{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--color-background-brand-subtle, #f0edfe);border-radius:8px;animation:slideDown .2s ease-out}.edit-indicator-content{display:flex;align-items:center;gap:8px;color:var(--color-accent, #6b5ff5);flex:1;min-width:0}.edit-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:18px;color:var(--color-accent, #6b5ff5)}.cancel-edit{background:none;border:none;padding:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--color-accent, #6b5ff5);border-radius:4px;transition:background .2s ease;flex-shrink:0}.cancel-edit:active{background:var(--color-brand-subtle, #e0dbfe)}.reply-indicator{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:8px;animation:slideDown .2s ease-out}.reply-indicator-content{display:flex;align-items:center;gap:4px;color:var(--color-text-secondary, #737373);flex:1;min-width:0}.reply-to-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);line-height:18px;color:var(--color-text-secondary, #737373);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.reply-author{color:var(--color-accent, #6b5ff5);font-weight:600}.cancel-reply{background:none;border:none;padding:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--color-text-secondary, #737373);border-radius:4px;transition:background .2s ease;flex-shrink:0}.cancel-reply:active{background:var(--color-background-neutral-secondary, #f5f5f5)}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.attachment-previews-section{padding:0 0 8px;animation:slideDown .2s ease-out}.attachment-previews{display:flex;flex-wrap:wrap;gap:8px}.composer-content{display:flex;align-items:center;gap:12px;width:100%;position:relative}.composer-leading-button{flex-shrink:0}.composer-leading-button::ng-deep button{width:40px!important;height:40px!important;min-width:40px!important;min-height:40px!important;padding:0!important;border-radius:50%!important;transition:transform .3s ease}.composer-leading-button--open::ng-deep button{transform:rotate(45deg)}.composer-input-wrapper{flex:1;display:flex;align-items:flex-start;gap:8px;background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:24px;padding:12px 16px;min-height:44px;position:relative}.mention-user-info{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.mention-user-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:20px;color:var(--color-text-primary, #1a1a1a)}.mention-user-role{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);line-height:18px;color:var(--color-text-secondary, #737373)}.composer-input{flex:1;border:none;background:transparent;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);line-height:20px;color:var(--color-text-primary, #1a1a1a);outline:none;resize:none;min-height:20px;max-height:120px;overflow-y:auto;padding:0;margin:0}.composer-input::placeholder{color:var(--color-text-tertiary, #a0a0a0);font-size:var(--font-size-sm)}.send-button-inline{position:absolute;top:6px;right:6px;z-index:10;flex-shrink:0;opacity:0;transform:translate(20px) scale(.8);pointer-events:none;transition:opacity .15s ease-in,transform .15s ease-in}.send-button-inline.show{opacity:1;transform:translate(0) scale(1);pointer-events:auto;animation:slideInFromRight var(--spring-bouncy)}.send-button-inline::ng-deep button{width:32px!important;height:32px!important;min-width:32px!important;min-height:32px!important;padding:0!important;border-radius:50%!important}@keyframes slideInFromRight{0%{opacity:0;transform:translate(20px) scale(.8)}to{opacity:1;transform:translate(0) scale(1)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsMobileAttachmentPreviewComponent, selector: "ds-mobile-attachment-preview", inputs: ["attachment"], outputs: ["remove"] }, { kind: "component", type: DsMobileDropdownComponent, selector: "ds-mobile-dropdown", inputs: ["trigger", "keepFocusOn", "items", "isOpen", "position", "align", "maxHeight", "emptyMessage", "ariaLabel"], outputs: ["itemSelected", "closed"] }] });
|
|
7906
7898
|
}
|
|
7907
7899
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileMessageComposerComponent, decorators: [{
|
|
7908
7900
|
type: Component,
|
|
7909
|
-
args: [{ selector: 'ds-mobile-message-composer', standalone: true, imports: [
|
|
7910
|
-
CommonModule,
|
|
7911
|
-
FormsModule,
|
|
7912
|
-
DsAvatarComponent,
|
|
7913
|
-
DsIconButtonComponent,
|
|
7914
|
-
DsIconComponent,
|
|
7915
|
-
DsMobileAttachmentPreviewComponent,
|
|
7916
|
-
DsMobileDropdownComponent
|
|
7917
|
-
], template: `
|
|
7901
|
+
args: [{ selector: 'ds-mobile-message-composer', standalone: true, imports: [CommonModule, FormsModule, DsAvatarComponent, DsIconButtonComponent, DsIconComponent, DsMobileAttachmentPreviewComponent, DsMobileDropdownComponent], template: `
|
|
7918
7902
|
<div class="message-composer">
|
|
7919
7903
|
<!-- Edit indicator (optional) -->
|
|
7920
7904
|
@if (editingMessage()) {
|
|
@@ -7928,7 +7912,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
7928
7912
|
</button>
|
|
7929
7913
|
</div>
|
|
7930
7914
|
}
|
|
7931
|
-
|
|
7915
|
+
|
|
7932
7916
|
<!-- Reply indicator (optional) -->
|
|
7933
7917
|
@if (replyingTo() && !editingMessage()) {
|
|
7934
7918
|
<div class="reply-indicator">
|
|
@@ -7943,21 +7927,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
7943
7927
|
</button>
|
|
7944
7928
|
</div>
|
|
7945
7929
|
}
|
|
7946
|
-
|
|
7930
|
+
|
|
7947
7931
|
<!-- Attachment Previews (if any) -->
|
|
7948
7932
|
@if (attachments().length > 0) {
|
|
7949
7933
|
<div class="attachment-previews-section">
|
|
7950
7934
|
<div class="attachment-previews">
|
|
7951
7935
|
@for (attachment of attachments(); track attachment.id) {
|
|
7952
|
-
<ds-mobile-attachment-preview
|
|
7953
|
-
[attachment]="attachment"
|
|
7954
|
-
(remove)="removeAttachment($event)"
|
|
7955
|
-
/>
|
|
7936
|
+
<ds-mobile-attachment-preview [attachment]="attachment" (remove)="removeAttachment($event)" />
|
|
7956
7937
|
}
|
|
7957
7938
|
</div>
|
|
7958
7939
|
</div>
|
|
7959
7940
|
}
|
|
7960
|
-
|
|
7941
|
+
|
|
7961
7942
|
<div class="composer-content">
|
|
7962
7943
|
<!-- Attachment button replacing avatar (left side) -->
|
|
7963
7944
|
@if (showAttachmentButton()) {
|
|
@@ -7968,34 +7949,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
7968
7949
|
icon="remixAddLine"
|
|
7969
7950
|
variant="secondary"
|
|
7970
7951
|
size="lg"
|
|
7971
|
-
(
|
|
7972
|
-
(mousedown)="toggleAttachmentMenu($event)"
|
|
7952
|
+
(clicked)="toggleAttachmentMenu($event)"
|
|
7973
7953
|
[attr.aria-label]="attachmentButtonLabel()"
|
|
7974
|
-
[attr.aria-expanded]="isAttachmentMenuOpen()"
|
|
7954
|
+
[attr.aria-expanded]="isAttachmentMenuOpen()"
|
|
7955
|
+
>
|
|
7975
7956
|
</ds-icon-button>
|
|
7976
|
-
|
|
7957
|
+
|
|
7977
7958
|
<!-- Attachment menu using dropdown -->
|
|
7978
7959
|
<ds-mobile-dropdown
|
|
7979
|
-
[items]="attachmentMenuItems
|
|
7960
|
+
[items]="attachmentMenuItems"
|
|
7980
7961
|
[isOpen]="isAttachmentMenuOpen()"
|
|
7981
7962
|
[trigger]="'attachment-trigger'"
|
|
7982
7963
|
[keepFocusOn]="messageInputRef"
|
|
7983
7964
|
position="above"
|
|
7984
7965
|
align="start"
|
|
7985
7966
|
(itemSelected)="handleAttachmentMenuSelect($event)"
|
|
7986
|
-
(closed)="closeAttachmentMenu()"
|
|
7967
|
+
(closed)="closeAttachmentMenu()"
|
|
7968
|
+
>
|
|
7987
7969
|
</ds-mobile-dropdown>
|
|
7988
7970
|
</div>
|
|
7989
7971
|
} @else {
|
|
7990
7972
|
<!-- Avatar (only shown when attachment button is hidden) -->
|
|
7991
|
-
<ds-avatar
|
|
7992
|
-
[initials]="avatarInitials()"
|
|
7993
|
-
[type]="avatarType()"
|
|
7994
|
-
[src]="avatarSrc()"
|
|
7995
|
-
size="lg"
|
|
7996
|
-
/>
|
|
7973
|
+
<ds-avatar [initials]="avatarInitials()" [type]="avatarType()" [src]="avatarSrc()" size="lg" />
|
|
7997
7974
|
}
|
|
7998
|
-
|
|
7975
|
+
|
|
7999
7976
|
<div class="composer-input-wrapper">
|
|
8000
7977
|
<textarea
|
|
8001
7978
|
#messageInputEl
|
|
@@ -8008,8 +7985,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
8008
7985
|
(focus)="showKeyboard()"
|
|
8009
7986
|
(click)="showKeyboard()"
|
|
8010
7987
|
rows="1"
|
|
8011
|
-
>
|
|
8012
|
-
|
|
7988
|
+
>
|
|
7989
|
+
</textarea>
|
|
7990
|
+
|
|
8013
7991
|
<!-- Mention menu using dropdown (only render if mentions are enabled) -->
|
|
8014
7992
|
@if (enableMentions()) {
|
|
8015
7993
|
<ds-mobile-dropdown
|
|
@@ -8020,12 +7998,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
8020
7998
|
align="start"
|
|
8021
7999
|
[maxHeight]="200"
|
|
8022
8000
|
(itemSelected)="handleMentionSelect($event)"
|
|
8023
|
-
(closed)="closeMentionMenu()"
|
|
8001
|
+
(closed)="closeMentionMenu()"
|
|
8002
|
+
>
|
|
8024
8003
|
<ng-template #itemTemplate let-item>
|
|
8025
|
-
<ds-avatar
|
|
8026
|
-
[initials]="item.data.initials"
|
|
8027
|
-
[type]="'initials'"
|
|
8028
|
-
size="sm" />
|
|
8004
|
+
<ds-avatar [initials]="item.data.initials" [type]="'initials'" size="sm" />
|
|
8029
8005
|
<div class="mention-user-info">
|
|
8030
8006
|
<span class="mention-user-name">{{ item.data.name }}</span>
|
|
8031
8007
|
<span class="mention-user-role">{{ item.data.role }}</span>
|
|
@@ -8033,7 +8009,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
8033
8009
|
</ng-template>
|
|
8034
8010
|
</ds-mobile-dropdown>
|
|
8035
8011
|
}
|
|
8036
|
-
|
|
8012
|
+
|
|
8037
8013
|
<!-- Send button (absolute positioned in top right, always rendered) -->
|
|
8038
8014
|
<ds-icon-button
|
|
8039
8015
|
icon="remixCheckLine"
|
|
@@ -8042,11 +8018,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
8042
8018
|
(clicked)="sendMessage()"
|
|
8043
8019
|
[attr.aria-label]="sendButtonLabel()"
|
|
8044
8020
|
[class.send-button-inline]="true"
|
|
8045
|
-
[class.show]="messageText().trim().length > 0 || attachments().length > 0"
|
|
8021
|
+
[class.show]="messageText().trim().length > 0 || attachments().length > 0"
|
|
8022
|
+
>
|
|
8046
8023
|
</ds-icon-button>
|
|
8047
8024
|
</div>
|
|
8048
8025
|
</div>
|
|
8049
|
-
|
|
8026
|
+
|
|
8050
8027
|
<!-- Hidden file input -->
|
|
8051
8028
|
<input
|
|
8052
8029
|
#fileInput
|
|
@@ -8058,8 +8035,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
8058
8035
|
(change)="handleFileSelect($event)"
|
|
8059
8036
|
/>
|
|
8060
8037
|
</div>
|
|
8061
|
-
`, styles: [":host{display:block}.message-composer{background:var(--color-background-neutral-primary, #ffffff);border-top:1px solid var(--border-color-default);border-bottom-left-radius:0;border-bottom-right-radius:0;padding:12px 16px;width:100%;display:flex;flex-direction:column;gap:8px}.edit-indicator{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--color-background-brand-subtle, #f0edfe);border-radius:8px;animation:slideDown .2s ease-out}.edit-indicator-content{display:flex;align-items:center;gap:8px;color:var(--color-accent, #
|
|
8062
|
-
}], propDecorators: { avatarInitials: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarInitials", required: false }] }], avatarType: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarType", required: false }] }], avatarSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarSrc", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], sendButtonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendButtonLabel", required: false }] }], attachmentButtonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachmentButtonLabel", required: false }] }], showAttachmentButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAttachmentButton", required: false }] }], editIndicatorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "editIndicatorText", required: false }] }], replyIndicatorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "replyIndicatorText", required: false }] }], enableMentions: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableMentions", required: false }] }], mentionUsers: [{ type: i0.Input, args: [{ isSignal: true, alias: "mentionUsers", required: false }] }], autoFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], messageInputRef: [{
|
|
8038
|
+
`, styles: [":host{display:block}.message-composer{background:var(--color-background-neutral-primary, #ffffff);border-top:1px solid var(--border-color-default);border-bottom-left-radius:0;border-bottom-right-radius:0;padding:12px 16px;width:100%;display:flex;flex-direction:column;gap:8px}.edit-indicator{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--color-background-brand-subtle, #f0edfe);border-radius:8px;animation:slideDown .2s ease-out}.edit-indicator-content{display:flex;align-items:center;gap:8px;color:var(--color-accent, #6b5ff5);flex:1;min-width:0}.edit-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:18px;color:var(--color-accent, #6b5ff5)}.cancel-edit{background:none;border:none;padding:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--color-accent, #6b5ff5);border-radius:4px;transition:background .2s ease;flex-shrink:0}.cancel-edit:active{background:var(--color-brand-subtle, #e0dbfe)}.reply-indicator{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:8px;animation:slideDown .2s ease-out}.reply-indicator-content{display:flex;align-items:center;gap:4px;color:var(--color-text-secondary, #737373);flex:1;min-width:0}.reply-to-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);line-height:18px;color:var(--color-text-secondary, #737373);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.reply-author{color:var(--color-accent, #6b5ff5);font-weight:600}.cancel-reply{background:none;border:none;padding:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--color-text-secondary, #737373);border-radius:4px;transition:background .2s ease;flex-shrink:0}.cancel-reply:active{background:var(--color-background-neutral-secondary, #f5f5f5)}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.attachment-previews-section{padding:0 0 8px;animation:slideDown .2s ease-out}.attachment-previews{display:flex;flex-wrap:wrap;gap:8px}.composer-content{display:flex;align-items:center;gap:12px;width:100%;position:relative}.composer-leading-button{flex-shrink:0}.composer-leading-button::ng-deep button{width:40px!important;height:40px!important;min-width:40px!important;min-height:40px!important;padding:0!important;border-radius:50%!important;transition:transform .3s ease}.composer-leading-button--open::ng-deep button{transform:rotate(45deg)}.composer-input-wrapper{flex:1;display:flex;align-items:flex-start;gap:8px;background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:24px;padding:12px 16px;min-height:44px;position:relative}.mention-user-info{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.mention-user-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:20px;color:var(--color-text-primary, #1a1a1a)}.mention-user-role{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);line-height:18px;color:var(--color-text-secondary, #737373)}.composer-input{flex:1;border:none;background:transparent;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);line-height:20px;color:var(--color-text-primary, #1a1a1a);outline:none;resize:none;min-height:20px;max-height:120px;overflow-y:auto;padding:0;margin:0}.composer-input::placeholder{color:var(--color-text-tertiary, #a0a0a0);font-size:var(--font-size-sm)}.send-button-inline{position:absolute;top:6px;right:6px;z-index:10;flex-shrink:0;opacity:0;transform:translate(20px) scale(.8);pointer-events:none;transition:opacity .15s ease-in,transform .15s ease-in}.send-button-inline.show{opacity:1;transform:translate(0) scale(1);pointer-events:auto;animation:slideInFromRight var(--spring-bouncy)}.send-button-inline::ng-deep button{width:32px!important;height:32px!important;min-width:32px!important;min-height:32px!important;padding:0!important;border-radius:50%!important}@keyframes slideInFromRight{0%{opacity:0;transform:translate(20px) scale(.8)}to{opacity:1;transform:translate(0) scale(1)}}\n"] }]
|
|
8039
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { avatarInitials: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarInitials", required: false }] }], avatarType: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarType", required: false }] }], avatarSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarSrc", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], sendButtonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendButtonLabel", required: false }] }], attachmentButtonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachmentButtonLabel", required: false }] }], showAttachmentButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAttachmentButton", required: false }] }], editIndicatorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "editIndicatorText", required: false }] }], replyIndicatorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "replyIndicatorText", required: false }] }], enableMentions: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableMentions", required: false }] }], mentionUsers: [{ type: i0.Input, args: [{ isSignal: true, alias: "mentionUsers", required: false }] }], autoFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], messageInputRef: [{
|
|
8063
8040
|
type: ViewChild,
|
|
8064
8041
|
args: ['messageInputEl']
|
|
8065
8042
|
}], fileInput: [{
|
|
@@ -15144,8 +15121,10 @@ class DsMobileChatModalComponent {
|
|
|
15144
15121
|
}, 150);
|
|
15145
15122
|
});
|
|
15146
15123
|
});
|
|
15147
|
-
//
|
|
15148
|
-
|
|
15124
|
+
// Executing the onSend callback if provided
|
|
15125
|
+
if (this.chatData.onSend) {
|
|
15126
|
+
this.chatData.onSend(event.content, event.attachments || []);
|
|
15127
|
+
}
|
|
15149
15128
|
}
|
|
15150
15129
|
/**
|
|
15151
15130
|
* Handle attachment click
|
|
@@ -15251,8 +15230,28 @@ class DsMobileChatModalComponent {
|
|
|
15251
15230
|
* Handle file attachment click
|
|
15252
15231
|
*/
|
|
15253
15232
|
handleFileAttachmentClick(fileAttachment) {
|
|
15254
|
-
|
|
15255
|
-
|
|
15233
|
+
// If a custom handler is provided, use it
|
|
15234
|
+
if (this.chatData.onFileClick) {
|
|
15235
|
+
this.chatData.onFileClick(fileAttachment);
|
|
15236
|
+
return;
|
|
15237
|
+
}
|
|
15238
|
+
// Default behavior: Try to open/download the file
|
|
15239
|
+
const url = fileAttachment.src || fileAttachment.url;
|
|
15240
|
+
if (url) {
|
|
15241
|
+
const link = document.createElement('a');
|
|
15242
|
+
link.href = url;
|
|
15243
|
+
link.target = '_blank';
|
|
15244
|
+
// If it has a name, setting download attribute suggests downloading
|
|
15245
|
+
if (fileAttachment.name) {
|
|
15246
|
+
link.download = fileAttachment.name;
|
|
15247
|
+
}
|
|
15248
|
+
document.body.appendChild(link);
|
|
15249
|
+
link.click();
|
|
15250
|
+
document.body.removeChild(link);
|
|
15251
|
+
}
|
|
15252
|
+
else {
|
|
15253
|
+
console.warn('[ChatModal] No URL or source for file attachment:', fileAttachment);
|
|
15254
|
+
}
|
|
15256
15255
|
}
|
|
15257
15256
|
/**
|
|
15258
15257
|
* Handle image attachment click - opens lightbox
|
|
@@ -15809,7 +15808,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
15809
15808
|
* ],
|
|
15810
15809
|
* currentUserId: '456',
|
|
15811
15810
|
* currentUserInitials: 'JD',
|
|
15812
|
-
*
|
|
15811
|
+
* currentUserInitials: 'JD',
|
|
15812
|
+
* autoFocus: true,
|
|
15813
|
+
* onSend: async (message, attachments) => {
|
|
15814
|
+
* console.log('Sending message:', message);
|
|
15815
|
+
* // await this.chatService.sendMessage(participant.id, message, attachments);
|
|
15816
|
+
* },
|
|
15817
|
+
* onFileClick: (file) => {
|
|
15818
|
+
* console.log('File clicked:', file);
|
|
15819
|
+
* // window.open(file.url, '_blank');
|
|
15820
|
+
* }
|
|
15813
15821
|
* });
|
|
15814
15822
|
* }
|
|
15815
15823
|
* ```
|