Skip to content

Commit 599d283

Browse files
committed
Merge branch 'dmdimitrov/chat-ai-component' of https://github.com/IgniteUI/igniteui-webcomponents into dmdimitrov/chat-ai-component
2 parents 1be97ff + cb8cef1 commit 599d283

File tree

14 files changed

+91
-60
lines changed

14 files changed

+91
-60
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
"lint-staged": "^16.1.4",
8585
"lit-analyzer": "^2.0.3",
8686
"madge": "^8.0.0",
87+
"marked": "^12.0.0",
8788
"node-watch": "^0.7.4",
8889
"playwright": "^1.54.2",
8990
"postcss": "^8.5.6",
686 Bytes
Loading
787 Bytes
Loading
839 Bytes
Loading

src/components/chat/chat.ts

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -331,38 +331,36 @@ export default class IgcChatComponent extends EventEmitterMixin<
331331

332332
private renderSuggestions() {
333333
const hasContent = this._slots.hasAssignedElements('suggestions-header');
334-
return html` <igc-list
335-
part="suggestions-container"
336-
role="list"
337-
aria-label="Suggestions"
338-
>
339-
<igc-list-header part="suggestions-header">
340-
<span ?hidden=${hasContent}
341-
>${this.resourceStrings.suggestionsHeader}</span
342-
>
343-
<slot name="suggestions-header"></slot>
344-
</igc-list-header>
345-
<slot name="suggestions" part="suggestions">
346-
${this._chatState.options?.suggestions?.map(
347-
(suggestion) => html`
348-
<slot name="suggestion" part="suggestion" role="listitem">
349-
<igc-list-item
350-
@click=${() =>
351-
this._chatState?.handleSuggestionClick(suggestion)}
352-
>
353-
<igc-icon
354-
slot="start"
355-
name="star-icon"
356-
collection="material"
357-
></igc-icon>
358-
<span>${suggestion}</span>
359-
</igc-list-item>
360-
</slot>
361-
`
362-
)}
363-
</slot>
364-
<slot name="suggestions-actions" part="suggestions-actions"></slot>
365-
</igc-list>`;
334+
return html`<div part="suggestions-container">
335+
<igc-list role="list" aria-label="Suggestions">
336+
<igc-list-header part="suggestions-header">
337+
<span ?hidden=${hasContent}>
338+
${this.resourceStrings.suggestionsHeader}
339+
</span>
340+
<slot name="suggestions-header"></slot>
341+
</igc-list-header>
342+
<slot name="suggestions" part="suggestions">
343+
${this._chatState.options?.suggestions?.map(
344+
(suggestion) => html`
345+
<slot name="suggestion" part="suggestion" role="listitem">
346+
<igc-list-item
347+
@click=${() =>
348+
this._chatState?.handleSuggestionClick(suggestion)}
349+
>
350+
<igc-icon
351+
slot="start"
352+
name="star-icon"
353+
collection="material"
354+
></igc-icon>
355+
<span slot="title">${suggestion}</span>
356+
</igc-list-item>
357+
</slot>
358+
`
359+
)}
360+
</slot>
361+
<slot name="suggestions-actions" part="suggestions-actions"></slot>
362+
</igc-list>
363+
</div>`;
366364
}
367365

