Chat

Awesome chat
Chat built using the awesome grid with a custom item render function. SignalR is used for syncing the clients.
Shared/Demos/Chat.cshtml
@using System.Globalization
<div class="chat o-flexf o-flex-col" style="max-width: 30em; min-width: 13em;">
<div class="chat-header">Awesome chat</div>
<div class="o-flex" style="padding:0.6em 1em;">
<label>
Name: @(Html.Awe().TextBox(new TextBoxOpt
{
Name = "userName",
Placeholder = "user name"
}))
</label>
</div>
@(Html.Awe().Grid("ChatList")
.ShowFooter(false)
.ShowHeader(false)
.Groupable(false)
.Mod(o => o.InfiniteScroll())
.BlockLayout()
.Url(Url.Action("ChatMessagesGrid", "Chat"))
.Load(false)
.Attr("culture", CultureInfo.CurrentCulture.Name)
.Columns(
new Column { Bind = "DateCreated", Sort = Sort.Asc }
))
<div class="o-flex" style="padding:.4em;" id="chatForm" action="@Url.Action("SendMessage", "Chat")">
<div class="o-flexf chat-editor">
<input type="hidden" name="id" />
<textarea name="content" id="content" placeholder="Aa" class="o-flexf"></textarea>
<button type="button" class="awe-btn o-hidden chat-cancel">@MyAweIcons.CancelIco()</button>
<button id="btnSend" type="button" class="awe-btn chat-send">Send</button>
</div>
</div>
</div>
<script>
$(function(){
$.when(awe.using({ url: '/js/chatInit.js', get: () => window.chatInit }))
.then(() => chatInit({
grid: $('#ChatList'),
hubUrl: '/chatHub',
deleteUrl: '@Url.Action("Delete", "Chat")'
}));
});
</script>
<link href="~/css/comp/chat.css" rel="stylesheet">
Demos/Grid/ChatController.cs
public class ChatController : Controller
{
private readonly IHubContext<ChatHub> _chatHubContext;

public ChatController(IHubContext<ChatHub> chatHubContext)
{
_chatHubContext = chatHubContext;
}

public IActionResult Index()
{
return View();
}

[HttpPost]
public IActionResult Delete(ChatMessageInput input)
{
var msg = Db.Get<ChatMessage>(input.Id.Value);

if (msg != null && msg.UserId == input.UserId)
{
Db.Remove(msg);
_chatHubContext.Clients.All.SendAsync("Remove", msg.Id);
}

return Json(new { });
}

[HttpPost]
public IActionResult SendMessage(ChatMessageInput input)
{
if (!ModelState.IsValid)
{
var errMsg = string.Join(", ", ModelState.Values
.SelectMany(v => v.Errors)
.Select(e => e.ErrorMessage));

return Json(new { invalid = 1, errMsg });
}

ChatMessage msg;

var name = input.Name.Trim();
if (name.ToLower() == "awe")
{
name = "user";
}

// edit
if (input.Id.HasValue)
{
msg = Db.Get<ChatMessage>(input.Id.Value);

if (msg != null && msg.UserId == input.UserId)
{
msg.Content = input.Content;
}

_chatHubContext.Clients.All.SendAsync("Edit", msg.Id);
return Json(new { });
}

msg = Db.Add(new ChatMessage
{
Content = input.Content,
UserName = name,
UserId = input.UserId
});

Db.ChatMessages
.Where(o => o.UserId == input.UserId && o.UserName != name)
.ToList()
.ForEach(o => o.UserName = name);

_chatHubContext.Clients.All.SendAsync("Reload");

return Json(new { });
}

private object map(ChatMessage o, bool canEdit = false)
{
return new
{
o.Id,
o.UserName,
o.Content,
o.DateCreated,
canEdit
};
}

public IActionResult ChatMessagesGrid(GridParams g, string userId, bool lastPage = false)
{
var query = Db.ChatMessages.AsQueryable();

var gmb = new GridModelBuilder<ChatMessage>(g)
{
KeyProp = o => o.Id,
Map = o => map(o, o.UserId == userId)
};

// apply OrderBy according to GridParams
query = gmb.OrderBy(query);

// g.Key is set when calling api.update(id);
if (g.Key != null)
{
var item = Db.Find<ChatMessage>(Convert.ToInt32(g.Key));
gmb.GetItem = () => item;
}
else
{
var count = query.Count();
gmb.ItemsCount = count;

if (lastPage)
{
var pageCount = (int)Math.Ceiling((float)count / g.PageSize);
g.Page = pageCount;
}

gmb.PageItems = gmb.GetPage(query).ToArray();
}

return Json(gmb.Build());
}
}



Comments