diff --git a/apps/demos/Demos/Chat/Customization/Angular/app/app.component.css b/apps/demos/Demos/Chat/Customization/Angular/app/app.component.css
new file mode 100644
index 00000000000..9c2d96ac5b0
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/Angular/app/app.component.css
@@ -0,0 +1,38 @@
+.demo-container {
+ min-width: 720px;
+ display: flex;
+ gap: 20px;
+}
+
+::ng-deep .chat-container {
+ display: flex;
+ flex-grow: 1;
+ align-items: center;
+ justify-content: center;
+}
+
+::ng-deep .options {
+ padding: 20px;
+ display: flex;
+ flex-direction: column;
+ min-width: 280px;
+ background-color: rgba(191, 191, 191, 0.15);
+ gap: 16px;
+}
+
+::ng-deep .dx-chat {
+ max-width: 480px;
+}
+
+::ng-deep .caption {
+ font-size: var(--dx-font-size-sm);
+ font-weight: 500;
+}
+
+::ng-deep .option-separator {
+ border-bottom: 1px solid var(--dx-color-border);
+}
+
+::ng-deep .dx-avatar {
+ border: 1px solid var(--dx-color-border);
+}
diff --git a/apps/demos/Demos/Chat/Customization/Angular/app/app.component.html b/apps/demos/Demos/Chat/Customization/Angular/app/app.component.html
new file mode 100644
index 00000000000..f56f172747d
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/Angular/app/app.component.html
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
Options
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Day Header Format:
+
+
+
+
+
+
+
+
+
+
+ Message Timestamp Format:
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demos/Demos/Chat/Customization/Angular/app/app.component.ts b/apps/demos/Demos/Chat/Customization/Angular/app/app.component.ts
new file mode 100644
index 00000000000..4761f32429a
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/Angular/app/app.component.ts
@@ -0,0 +1,63 @@
+import { NgModule, Component, enableProdMode } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { DxChatModule, DxCheckBoxModule, DxSelectBoxModule } from 'devextreme-angular';
+import { User, Message, MessageEnteredEvent } from 'devextreme/ui/chat';
+import { Observable } from 'rxjs';
+import { AppService } from './app.service';
+
+if (!/localhost/.test(document.location.host)) {
+ enableProdMode();
+}
+
+let modulePrefix = '';
+// @ts-ignore
+if (window && window.config.packageConfigPaths) {
+ modulePrefix = '/app';
+}
+
+@Component({
+ selector: 'demo-app',
+ templateUrl: `.${modulePrefix}/app.component.html`,
+ styleUrls: [`.${modulePrefix}/app.component.css`],
+})
+export class AppComponent {
+ currentUser: User;
+
+ supportAgent: User;
+
+ messages$: Observable;
+
+ dayHeaderFormats = this.appService.dayHeaderFormats;
+
+ messageTimestampFormats = this.appService.messageTimestampFormats;
+
+ dayHeaderLabel = this.appService.dayHeaderLabel;
+
+ messageTimestampLabel = this.appService.messageTimestampLabel;
+
+ constructor(private readonly appService: AppService) {
+ [this.currentUser, this.supportAgent] = this.appService.getUsers();
+ this.messages$ = this.appService.messages$;
+ }
+
+ onMessageEntered(event: MessageEnteredEvent) {
+ this.appService.onMessageEntered(event);
+ }
+}
+
+@NgModule({
+ imports: [
+ BrowserModule,
+ DxChatModule,
+ DxCheckBoxModule,
+ DxSelectBoxModule,
+ ],
+ declarations: [AppComponent],
+ bootstrap: [AppComponent],
+ providers: [AppService],
+})
+export class AppModule { }
+
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/apps/demos/Demos/Chat/Customization/Angular/app/app.service.ts b/apps/demos/Demos/Chat/Customization/Angular/app/app.service.ts
new file mode 100644
index 00000000000..76090483287
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/Angular/app/app.service.ts
@@ -0,0 +1,90 @@
+import { Injectable } from '@angular/core';
+import { Observable, BehaviorSubject } from 'rxjs';
+import { User, Message, MessageEnteredEvent } from 'devextreme/ui/chat';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class AppService {
+ date: Date;
+
+ currentUser: User = {
+ id: 'c94c0e76-fb49-4b9b-8f07-9f93ed93b4f3',
+ name: 'John Doe',
+ };
+
+ supportAgent: User = {
+ id: 'd16d1a4c-5c67-4e20-b70e-2991c22747c3',
+ name: 'Support Agent',
+ avatarUrl: '../../../../images/petersmith.png',
+ };
+
+ dayHeaderFormats = ['dd/MM/yyyy', 'dd.MM.yyyy', 'MMMM dd, yyyy', 'EEEE, MMMM dd'];
+
+ messageTimestampFormats = ['hh:mm a', 'hh:mm:ss a', 'HH:mm', 'HH:mm:ss'];
+
+ messageTimestampLabel = { 'aria-label': 'Message Timestamp Format' };
+
+ dayHeaderLabel = { 'aria-label': 'Day Header Format' };
+
+ messages: Message[] = [];
+
+ messagesSubject: BehaviorSubject = new BehaviorSubject([]);
+
+ constructor() {
+ this.date = new Date();
+ this.date.setHours(0, 0, 0, 0);
+
+ this.messages = [
+ {
+ timestamp: this.getTimestamp(this.date, -9),
+ author: this.supportAgent,
+ text: 'Hello, John!\nHow can I assist you today?',
+ },
+ {
+ timestamp: this.getTimestamp(this.date, -7),
+ author: this.currentUser,
+ text: 'Hi, I\'m having trouble accessing my account.',
+ },
+ {
+ timestamp: this.getTimestamp(this.date, -7),
+ author: this.currentUser,
+ text: 'It says my password is incorrect.',
+ },
+ {
+ timestamp: this.getTimestamp(this.date, -7),
+ author: this.supportAgent,
+ text: 'I can help you with that. Can you please confirm your UserID for security purposes?',
+ },
+ {
+ timestamp: this.getTimestamp(this.date, 1),
+ author: this.currentUser,
+ text: 'john.doe1357',
+ },
+ {
+ timestamp: this.getTimestamp(this.date, 1),
+ author: this.supportAgent,
+ text: '✅ Instructions to restore access have been sent to the email address associated with your account.',
+ },
+ ];
+
+ this.messagesSubject.next(this.messages);
+ }
+
+ get messages$(): Observable {
+ return this.messagesSubject.asObservable();
+ }
+
+ getUsers(): User[] {
+ return [this.currentUser, this.supportAgent];
+ }
+
+ getTimestamp(date: Date, offsetMinutes = 0): number {
+ return date.getTime() + offsetMinutes * 60000;
+ }
+
+ onMessageEntered(event: MessageEnteredEvent) {
+ this.messages = [...this.messages, event.message];
+ this.messagesSubject.next(this.messages);
+ }
+}
diff --git a/apps/demos/Demos/Chat/Customization/Angular/index.html b/apps/demos/Demos/Chat/Customization/Angular/index.html
new file mode 100644
index 00000000000..1ab1fb54a1d
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/Angular/index.html
@@ -0,0 +1,26 @@
+
+
+
+ DevExtreme Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Loading...
+
+
+
diff --git a/apps/demos/Demos/Chat/Customization/React/App.tsx b/apps/demos/Demos/Chat/Customization/React/App.tsx
new file mode 100644
index 00000000000..0702563c234
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/React/App.tsx
@@ -0,0 +1,119 @@
+import React, { useState, useCallback } from 'react';
+import Chat, { ChatTypes } from 'devextreme-react/chat';
+import { MessageEnteredEvent } from 'devextreme/ui/chat';
+import SelectBox from 'devextreme-react/select-box';
+import CheckBox from 'devextreme-react/check-box';
+
+import {
+ currentUser,
+ messages as initialMessages,
+ dayHeaderFormats as headerFormats,
+ messageTimestampFormats as messageTimestamps,
+ messageTimestampLabel,
+ dayHeaderLabel,
+} from './data.ts';
+
+export default function App() {
+ const [messages, setMessages] = useState(initialMessages);
+ const [showAvatar, setShowAvatar] = useState(true);
+ const [showUsername, setShowUsername] = useState(true);
+ const [showDayHeaders, setDayHeaders] = useState(true);
+ const [dayHeaderFormat, setDayHeaderFormat] = useState(headerFormats[0]);
+ const [showMessageTimestamp, setMessageTimestamp] = useState(true);
+ const [messageTimestampFormat, setMessageTimestampFormat] = useState(messageTimestamps[0]);
+ const [isDisabled, setDisabled] = useState(false);
+
+ const onMessageEntered = useCallback(({ message }: MessageEnteredEvent) => {
+ setMessages((prevMessages) => [...prevMessages, message]);
+ }, []);
+
+ return (
+
+
+
+
+
+
+
Options
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Day Header Format:
+
+
+
+
+
+
+
+
+
+
+ Message Timestamp Format:
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/apps/demos/Demos/Chat/Customization/React/data.ts b/apps/demos/Demos/Chat/Customization/React/data.ts
new file mode 100644
index 00000000000..de004f28c98
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/React/data.ts
@@ -0,0 +1,57 @@
+import { ChatTypes } from 'devextreme-react/chat';
+
+function getTimestamp(date, offsetMinutes = 0) {
+ return date.getTime() + offsetMinutes * 60000;
+}
+
+const date = new Date();
+date.setHours(0, 0, 0, 0);
+
+export const currentUser: ChatTypes.User = {
+ id: 'c94c0e76-fb49-4b9b-8f07-9f93ed93b4f3',
+ name: 'John Doe',
+};
+
+export const supportAgent: ChatTypes.User = {
+ id: 'd16d1a4c-5c67-4e20-b70e-2991c22747c3',
+ name: 'Support Agent',
+ avatarUrl: '../../../../images/petersmith.png',
+};
+
+export const messages = [
+ {
+ timestamp: getTimestamp(date, -9),
+ author: supportAgent,
+ text: 'Hello, John!\nHow can I assist you today?',
+ },
+ {
+ timestamp: getTimestamp(date, -7),
+ author: currentUser,
+ text: 'Hi, I\'m having trouble accessing my account.',
+ },
+ {
+ timestamp: getTimestamp(date, -7),
+ author: currentUser,
+ text: 'It says my password is incorrect.',
+ },
+ {
+ timestamp: getTimestamp(date, -7),
+ author: supportAgent,
+ text: 'I can help you with that. Can you please confirm your UserID for security purposes?',
+ },
+ {
+ timestamp: getTimestamp(date, 1),
+ author: currentUser,
+ text: 'john.doe1357',
+ },
+ {
+ timestamp: getTimestamp(date, 1),
+ author: supportAgent,
+ text: '✅ Instructions to restore access have been sent to the email address associated with your account.',
+ },
+];
+
+export const dayHeaderFormats = ['dd/MM/yyyy', 'dd.MM.yyyy', 'MMMM dd, yyyy', 'EEEE, MMMM dd'];
+export const messageTimestampFormats = ['hh:mm a', 'hh:mm:ss a', 'HH:mm', 'HH:mm:ss'];
+export const messageTimestampLabel = { 'aria-label': 'Message Timestamp Format' };
+export const dayHeaderLabel = { 'aria-label': 'Day Header Format' };
diff --git a/apps/demos/Demos/Chat/Customization/React/index.html b/apps/demos/Demos/Chat/Customization/React/index.html
new file mode 100644
index 00000000000..e90d25ad879
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/React/index.html
@@ -0,0 +1,24 @@
+
+
+
+ DevExtreme Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demos/Demos/Chat/Customization/React/index.tsx b/apps/demos/Demos/Chat/Customization/React/index.tsx
new file mode 100644
index 00000000000..8acbec4b617
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/React/index.tsx
@@ -0,0 +1,9 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+import App from './App.tsx';
+
+ReactDOM.render(
+ ,
+ document.getElementById('app'),
+);
diff --git a/apps/demos/Demos/Chat/Customization/React/styles.css b/apps/demos/Demos/Chat/Customization/React/styles.css
new file mode 100644
index 00000000000..7a5b25461db
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/React/styles.css
@@ -0,0 +1,38 @@
+#app {
+ min-width: 720px;
+ display: flex;
+ gap: 20px;
+}
+
+.chat-container {
+ display: flex;
+ flex-grow: 1;
+ align-items: center;
+ justify-content: center;
+}
+
+.options {
+ padding: 20px;
+ display: flex;
+ flex-direction: column;
+ min-width: 280px;
+ background-color: rgba(191, 191, 191, 0.15);
+ gap: 16px;
+}
+
+.dx-chat {
+ max-width: 480px;
+}
+
+.caption {
+ font-size: var(--dx-font-size-sm);
+ font-weight: 500;
+}
+
+.option-separator {
+ border-bottom: 1px solid var(--dx-color-border);
+}
+
+.dx-avatar {
+ border: 1px solid var(--dx-color-border);
+}
diff --git a/apps/demos/Demos/Chat/Customization/ReactJs/App.js b/apps/demos/Demos/Chat/Customization/ReactJs/App.js
new file mode 100644
index 00000000000..92f10777d68
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/ReactJs/App.js
@@ -0,0 +1,115 @@
+import React, { useState, useCallback } from 'react';
+import Chat from 'devextreme-react/chat';
+import SelectBox from 'devextreme-react/select-box';
+import CheckBox from 'devextreme-react/check-box';
+import {
+ currentUser,
+ messages as initialMessages,
+ dayHeaderFormats as headerFormats,
+ messageTimestampFormats as messageTimestamps,
+ messageTimestampLabel,
+ dayHeaderLabel,
+} from './data.js';
+
+export default function App() {
+ const [messages, setMessages] = useState(initialMessages);
+ const [showAvatar, setShowAvatar] = useState(true);
+ const [showUsername, setShowUsername] = useState(true);
+ const [showDayHeaders, setDayHeaders] = useState(true);
+ const [dayHeaderFormat, setDayHeaderFormat] = useState(headerFormats[0]);
+ const [showMessageTimestamp, setMessageTimestamp] = useState(true);
+ const [messageTimestampFormat, setMessageTimestampFormat] = useState(messageTimestamps[0]);
+ const [isDisabled, setDisabled] = useState(false);
+ const onMessageEntered = useCallback(({ message }) => {
+ setMessages((prevMessages) => [...prevMessages, message]);
+ }, []);
+ return (
+
+
+
+
+
+
+
Options
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Day Header Format:
+
+
+
+
+
+
+
+
+
+
+ Message Timestamp Format:
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/apps/demos/Demos/Chat/Customization/ReactJs/data.js b/apps/demos/Demos/Chat/Customization/ReactJs/data.js
new file mode 100644
index 00000000000..40b37bf56ff
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/ReactJs/data.js
@@ -0,0 +1,50 @@
+function getTimestamp(date, offsetMinutes = 0) {
+ return date.getTime() + offsetMinutes * 60000;
+}
+const date = new Date();
+date.setHours(0, 0, 0, 0);
+export const currentUser = {
+ id: 'c94c0e76-fb49-4b9b-8f07-9f93ed93b4f3',
+ name: 'John Doe',
+};
+export const supportAgent = {
+ id: 'd16d1a4c-5c67-4e20-b70e-2991c22747c3',
+ name: 'Support Agent',
+ avatarUrl: '../../../../images/petersmith.png',
+};
+export const messages = [
+ {
+ timestamp: getTimestamp(date, -9),
+ author: supportAgent,
+ text: 'Hello, John!\nHow can I assist you today?',
+ },
+ {
+ timestamp: getTimestamp(date, -7),
+ author: currentUser,
+ text: "Hi, I'm having trouble accessing my account.",
+ },
+ {
+ timestamp: getTimestamp(date, -7),
+ author: currentUser,
+ text: 'It says my password is incorrect.',
+ },
+ {
+ timestamp: getTimestamp(date, -7),
+ author: supportAgent,
+ text: 'I can help you with that. Can you please confirm your UserID for security purposes?',
+ },
+ {
+ timestamp: getTimestamp(date, 1),
+ author: currentUser,
+ text: 'john.doe1357',
+ },
+ {
+ timestamp: getTimestamp(date, 1),
+ author: supportAgent,
+ text: '✅ Instructions to restore access have been sent to the email address associated with your account.',
+ },
+];
+export const dayHeaderFormats = ['dd/MM/yyyy', 'dd.MM.yyyy', 'MMMM dd, yyyy', 'EEEE, MMMM dd'];
+export const messageTimestampFormats = ['hh:mm a', 'hh:mm:ss a', 'HH:mm', 'HH:mm:ss'];
+export const messageTimestampLabel = { 'aria-label': 'Message Timestamp Format' };
+export const dayHeaderLabel = { 'aria-label': 'Day Header Format' };
diff --git a/apps/demos/Demos/Chat/Customization/ReactJs/index.html b/apps/demos/Demos/Chat/Customization/ReactJs/index.html
new file mode 100644
index 00000000000..c9ee055d50a
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/ReactJs/index.html
@@ -0,0 +1,44 @@
+
+
+
+ DevExtreme Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demos/Demos/Chat/Customization/ReactJs/index.js b/apps/demos/Demos/Chat/Customization/ReactJs/index.js
new file mode 100644
index 00000000000..b853e0be824
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/ReactJs/index.js
@@ -0,0 +1,5 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import App from './App.js';
+
+ReactDOM.render(, document.getElementById('app'));
diff --git a/apps/demos/Demos/Chat/Customization/ReactJs/styles.css b/apps/demos/Demos/Chat/Customization/ReactJs/styles.css
new file mode 100644
index 00000000000..7a5b25461db
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/ReactJs/styles.css
@@ -0,0 +1,38 @@
+#app {
+ min-width: 720px;
+ display: flex;
+ gap: 20px;
+}
+
+.chat-container {
+ display: flex;
+ flex-grow: 1;
+ align-items: center;
+ justify-content: center;
+}
+
+.options {
+ padding: 20px;
+ display: flex;
+ flex-direction: column;
+ min-width: 280px;
+ background-color: rgba(191, 191, 191, 0.15);
+ gap: 16px;
+}
+
+.dx-chat {
+ max-width: 480px;
+}
+
+.caption {
+ font-size: var(--dx-font-size-sm);
+ font-weight: 500;
+}
+
+.option-separator {
+ border-bottom: 1px solid var(--dx-color-border);
+}
+
+.dx-avatar {
+ border: 1px solid var(--dx-color-border);
+}
diff --git a/apps/demos/Demos/Chat/Customization/Vue/App.vue b/apps/demos/Demos/Chat/Customization/Vue/App.vue
new file mode 100644
index 00000000000..2299a9350d1
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/Vue/App.vue
@@ -0,0 +1,151 @@
+
+
+
+
+
+
+
Options
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Day Header Format:
+
+
+
+
+
+
+
+
+
+
+ Message Timestamp Format:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demos/Demos/Chat/Customization/Vue/data.ts b/apps/demos/Demos/Chat/Customization/Vue/data.ts
new file mode 100644
index 00000000000..de0ab54cf1e
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/Vue/data.ts
@@ -0,0 +1,55 @@
+const date = new Date();
+date.setHours(0, 0, 0, 0);
+
+function getTimestamp(date, offsetMinutes = 0) {
+ return date.getTime() + offsetMinutes * 60000;
+}
+
+export const currentUser = {
+ id: 'c94c0e76-fb49-4b9b-8f07-9f93ed93b4f3',
+ name: 'John Doe',
+};
+
+export const supportAgent = {
+ id: 'd16d1a4c-5c67-4e20-b7v0e-2991c22747c3',
+ name: 'Support Agent',
+ avatarUrl: '../../../../images/petersmith.png',
+};
+
+export const messages = [
+ {
+ timestamp: getTimestamp(date, -9),
+ author: supportAgent,
+ text: 'Hello, John!\nHow can I assist you today?',
+ },
+ {
+ timestamp: getTimestamp(date, -7),
+ author: currentUser,
+ text: 'Hi, I\'m having trouble accessing my account.',
+ },
+ {
+ timestamp: getTimestamp(date, -7),
+ author: currentUser,
+ text: 'It says my password is incorrect.',
+ },
+ {
+ timestamp: getTimestamp(date, -7),
+ author: supportAgent,
+ text: 'I can help you with that. Can you please confirm your UserID for security purposes?',
+ },
+ {
+ timestamp: getTimestamp(date, 1),
+ author: currentUser,
+ text: 'john.doe1357',
+ },
+ {
+ timestamp: getTimestamp(date, 1),
+ author: supportAgent,
+ text: '✅ Instructions to restore access have been sent to the email address associated with your account.',
+ },
+];
+
+export const dayHeaderFormats = ['dd/MM/yyyy', 'dd.MM.yyyy', 'MMMM dd, yyyy', 'EEEE, MMMM dd'];
+export const messageTimestampFormats = ['hh:mm a', 'hh:mm:ss a', 'HH:mm', 'HH:mm:ss'];
+export const messageTimestampLabel = { 'aria-label': 'Message Timestamp Format' };
+export const dayHeaderLabel = { 'aria-label': 'Day Header Format' };
diff --git a/apps/demos/Demos/Chat/Customization/Vue/index.html b/apps/demos/Demos/Chat/Customization/Vue/index.html
new file mode 100644
index 00000000000..2413f2254bf
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/Vue/index.html
@@ -0,0 +1,29 @@
+
+
+
+ DevExtreme Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demos/Demos/Chat/Customization/Vue/index.ts b/apps/demos/Demos/Chat/Customization/Vue/index.ts
new file mode 100644
index 00000000000..684d04215d7
--- /dev/null
+++ b/apps/demos/Demos/Chat/Customization/Vue/index.ts
@@ -0,0 +1,4 @@
+import { createApp } from 'vue';
+import App from './App.vue';
+
+createApp(App).mount('#app');
diff --git a/apps/demos/Demos/Chat/Customization/jQuery/data.js b/apps/demos/Demos/Chat/Customization/jQuery/data.js
index d08b0148f92..a1fac597078 100644
--- a/apps/demos/Demos/Chat/Customization/jQuery/data.js
+++ b/apps/demos/Demos/Chat/Customization/jQuery/data.js
@@ -49,5 +49,5 @@ const messages = [
},
];
-const dayHeaderFormat = ['dd/MM/yyyy', 'dd.MM.yyyy', 'MMMM dd, yyyy', 'EEEE, MMMM dd'];
-const messageTimestampFormat = ['hh:mm a', 'hh:mm:ss a', 'HH:mm', 'HH:mm:ss'];
+const dayHeaderFormats = ['dd/MM/yyyy', 'dd.MM.yyyy', 'MMMM dd, yyyy', 'EEEE, MMMM dd'];
+const messageTimestampFormats = ['hh:mm a', 'hh:mm:ss a', 'HH:mm', 'HH:mm:ss'];
diff --git a/apps/demos/Demos/Chat/Customization/jQuery/index.html b/apps/demos/Demos/Chat/Customization/jQuery/index.html
index 982e6920c30..3e7795ca02b 100644
--- a/apps/demos/Demos/Chat/Customization/jQuery/index.html
+++ b/apps/demos/Demos/Chat/Customization/jQuery/index.html
@@ -36,8 +36,8 @@
- Day Headers Format:
-
+ Day Header Format:
+
diff --git a/apps/demos/Demos/Chat/Customization/jQuery/index.js b/apps/demos/Demos/Chat/Customization/jQuery/index.js
index b6381e0deed..60d457efe70 100644
--- a/apps/demos/Demos/Chat/Customization/jQuery/index.js
+++ b/apps/demos/Demos/Chat/Customization/jQuery/index.js
@@ -3,16 +3,16 @@ $(() => {
height: 710,
items: messages,
user: currentUser,
- dayHeaderFormat: dayHeaderFormat[0],
+ dayHeaderFormat: dayHeaderFormats[0],
+ messageTimestampFormat: messageTimestampFormats[0],
onMessageEntered({ component, message }) {
component.renderMessage(message);
},
- messageTimestampFormat: messageTimestampFormat[0],
}).dxChat('instance');
$('#show-avatar').dxCheckBox({
value: true,
- text: 'Show Avatar',
+ text: 'Avatar',
onValueChanged(data) {
chat.option('showAvatar', data.value);
},
@@ -20,7 +20,7 @@ $(() => {
$('#show-user-name').dxCheckBox({
value: true,
- text: 'Show User Name',
+ text: 'User Name',
onValueChanged(data) {
chat.option('showUserName', data.value);
},
@@ -28,16 +28,16 @@ $(() => {
$('#show-day-headers').dxCheckBox({
value: true,
- text: 'Show Day Headers',
+ text: 'Day Headers',
onValueChanged(data) {
chat.option('showDayHeaders', data.value);
},
});
- $('#day-headers-format').dxSelectBox({
- items: dayHeaderFormat,
- value: dayHeaderFormat[0],
- inputAttr: { 'aria-label': 'Day Headers Format' },
+ $('#day-header-format').dxSelectBox({
+ items: dayHeaderFormats,
+ value: dayHeaderFormats[0],
+ inputAttr: { 'aria-label': 'Day Header Format' },
onValueChanged(data) {
chat.option('dayHeaderFormat', data.value);
},
@@ -45,15 +45,15 @@ $(() => {
$('#show-message-timestamp').dxCheckBox({
value: true,
- text: 'Show Message Timestamp',
+ text: 'Message Timestamp',
onValueChanged(data) {
chat.option('showMessageTimestamp', data.value);
},
});
$('#message-timestamp-format').dxSelectBox({
- items: messageTimestampFormat,
- value: messageTimestampFormat[0],
+ items: messageTimestampFormats,
+ value: messageTimestampFormats[0],
inputAttr: { 'aria-label': 'Message Timestamp Format' },
onValueChanged(data) {
chat.option('messageTimestampFormat', data.value);
diff --git a/apps/demos/Demos/Chat/Overview/Angular/app/app.component.ts b/apps/demos/Demos/Chat/Overview/Angular/app/app.component.ts
index d7524f752de..441a9da8424 100644
--- a/apps/demos/Demos/Chat/Overview/Angular/app/app.component.ts
+++ b/apps/demos/Demos/Chat/Overview/Angular/app/app.component.ts
@@ -4,8 +4,8 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { DxChatModule } from 'devextreme-angular';
import { User, Message, MessageEnteredEvent } from 'devextreme/ui/chat';
-import { AppService } from './app.service';
import { Observable } from 'rxjs';
+import { AppService } from './app.service';
if (!/localhost/.test(document.location.host)) {
enableProdMode();
@@ -24,12 +24,16 @@ if (window && window.config.packageConfigPaths) {
})
export class AppComponent {
currentUser: User;
+
supportAgent: User;
+
messages$: Observable;
+
userChatTypingUsers$: Observable;
+
supportChatTypingUsers$: Observable;
- constructor(private appService: AppService) {
+ constructor(private readonly appService: AppService) {
[this.currentUser, this.supportAgent] = this.appService.getUsers();
this.messages$ = this.appService.messages$;
this.userChatTypingUsers$ = this.appService.userChatTypingUsers$;
diff --git a/apps/demos/Demos/Chat/Overview/Angular/app/app.service.ts b/apps/demos/Demos/Chat/Overview/Angular/app/app.service.ts
index 890f1fd173f..2c886093144 100644
--- a/apps/demos/Demos/Chat/Overview/Angular/app/app.service.ts
+++ b/apps/demos/Demos/Chat/Overview/Angular/app/app.service.ts
@@ -23,6 +23,7 @@ export class AppService {
messages: Message[] = [];
userChatTypingUsersSubject: BehaviorSubject = new BehaviorSubject([]);
+
supportChatTypingUsersSubject: BehaviorSubject = new BehaviorSubject([]);
messagesSubject: BehaviorSubject = new BehaviorSubject([]);
@@ -35,32 +36,32 @@ export class AppService {
{
timestamp: this.getTimestamp(this.date, -9),
author: this.supportAgent,
- text: 'Hello, John!\nHow can I assist you today?'
+ text: 'Hello, John!\nHow can I assist you today?',
},
{
timestamp: this.getTimestamp(this.date, -7),
author: this.currentUser,
- text: 'Hi, I\'m having trouble accessing my account.'
+ text: 'Hi, I\'m having trouble accessing my account.',
},
{
timestamp: this.getTimestamp(this.date, -7),
author: this.currentUser,
- text: 'It says my password is incorrect.'
+ text: 'It says my password is incorrect.',
},
{
timestamp: this.getTimestamp(this.date, -7),
author: this.supportAgent,
- text: 'I can help you with that. Can you please confirm your UserID for security purposes?'
+ text: 'I can help you with that. Can you please confirm your UserID for security purposes?',
},
{
timestamp: this.getTimestamp(this.date, 1),
author: this.currentUser,
- text: 'john.doe1357'
+ text: 'john.doe1357',
},
{
timestamp: this.getTimestamp(this.date, 1),
author: this.supportAgent,
- text: '✅ Instructions to restore access have been sent to the email address associated with your account.'
+ text: '✅ Instructions to restore access have been sent to the email address associated with your account.',
},
];
@@ -85,7 +86,7 @@ export class AppService {
return [this.currentUser, this.supportAgent];
}
- getTimestamp(date: Date, offsetMinutes: number = 0): number {
+ getTimestamp(date: Date, offsetMinutes = 0): number {
return date.getTime() + offsetMinutes * 60000;
}
diff --git a/apps/demos/Demos/Chat/Overview/React/App.tsx b/apps/demos/Demos/Chat/Overview/React/App.tsx
index 57cba74af15..4fc1a0f2e8a 100644
--- a/apps/demos/Demos/Chat/Overview/React/App.tsx
+++ b/apps/demos/Demos/Chat/Overview/React/App.tsx
@@ -11,7 +11,7 @@ export default function App() {
const [messages, setMessages] = useState(initialMessages);
function onMessageEntered({ message }: MessageEnteredEvent) {
- setMessages(prevMessages => [...prevMessages, message]);
+ setMessages((prevMessages) => [...prevMessages, message]);
}
function typingStart({ user }: TypingStartEvent) {
diff --git a/apps/demos/Demos/Chat/Overview/React/data.ts b/apps/demos/Demos/Chat/Overview/React/data.ts
index 45bc06d30ea..7d233683b19 100644
--- a/apps/demos/Demos/Chat/Overview/React/data.ts
+++ b/apps/demos/Demos/Chat/Overview/React/data.ts
@@ -22,31 +22,31 @@ export const initialMessages = [
{
timestamp: getTimestamp(date, -9),
author: supportAgent,
- text: 'Hello, John!\nHow can I assist you today?'
+ text: 'Hello, John!\nHow can I assist you today?',
},
{
timestamp: getTimestamp(date, -7),
author: currentUser,
- text: 'Hi, I\'m having trouble accessing my account.'
+ text: 'Hi, I\'m having trouble accessing my account.',
},
{
timestamp: getTimestamp(date, -7),
author: currentUser,
- text: 'It says my password is incorrect.'
+ text: 'It says my password is incorrect.',
},
{
timestamp: getTimestamp(date, -7),
author: supportAgent,
- text: 'I can help you with that. Can you please confirm your UserID for security purposes?'
+ text: 'I can help you with that. Can you please confirm your UserID for security purposes?',
},
{
timestamp: getTimestamp(date, 1),
author: currentUser,
- text: 'john.doe1357'
+ text: 'john.doe1357',
},
{
timestamp: getTimestamp(date, 1),
author: supportAgent,
- text: '✅ Instructions to restore access have been sent to the email address associated with your account.'
+ text: '✅ Instructions to restore access have been sent to the email address associated with your account.',
},
];
diff --git a/apps/demos/Demos/Chat/Overview/Vue/App.vue b/apps/demos/Demos/Chat/Overview/Vue/App.vue
index 0141f6fff78..3fcf8fe9a28 100644
--- a/apps/demos/Demos/Chat/Overview/Vue/App.vue
+++ b/apps/demos/Demos/Chat/Overview/Vue/App.vue
@@ -20,11 +20,7 @@