368366
protected override firstUpdated() {

src/components/chat/message-attachments.ts

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import { registerComponent } from '../common/definitions/register.js';
77
import IgcExpansionPanelComponent from '../expansion-panel/expansion-panel.js';
88
import IgcIconComponent from '../icon/icon.js';
99
import { registerIconFromText } from '../icon/icon.registry.js';
10+
import defaultFileIcon from './assets/file.png';
11+
import jsonIcon from './assets/json.png';
12+
import linkIcon from './assets/link.png';
1013
import type { ChatState } from './chat-state.js';
1114
import { styles } from './themes/message-attachments.base.css.js';
1215
import { styles as shared } from './themes/shared/message-attachments.common.css.js';
@@ -76,6 +79,32 @@ export default class IgcMessageAttachmentsComponent extends LitElement {
7679
this._chatState?.emitEvent('igcAttachmentClick', { detail: attachment });
7780
}
7881

82+
private isImageAttachment(attachment: IgcMessageAttachment): boolean {
83+
return (
84+
attachment.type === 'image' ||
85+
!!attachment.file?.type.startsWith('image/')
86+
);
87+
}
88+
private _fileIconMap: Record<string, string> = {
89+
pdf: defaultFileIcon,
90+
doc: defaultFileIcon,
91+
docx: defaultFileIcon,
92+
xls: defaultFileIcon,
93+
xlsx: defaultFileIcon,
94+
txt: defaultFileIcon,
95+
json: jsonIcon,
96+
link: linkIcon,
97+
default: defaultFileIcon, // A fallback icon
98+
};
99+
100+
private getFileExtension(fileName: string): string {
101+
const parts = fileName.split('.');
102+
if (parts.length > 1) {
103+
return parts.pop()!.toLowerCase();
104+
}
105+
return '';
106+
}
107+
79108
private getURL(attachment: IgcMessageAttachment): string {
80109
if (attachment.url) {
81110
return attachment.url;
@@ -87,14 +116,13 @@ export default class IgcMessageAttachmentsComponent extends LitElement {
87116
}
88117

89118
private renderDefaultAttachmentContent(attachment: IgcMessageAttachment) {
90-
return html`${attachment.type === 'image' ||
91-
attachment.file?.type.startsWith('image/')
92-
? html`<img
93-
part="image-attachment"
94-
src=${this.getURL(attachment)}
95-
alt=${attachment.name}
96-
/>`
97-
: nothing}`;
119+
const ext = this.getFileExtension(attachment.name);
120+
const isImage = this.isImageAttachment(attachment);
121+
const url = isImage
122+
? this.getURL(attachment)
123+
: (this._fileIconMap[ext] ?? this._fileIconMap['default']);
124+
const partName = isImage ? 'image-attachment' : 'file-attachment';
125+
return html` <img part="${partName}" src=${url} alt=${attachment.name} />`;
98126
}
99127

100128
private renderAttachmentHeaderText(attachment: IgcMessageAttachment) {
@@ -146,6 +174,9 @@ export default class IgcMessageAttachmentsComponent extends LitElement {
146174
return html`${this.message?.attachments?.map(
147175
(attachment) =>
148176
html`<div part="attachment">
177+
${this.message?.sender === this._chatState?.currentUserId
178+
? this.renderAttachmentContent(attachment)
179+
: nothing}
149180
<div
150181
part="attachment-header"
151182
role="button"
@@ -155,9 +186,7 @@ export default class IgcMessageAttachmentsComponent extends LitElement {
155186
${this.renderAttachmentHeaderActions()}
156187
</div>
157188
158-
${attachment.type === 'image' ||
159-
attachment.file?.type.startsWith('image/') ||
160-
this._chatState?.options?.templates?.attachmentContentTemplate
189+
${this.message?.sender !== this._chatState?.currentUserId
161190
? this.renderAttachmentContent(attachment)
162191
: nothing}
163192
</div>`

src/components/chat/themes/chat.base.scss

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ $inline-inset: rem(16px);
99
width: 100%;
1010
height: var(--igc-chat-height);
1111
overflow: hidden;
12-
box-shadow: var(--ig-elevation-24);
1312
display: flex;
1413
flex-direction: column;
1514
}
@@ -70,15 +69,16 @@ $inline-inset: rem(16px);
7069
igc-list {
7170
--ig-size: 3;
7271

73-
min-height: fit-content;
7472
padding-block-end: rem(24px);
75-
}
76-
77-
igc-list-header,
78-
igc-list-item {
73+
min-height: fit-content;
74+
width: fit-content;
7975
max-width: rem(576px);
8076
}
8177

8278
igc-list-item {
8379
cursor: pointer;
8480
}
81+
82+
igc-list-item::part(title) {
83+
@include line-clamp(2, true, true);
84+
}

src/components/chat/themes/input.base.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
max-width: rem(760px);
1616
width: 100%;
1717
margin-inline: rem(16px);
18-
gap: rem(8px);
18+
border-radius: rem(4px);
19+
padding: rem(16px);
20+
gap: rem(12px);
1921
}
2022

2123
[part='buttons-container'] {

src/components/chat/themes/message.base.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
padding: rem(12px) rem(16px);
1515
border-radius: rem(24px) rem(24px) 0;
1616
max-width: rem(576px);
17+
width: fit-content;
1718
}
1819

1920
[part~='bubble'] {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@use 'styles/utilities' as *;
22

33
[part~='sent'] {
4-
border-radius: rem(4px);
4+
border-radius: rem(8px) rem(8px) 0;
55
}

0 commit comments

Comments
 (0)