Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
<PackageReference Include="System.Security.Cryptography.Xml" Version="9.0.2" />
<PackageReference Include="System.Text.Encodings.Web" Version="9.0.2" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageReference Include="Telerik.UI.for.AspNet.Core" Version="2025.2.520" />
<PackageReference Include="Telerik.UI.for.AspNet.Core" Version="2025.3.825" />
</ItemGroup>

<ProjectExtensions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://localhost:52626/; img-src 'self' data:; script-src 'self' https://kendo.cdn.telerik.com https://code.jquery.com/ 'nonce-Telerik-CSP-Examples'; style-src 'self' https://kendo.cdn.telerik.com 'nonce-Telerik-CSP-Examples'; font-src 'self' data:;connect-src 'self' wss://localhost;" />
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src 'self' data:; script-src 'self' https://kendo.cdn.telerik.com https://code.jquery.com/ https://unpkg.com 'nonce-Telerik-CSP-Examples'; style-src 'self' https://kendo.cdn.telerik.com 'nonce-Telerik-CSP-Examples'; font-src 'self' data:;connect-src 'self' wss://localhost;" />
<title>@ViewData["Title"] - Telerik.Examples.ContentSecurityPolicy</title>

@{
var kendoVersion = "2025.2.520";
var themeVersion = "11.0.2";
var kendoVersion = "2025.3.825";
var themeVersion = "12.0.0";
}
<link href="https://kendo.cdn.telerik.com/themes/@themeVersion/default/default-ocean-blue.css" rel="stylesheet" type="text/css" />

Expand Down
15 changes: 10 additions & 5 deletions Telerik.Examples.Mvc/Telerik.Examples.Mvc/Hubs/ChatHub.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
using Microsoft.AspNetCore.SignalR;
using Kendo.Mvc.UI;
using Microsoft.AspNetCore.SignalR;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading.Tasks;

namespace Telerik.Examples.Mvc.Hubs
{
public class ChatHub : Hub
{
public async Task Send(object sender, string message)
public async Task Send(string senderId, string senderName, string message)
{
await Clients.Others.SendAsync("broadcastMessage", sender, message);
// Broadcast the message to all clients except the sender.
await Clients.Others.SendAsync("broadcastMessage", senderId, senderName, message);
}

public async Task SendTyping(object sender)
public async Task SendTyping(string senderId, string senderName)
{
await Clients.Others.SendAsync("typing", sender);
// Broadcast the typing notification to all clients except the sender.
await Clients.Others.SendAsync("typing", senderId, senderName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="9.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="9.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="9.0.2" />
<PackageReference Include="Microsoft.AspNetCore.OData" Version="9.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.2" />
Expand All @@ -23,10 +23,10 @@
<PackageReference Include="System.Drawing.Common" Version="9.0.2" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageReference Include="Telerik.Core.Export" Version="2025.2.520" />
<PackageReference Include="Telerik.UI.for.AspNet.Core" Version="2025.2.520" />
<PackageReference Include="Telerik.Web.Captcha" Version="2.0.2" />
<PackageReference Include="Telerik.Web.Spreadsheet" Version="2025.2.520" />
<PackageReference Include="Telerik.Core.Export" Version="2025.3.812" />
<PackageReference Include="Telerik.UI.for.AspNet.Core" Version="2025.3.825" />
<PackageReference Include="Telerik.Web.Captcha" Version="2.0.3" />
<PackageReference Include="Telerik.Web.Spreadsheet" Version="2025.3.812" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,105 @@

@(Html.Kendo().Chat()
.Name("chat")
.User(user => user
.Name(@name)
.IconUrl("https://demos.telerik.com/kendo-ui/content/chat/avatar.png")
)
.AuthorId(@name)
.IsTypingField("isTyping")
.FileAttachment(false)
.Events(events => events
.TypingStart("onTypingStart")
.Post("onPost")
.Input("onInput")
.SendMessage("onSendMessage")
)
)

<script>
const currentUser = {
id: '@name',
name: 'User123',
iconUrl: "https://demos.telerik.com/kendo-ui/content/chat/avatar.png"
};
let isTyping = false;

window.chatHub = new signalR.HubConnectionBuilder()
.withUrl('/chat')
.build();

chatHub.start()
.then(function () {
console.log('SignalR connection started.');
})
.catch(function(err) {
console.error(err.toString());
console.error('Error starting SignalR connection: ' + err.toString());
});

$(function() {
window.chat = $("#chat").getKendoChat();
chatHub.on('broadcastMessage', function(senderId, senderName, message) {
const chat = $("#chat").getKendoChat();

chatHub.on('broadcastMessage', function(sender, message) {
var message = {
type: 'text',
text: message
};
// Check for a "typing" message.
let typingMessages = $.grep(chat.dataSource.data(), function(item){
return item.isTyping == true ? item.id : "";
});

chat.renderMessage(message, sender);
if(typingMessages.length > 0) {
if(typingMessages[0].id != null) {
let messageObject = chat.dataSource.get(typingMessages[0].id);
if (messageObject) {
// Update the "typing" message with the received message text.
let updatedMessage = chat.updateMessage(messageObject, {
text: message,
isTyping: false
});
}
}
} else {
// Post the received message in the Chat.
chat.postMessage({
id: kendo.guid(),
authorId: senderId,
authorName: senderId,
authorImageUrl:currentUser.iconUrl,
text: message,
isTyping: false
});
}
});

chatHub.on('typing', function(sender) {
chat.renderMessage({ type: 'typing' }, sender);
chatHub.on('typing', function(senderId, senderName) {
console.log(senderName + ' is typing');
const chat = $("#chat").getKendoChat();

chat.postMessage({
id: kendo.guid(),
isTyping: true,
authorId: senderId,
authorName: senderId,
authorImageUrl: currentUser.iconUrl
});
});
});

function onTypingStart(e) {
chatHub.invoke("sendTyping", chat.getUser());
// The 'Input' will notify the SignallR Hub that the current client is typing.
// The Hub, in turn, will notify all the other clients that the user has started typing.
function onInput(e) {
// If not already typing, send typing notification.
if (!isTyping) {
isTyping = true;
chatHub.invoke("sendTyping", currentUser.id, currentUser.name);
}
}

function onPost(args) {
chatHub.invoke("send", chat.getUser(), args.text);
// The 'SendMessage' handler will send the user data and the typed text to the SignalR Hub.
// The Hub will then forward that info to the other clients.
function onSendMessage(args) {
// Update the message data based on the current user's data.
args.message.id = kendo.guid();
args.message.authorId = currentUser.id;
args.message.authorName = currentUser.name;
args.message.authorImageUrl = currentUser.iconUrl;

// Stop typing when sending a message.
if (isTyping) {
isTyping = false;
}
chatHub.invoke("send", args.message.authorId, args.message.authorName, args.message.text);
}
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Telerik.Examples.Mvc</title>
@{
var kendoVersion = "2025.2.520";
var themeVersion = "11.0.2";
var kendoVersion = "2025.3.825";
var themeVersion = "12.0.0";
}
<link href="https://kendo.cdn.telerik.com/themes/@themeVersion/default/default-ocean-blue.css" rel="stylesheet" type="text/css" />

<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://unpkg.com/jszip/dist/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/@kendoVersion/js/kendo.all.min.js"></script>
<script src="https://kendo.cdn.telerik.com/@kendoVersion/js/kendo.aspnetmvc.min.js"></script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,53 @@
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@Html.AntiForgeryToken()

<h1>ChatIndex</h1>
<h1>Chat bound to remote data</h1>

@(Html.Kendo().Chat()
.Name("chat")
.Toolbar(toolbar =>
{
toolbar.Toggleable(Model.Toggable);
toolbar.Scrollable(Model.Scrollable);
toolbar.Buttons(buttons =>
{
buttons.Add().Name("Settings").IconClass("k-icon k-i-gear");
buttons.Add().Name("Hand").IconClass("k-icon k-i-hand");
buttons.Add().Name("Bold").IconClass("k-icon k-i-bold");
buttons.Add().Name("Italic").IconClass("k-icon k-i-italic");
buttons.Add().Name("Underline").IconClass("k-icon k-i-underline");
});
})
.Messages(messages =>
{
messages.Placeholder(Model.Placeholder);
messages.SendButton(Model.SendButton);
})
.Events(e =>
{
e.ToolClick("onToolClick");
})
@(Html.Kendo().Chat()
.Name("chat")
.Height("600px")
.Width("400px")
.AuthorId("1")
.TextField("Text")
.AuthorNameField("AuthorName")
.FilesField("Files")
.AuthorIdField("AuthorId")
.AuthorImageUrlField("AuthorImageUrl")
.AuthorImageAltTextField("AuthorImageAltText")
.TimestampField("TimeStamp")
.IdField("Id")
.IsPinnedField("IsPinned")
.IsDeletedField("IsDeleted")
.IsTypingField("IsTyping")
.DataSource(dataSource => dataSource
.Ajax()
.Read(r => r.Url("/Chat/ChatIndex?handler=ReadMessages").Data("forgeryToken"))
.Create(r => r.Url("/Chat/ChatIndex?handler=CreateMessage").Data("forgeryToken"))
.Update(r => r.Url("/Chat/ChatIndex?handler=UpdateMessage").Data("forgeryToken"))
)

.Events(events => events.SendMessage("onSendMessage"))
)

<script>
function onToolClick(e) {
console.log(e.name)
}
function forgeryToken() {
return kendo.antiForgeryTokens();
}

function onSendMessage(e) {
const currentUser = {
id: 1,
name: "John Doe",
iconUrl: "https://demos.telerik.com/aspnet-core/shared/web/Customers/RICSU.jpg",
iconAltText: "John's profile picture"
};

e.message.authorId = currentUser.id;
e.message.authorName = currentUser.name;
e.message.authorImageUrl = currentUser.iconUrl;
e.message.authorImageAltText = currentUser.iconAltText;

setTimeout(() => {
e.sender.scrollToBottom();
}, 30);
}
</script>
Loading