simplifying basic chat notifications
This commit is contained in:
@ -8,9 +8,8 @@ namespace Yavsc
|
|||||||
public const string UserJoin = "userjoin";
|
public const string UserJoin = "userjoin";
|
||||||
public const string PrivateMessageDenied = "deniedpv";
|
public const string PrivateMessageDenied = "deniedpv";
|
||||||
public const string Error = "error";
|
public const string Error = "error";
|
||||||
public const string BookQuery = "bookQuery";
|
|
||||||
public const string ContactRefused = "contact refused";
|
public const string ContactRefused = "contact refused";
|
||||||
public const string ExistingUserName ="existing user name";
|
public const string ExistingUserName ="existing user name";
|
||||||
|
public const string ServerMessage = "server message";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -1,10 +1,10 @@
|
|||||||
//
|
//
|
||||||
// MyHub.cs
|
// ChatHub.cs
|
||||||
//
|
//
|
||||||
// Author:
|
// Author:
|
||||||
// Paul Schneider <paul@pschneider.fr>
|
// Paul Schneider <paul@pschneider.fr>
|
||||||
//
|
//
|
||||||
// Copyright (c) 2016 GNU GPL
|
// Copyright (c) 2016-2019 GNU GPL
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
@ -98,7 +98,7 @@ namespace Yavsc
|
|||||||
await Groups.Add(Context.ConnectionId, Constants.HubGroupAnonymous);
|
await Groups.Add(Context.ConnectionId, Constants.HubGroupAnonymous);
|
||||||
}
|
}
|
||||||
// TODO only notify followers
|
// TODO only notify followers
|
||||||
Clients.Group(Constants.HubGroupAuthenticated).notify(NotificationTypes.Connected, Context.ConnectionId, userName);
|
Clients.Group(Constants.HubGroupAuthenticated).notify(NotificationTypes.Connected, userName);
|
||||||
await base.OnConnected();
|
await base.OnConnected();
|
||||||
}
|
}
|
||||||
static ConcurrentDictionary<string, string> ChatUserNames
|
static ConcurrentDictionary<string, string> ChatUserNames
|
||||||
@ -113,8 +113,6 @@ namespace Yavsc
|
|||||||
return Context.User.Identity.Name;
|
return Context.User.Identity.Name;
|
||||||
}
|
}
|
||||||
anonymousSequence++;
|
anonymousSequence++;
|
||||||
var reqKeys = Context.Request.QueryString.Select(pv => pv.Key);
|
|
||||||
_logger.LogInformation(string.Join(" ", reqKeys));
|
|
||||||
|
|
||||||
var queryUname = Context.Request.QueryString[Constants.KeyParamChatUserName];
|
var queryUname = Context.Request.QueryString[Constants.KeyParamChatUserName];
|
||||||
|
|
||||||
@ -129,7 +127,7 @@ namespace Yavsc
|
|||||||
public override Task OnDisconnected(bool stopCalled)
|
public override Task OnDisconnected(bool stopCalled)
|
||||||
{
|
{
|
||||||
string userName = Context.User?.Identity.Name;
|
string userName = Context.User?.Identity.Name;
|
||||||
Clients.Group("authenticated").notify(NotificationTypes.DisConnected, Context.ConnectionId, userName);
|
Clients.Group("authenticated").notify(NotificationTypes.DisConnected, userName);
|
||||||
if (userName != null)
|
if (userName != null)
|
||||||
{
|
{
|
||||||
var cx = _dbContext.ChatConnection.SingleOrDefault(c => c.ConnectionId == Context.ConnectionId);
|
var cx = _dbContext.ChatConnection.SingleOrDefault(c => c.ConnectionId == Context.ConnectionId);
|
||||||
@ -139,6 +137,7 @@ namespace Yavsc
|
|||||||
{
|
{
|
||||||
var user = _dbContext.Users.Single(u => u.UserName == userName);
|
var user = _dbContext.Users.Single(u => u.UserName == userName);
|
||||||
user.Connections.Remove(cx);
|
user.Connections.Remove(cx);
|
||||||
|
ChatUserNames[Context.ConnectionId]=null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -175,7 +174,7 @@ namespace Yavsc
|
|||||||
Connected = true
|
Connected = true
|
||||||
});
|
});
|
||||||
_dbContext.SaveChanges();
|
_dbContext.SaveChanges();
|
||||||
Clients.Group("authenticated").notify(NotificationTypes.Reconnected, Context.ConnectionId, userName);
|
Clients.Group("authenticated").notify(NotificationTypes.Reconnected, userName);
|
||||||
}
|
}
|
||||||
return base.OnReconnected();
|
return base.OnReconnected();
|
||||||
}
|
}
|
||||||
@ -194,7 +193,7 @@ namespace Yavsc
|
|||||||
var candidate = "?"+nickName;
|
var candidate = "?"+nickName;
|
||||||
if (ChatUserNames.Any(u=> u.Value == candidate ))
|
if (ChatUserNames.Any(u=> u.Value == candidate ))
|
||||||
{
|
{
|
||||||
Clients.Caller.notify(NotificationTypes.ExistingUserName, "name already used:"+nickName);
|
Clients.Caller.notify(NotificationTypes.ExistingUserName, nickName);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
ChatUserNames[ Context.ConnectionId ] = "?"+nickName;
|
ChatUserNames[ Context.ConnectionId ] = "?"+nickName;
|
||||||
@ -228,7 +227,7 @@ namespace Yavsc
|
|||||||
Groups.Add(Context.ConnectionId, roomGroupName);
|
Groups.Add(Context.ConnectionId, roomGroupName);
|
||||||
}
|
}
|
||||||
Clients.Caller.joint(chanInfo);
|
Clients.Caller.joint(chanInfo);
|
||||||
Clients.Group("room_" + roomName).notify(NotificationTypes.UserJoin, Context.ConnectionId, Clients.Caller.UserName);
|
Clients.Group("room_" + roomName).notify(NotificationTypes.UserJoin, userName);
|
||||||
|
|
||||||
_logger.LogInformation("exiting ok.");
|
_logger.LogInformation("exiting ok.");
|
||||||
return chanInfo;
|
return chanInfo;
|
||||||
@ -312,7 +311,7 @@ namespace Yavsc
|
|||||||
Groups.Remove(Context.ConnectionId, roomGroupName);
|
Groups.Remove(Context.ConnectionId, roomGroupName);
|
||||||
var group = Clients.Group(roomGroupName);
|
var group = Clients.Group(roomGroupName);
|
||||||
var username = ChatUserNames[Context.ConnectionId];
|
var username = ChatUserNames[Context.ConnectionId];
|
||||||
group.notify(NotificationTypes.UserPart, Context.ConnectionId, new { username, reason });
|
group.notify( NotificationTypes.UserPart, $"{roomName} {username} ({reason})");
|
||||||
|
|
||||||
chanInfo.Users.Remove(Context.ConnectionId);
|
chanInfo.Users.Remove(Context.ConnectionId);
|
||||||
ChatRoomInfo deadchanInfo;
|
ChatRoomInfo deadchanInfo;
|
||||||
@ -326,10 +325,15 @@ namespace Yavsc
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Clients.Caller.notify(NotificationTypes.Error, "not joint");
|
NotifyNotJoint(roomName, "no such room");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NotifyNotJoint(string room, string reason)
|
||||||
|
{
|
||||||
|
Clients.Caller.notify(NotificationTypes.Error, $"{room} not joint: {reason}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Send(string roomName, string message)
|
public void Send(string roomName, string message)
|
||||||
{
|
{
|
||||||
@ -339,39 +343,52 @@ namespace Yavsc
|
|||||||
{
|
{
|
||||||
if (!chanInfo.Users.ContainsKey(Context.ConnectionId))
|
if (!chanInfo.Users.ContainsKey(Context.ConnectionId))
|
||||||
{
|
{
|
||||||
Clients.Caller.notify(NotificationTypes.Error, $"could not join channel ({roomName})");
|
var notSentMsg =$"could not send to channel ({roomName}) (not joint)";
|
||||||
|
Clients.Caller.notify(NotificationTypes.Error, notSentMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
string uname = ChatUserNames[Context.ConnectionId];
|
string uname = ChatUserNames[Context.ConnectionId];
|
||||||
Clients.Group(groupname).addMessage(uname, roomName, message);
|
Clients.Group(groupname).addMessage(uname, roomName, message);
|
||||||
|
_logger.LogInformation($"{uname} sent message {message} to {roomName}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Clients.Caller.notify(NotificationTypes.Error, $"could not join channel ({roomName})");
|
var noChanMsg = $"could not send to channel ({roomName}) (no such chan)";
|
||||||
|
Clients.Caller.notify(NotificationTypes.Error, noChanMsg);
|
||||||
|
_logger.LogWarning(noChanMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public void SendPV(string connectionId, string message)
|
public void SendPV(string userName, string message)
|
||||||
{
|
{
|
||||||
if (!Context.User.IsInRole(Constants.AdminGroupName))
|
if (string.IsNullOrWhiteSpace(userName))
|
||||||
{
|
return;
|
||||||
var bl = _dbContext.BlackListed
|
|
||||||
.Include(r => r.User)
|
|
||||||
.Where(r => r.User.UserName == Context.User.Identity.Name)
|
|
||||||
.Select(r => r.OwnerId);
|
|
||||||
|
|
||||||
if (bl != null) foreach (string uid in bl)
|
if (userName[0]!='?')
|
||||||
{
|
if (!Context.User.IsInRole(Constants.AdminGroupName))
|
||||||
if (_dbContext.ChatConnection.Any(cx => cx.ApplicationUserId == uid && cx.Connected))
|
{
|
||||||
Clients.Caller.notify(NotificationTypes.PrivateMessageDenied, connectionId);
|
var bl = _dbContext.BlackListed
|
||||||
return;
|
.Include(r => r.User)
|
||||||
}
|
.Include(r => r.Owner)
|
||||||
}
|
.Where(r => r.User.UserName == Context.User.Identity.Name && r.Owner.UserName == userName)
|
||||||
|
.Select(r => r.OwnerId);
|
||||||
|
|
||||||
|
if (bl.Count()>0)
|
||||||
|
{
|
||||||
|
Clients.Caller.notify(NotificationTypes.PrivateMessageDenied, userName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var cxIds = ChatUserNames.Where(name => name.Value == userName ).Select( name => name.Key );
|
||||||
|
|
||||||
|
foreach (var connectionId in cxIds)
|
||||||
|
{
|
||||||
var cli = Clients.Client(connectionId);
|
var cli = Clients.Client(connectionId);
|
||||||
cli.addPV(Context.User.Identity.Name, message);
|
cli.addPV(Context.User.Identity.Name, message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
|
@ -2,7 +2,7 @@ DESTDIR=/srv/www/yavscpre
|
|||||||
PRODDESTDIR=/srv/www/yavsc
|
PRODDESTDIR=/srv/www/yavsc
|
||||||
HOSTING=localhost
|
HOSTING=localhost
|
||||||
HOSTADMIN=root
|
HOSTADMIN=root
|
||||||
ASPNET_LOG_LEVEL=warn
|
ASPNET_LOG_LEVEL=debug
|
||||||
SOURCE_DIR=$(HOME)/workspace/yavsc
|
SOURCE_DIR=$(HOME)/workspace/yavsc
|
||||||
MAKEFILE_DIR=$(SOURCE_DIR)/scripts/build/make
|
MAKEFILE_DIR=$(SOURCE_DIR)/scripts/build/make
|
||||||
include $(MAKEFILE_DIR)/versioning.mk
|
include $(MAKEFILE_DIR)/versioning.mk
|
||||||
|
@ -493,5 +493,5 @@ Facture prévue (non réglée): {5}</value></data>
|
|||||||
Facture réglée: {5}</value></data>
|
Facture réglée: {5}</value></data>
|
||||||
|
|
||||||
<data name="AllowMonthlyEmail"><value>Recevoir la lettre mensuelle d'information</value></data>
|
<data name="AllowMonthlyEmail"><value>Recevoir la lettre mensuelle d'information</value></data>
|
||||||
|
<data name="Join"><value>joindre</value></data>
|
||||||
</root>
|
</root>
|
||||||
|
@ -110,7 +110,7 @@ namespace Yavsc.Services
|
|||||||
_logger.LogDebug($"Sending signal to {string.Join(" ",raa)} : "+JsonConvert.SerializeObject(ev));
|
_logger.LogDebug($"Sending signal to {string.Join(" ",raa)} : "+JsonConvert.SerializeObject(ev));
|
||||||
// we assume that each hub connected client will handle this signal
|
// we assume that each hub connected client will handle this signal
|
||||||
|
|
||||||
hubClient.notify(NotificationTypes.BookQuery,
|
hubClient.notify(NotificationTypes.ServerMessage,
|
||||||
$"# {ev.Sender} (un client) vous demande un rendez-vous\n"+body);
|
$"# {ev.Sender} (un client) vous demande un rendez-vous\n"+body);
|
||||||
|
|
||||||
result.message_id=MimeKit.Utils.MimeUtils.GenerateMessageId(
|
result.message_id=MimeKit.Utils.MimeUtils.GenerateMessageId(
|
||||||
|
@ -17,7 +17,7 @@ namespace Yavsc
|
|||||||
var webSocketOptions = new WebSocketOptions()
|
var webSocketOptions = new WebSocketOptions()
|
||||||
{
|
{
|
||||||
KeepAliveInterval = TimeSpan.FromSeconds(120),
|
KeepAliveInterval = TimeSpan.FromSeconds(120),
|
||||||
ReceiveBufferSize = 4 * 1024,
|
ReceiveBufferSize = 16 * 1024,
|
||||||
ReplaceFeature = true
|
ReplaceFeature = true
|
||||||
};
|
};
|
||||||
app.UseWebSockets(webSocketOptions);
|
app.UseWebSockets(webSocketOptions);
|
||||||
|
@ -168,9 +168,9 @@ a:hover {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
margin: 1em;
|
margin: 1em;
|
||||||
color: black;
|
color: #0d5175;
|
||||||
background-color: inherit;
|
background-color: inherit;
|
||||||
border: solid black 1px;
|
border: solid #306cc6 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#discussion {
|
#discussion {
|
||||||
@ -397,3 +397,17 @@ h6 {
|
|||||||
font-family: "Montserrat", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
font-family: "Montserrat", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
div.chatbar {
|
||||||
|
|
||||||
|
border-bottom: rgb(24, 24, 167) solid 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.roomlist {
|
||||||
|
display:inline-block;
|
||||||
|
|
||||||
|
}
|
||||||
|
div.chatctl {
|
||||||
|
float:right;
|
||||||
|
}
|
2
src/Yavsc/wwwroot/css/main/site.min.css
vendored
2
src/Yavsc/wwwroot/css/main/site.min.css
vendored
@ -1 +1 @@
|
|||||||
.discussion,.notif,.pv{font-family:monospace}#targets,.userinfo{display:block}.blog a:active,.blog a:hover,a:active,a:hover{outline:0}.blogphoto,.row img,main img{max-width:100%}.navbar-brand,.navbar-link,.navbar-nav .dropdown>a{background-color:rgba(0,0,0,.2);border-radius:2em}.navbar-brand:focus,.navbar-brand:hover,.navbar-link:focus,.navbar-link:hover{background-color:rgba(0,0,0,.4)}.ql-editor{border:1em outset #ee903e;padding:1em}.badge{margin:1em}.badge img{height:2em}.row img{max-height:6em}main img{max-height:100%}.userinfo{padding:.8em .8em .8em 2em;margin:.6em;background-repeat:no-repeat;background-attachment:local;background-size:contain;background-image:url(/images/lis.svg);overflow:auto}.performer{border-radius:1.5em;background-color:#f1e4f1;padding:1em}.performer ul{margin-left:2.5em}.smalltofhol{align-self:left;padding:.1em;border-radius:50%}.commentmeta{margin:.5em;padding:.5em;border-right:#444 dashed 1px;border-top:#444 solid 1px}.price,.total{font-weight:700;padding:.2em;margin:.2em}.price{font-size:large}.total{font-size:xx-large;background-color:#f8f;border:3px solid #000;border-radius:1em}.blog,.panel{padding:1em}.blog a{font-weight:900}.discussion{color:#000}.notif{color:#006}.pv{color:#251;font-style:bold}tr.visiblepost,tr.visiblepost img{max-height:3em}tr.hiddenpost{max-height:2em;background-color:#888;font-size:smaller}tr.hiddenpost img{max-height:3em}a.bloglink{font-weight:700;text-shadow:0 0 8px #000}a{font-weight:900}.panel{display:inline-block;margin:1em;color:#000;background-color:inherit;border:1px solid #000}#discussion{float:left}button,input,select,textarea{background-color:#bbb;color:#000}.jumbotron{padding:.5em}.carousel .item .carousel-caption-s{-webkit-transition:-webkit-transform 2s background-color 2s color 2s;-moz-transition:transform 2s background-color 2s color 2s;transition:transform 2s;transform:scale3d(0,0,0);-webkit-transform:scale3d(0,0,0)}.carousel .item.active .carousel-caption-s{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}.disabled{color:#999;background-color:#555}.smallphoto{max-height:4em}.carousel-caption-s p{-webkit-text-shadow:3px 3px 7px #000;animation:mymove 4s infinite;font-family:Arial;font-weight:800;font-size:x-large;text-shadow:3px 3px 7px #00003c;color:#fff;background-color:rgba(94,24,194,.15);border-radius:.5em}.carousel-caption-s{right:3em;top:1em;left:3em;z-index:10;padding-top:20px;padding-bottom:20px;text-align:center;min-height:16em;overflow:auto}.carousel-inner .item{padding-left:15%;padding-right:15%}.carousel-indicators{position:absolute;z-index:15;padding:0;text-align:center;list-style:none;top:.1em;height:1em}main.container{padding-right:1em;padding-left:1em;margin-left:1em;margin-right:1em}@media (max-width:767px){main.container{padding-right:.3em;padding-left:.3em;margin-left:.3em;margin-right:.3em}.carousel-caption-s p{margin:.2em;padding:.2em}}@-webkit-keyframes mymove{from,to{text-decoration-color:red}50%{text-decoration-color:#00f}}@keyframes mymove{from,to{text-decoration-color:red}50%{text-decoration-color:#00f}}ul.actiongroup li{display:inline}ul.actiongroup li a:hover{background-color:rgba(200,200,200,.6);color:#400}footer{vertical-align:bottom;padding:1.5em}.display-field{font-kerning:none;display:inline-flex;color:#008}.display-label{font-family:'Lucida Sans','Lucida Sans Regular','Lucida Grande','Lucida Sans Unicode',Geneva,Verdana,sans-serif;font-stretch:condensed;display:inline-flex;color:#ff8;padding:.1em;border-radius:.5em;background-color:#210912}footer{color:grey;font-weight:bolder;font-size:x-small}.meta{color:#444;font-style:italic;font-size:smaller}.activity{font-family:fantasy}.blogtitle{display:inline-block;font-size:x-large}.blogphoto{margin:1em;max-height:100%;image-orientation:from-image}body{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif}p{font-size:20px}p.small{font-size:16px}.smalltext{font-size:10px}h1,h2,h3,h4,h5,h6{font-family:Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:700}
|
.discussion,.notif,.pv{font-family:monospace}#targets,.userinfo{display:block}.blog a:active,.blog a:hover,a:active,a:hover{outline:0}.blogphoto,.row img,main img{max-width:100%}.navbar-brand,.navbar-link,.navbar-nav .dropdown>a{background-color:rgba(0,0,0,.2);border-radius:2em}.navbar-brand:focus,.navbar-brand:hover,.navbar-link:focus,.navbar-link:hover{background-color:rgba(0,0,0,.4)}.ql-editor{border:1em outset #ee903e;padding:1em}.badge{margin:1em}.badge img{height:2em}.row img{max-height:6em}main img{max-height:100%}.userinfo{padding:.8em .8em .8em 2em;margin:.6em;background-repeat:no-repeat;background-attachment:local;background-size:contain;background-image:url(/images/lis.svg);overflow:auto}.performer{border-radius:1.5em;background-color:#f1e4f1;padding:1em}.performer ul{margin-left:2.5em}.smalltofhol{align-self:left;padding:.1em;border-radius:50%}.commentmeta{margin:.5em;padding:.5em;border-right:#444 dashed 1px;border-top:#444 solid 1px}.price,.total{font-weight:700;padding:.2em;margin:.2em}.price{font-size:large}.total{font-size:xx-large;background-color:#f8f;border:3px solid #000;border-radius:1em}.blog,.panel{padding:1em}.blog a{font-weight:900}.discussion{color:#000}.notif{color:#006}.pv{color:#251;font-style:bold}tr.visiblepost,tr.visiblepost img{max-height:3em}tr.hiddenpost{max-height:2em;background-color:#888;font-size:smaller}tr.hiddenpost img{max-height:3em}a.bloglink{font-weight:700;text-shadow:0 0 8px #000}a{font-weight:900}.panel{display:inline-block;margin:1em;color:#0d5175;background-color:inherit;border:1px solid #306cc6}#discussion{float:left}button,input,select,textarea{background-color:#bbb;color:#000}.jumbotron{padding:.5em}.carousel .item .carousel-caption-s{-webkit-transition:-webkit-transform 2s background-color 2s color 2s;-moz-transition:transform 2s background-color 2s color 2s;transition:transform 2s;transform:scale3d(0,0,0);-webkit-transform:scale3d(0,0,0)}.carousel .item.active .carousel-caption-s{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}.disabled{color:#999;background-color:#555}.smallphoto{max-height:4em}.carousel-caption-s p{-webkit-text-shadow:3px 3px 7px #000;animation:mymove 4s infinite;font-family:Arial;font-weight:800;font-size:x-large;text-shadow:3px 3px 7px #00003c;color:#fff;background-color:rgba(94,24,194,.15);border-radius:.5em}.carousel-caption-s{right:3em;top:1em;left:3em;z-index:10;padding-top:20px;padding-bottom:20px;text-align:center;min-height:16em;overflow:auto}.carousel-inner .item{padding-left:15%;padding-right:15%}.carousel-indicators{position:absolute;z-index:15;padding:0;text-align:center;list-style:none;top:.1em;height:1em}main.container{padding-right:1em;padding-left:1em;margin-left:1em;margin-right:1em}@media (max-width:767px){main.container{padding-right:.3em;padding-left:.3em;margin-left:.3em;margin-right:.3em}.carousel-caption-s p{margin:.2em;padding:.2em}}@-webkit-keyframes mymove{from,to{text-decoration-color:red}50%{text-decoration-color:#00f}}@keyframes mymove{from,to{text-decoration-color:red}50%{text-decoration-color:#00f}}ul.actiongroup li{display:inline}ul.actiongroup li a:hover{background-color:rgba(200,200,200,.6);color:#400}footer{vertical-align:bottom;padding:1.5em}.display-field{font-kerning:none;display:inline-flex;color:#008}.display-label{font-family:'Lucida Sans','Lucida Sans Regular','Lucida Grande','Lucida Sans Unicode',Geneva,Verdana,sans-serif;font-stretch:condensed;display:inline-flex;color:#ff8;padding:.1em;border-radius:.5em;background-color:#210912}.blogtitle,div.roomlist{display:inline-block}footer{color:grey;font-weight:bolder;font-size:x-small}.meta{color:#444;font-style:italic;font-size:smaller}.activity{font-family:fantasy}.blogtitle{font-size:x-large}.blogphoto{margin:1em;max-height:100%;image-orientation:from-image}body{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif}p{font-size:20px}p.small{font-size:16px}.smalltext{font-size:10px}h1,h2,h3,h4,h5,h6{font-family:Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:700}div.chatbar{border-bottom:#1818a7 solid 2px}div.chatctl{float:right}
|
@ -27,17 +27,29 @@
|
|||||||
* btn btn-default
|
* btn btn-default
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
$.fn.filterByData = function (prop, val) {
|
||||||
|
return this.filter(
|
||||||
|
function () { return $(this).data(prop) == val; }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var ChatView = function ($view, full)
|
var ChatView = function ($view, full)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
if (!full) throw "not implemented";
|
if (!full) throw "not implemented";
|
||||||
|
|
||||||
// build a channel list
|
// build a channel list
|
||||||
var chans = Array();
|
var chans = Array();
|
||||||
|
var users = Array();
|
||||||
var frontRoomName;
|
var frontRoomName;
|
||||||
|
|
||||||
|
var ulist = $("<ul></ul>").addClass('userlist');
|
||||||
|
var notifications = $("<ul></ul>").addClass('notifs');
|
||||||
|
|
||||||
|
ulist.appendTo($view);
|
||||||
|
notifications.appendTo($view);
|
||||||
|
|
||||||
var chat = $.connection.chatHub
|
var chat = $.connection.chatHub
|
||||||
// Create a function that the hub can call back to display messages.
|
// Create a function that the hub can call back to display messages.
|
||||||
chat.client.addMessage = function (name, room, message) {
|
chat.client.addMessage = function (name, room, message) {
|
||||||
@ -54,32 +66,18 @@
|
|||||||
$('#pv_'+name).append('<li class="pv"><strong>' + htmlEncode(name)
|
$('#pv_'+name).append('<li class="pv"><strong>' + htmlEncode(name)
|
||||||
+ '</strong>: ' + htmlEncode(message) + '</li>')
|
+ '</strong>: ' + htmlEncode(message) + '</li>')
|
||||||
}
|
}
|
||||||
chat.client.notify = function (tag, message, data) {
|
chat.client.notify = function (tag, message) {
|
||||||
if (data) {
|
|
||||||
// Add the notification to the page.
|
// Add the notification to the page.
|
||||||
if (tag === 'connected') {
|
if (tag === 'connected' || tag === "reconnected") {
|
||||||
onUserConnected(ulist, message, data)
|
onUserConnected(message);
|
||||||
$('#notifications').append('<li class="notif"><i>' + htmlEncode(tag)
|
|
||||||
+ '</i> ' + htmlEncode(data) + '</li>')
|
|
||||||
}
|
}
|
||||||
else if (tag === 'disconnected') {
|
else if (tag === 'disconnected') {
|
||||||
onUserDisconnected(ulist, message, data)
|
onUserDisconnected(message)
|
||||||
$('#notifications').append('<li class="notif"><i>' + htmlEncode(tag)
|
|
||||||
+ '</i> ' + htmlEncode(data) + '</li>')
|
|
||||||
} // reconnected userpart userjoin deniedpv
|
} // reconnected userpart userjoin deniedpv
|
||||||
else {
|
$("<li></li>").append(tag+": ").append(message).addClass(tag).
|
||||||
$('#notifications').append('<li class="notif"><i>' + htmlEncode(tag)
|
appendTo(notifications);
|
||||||
+ '</i> ' + htmlEncode(message) + ' : <code>' + htmlEncode(data) + '</code></li>')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$.fn.filterByData = function (prop, val) {
|
|
||||||
return this.filter(
|
|
||||||
function () { return $(this).data(prop) == val; }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
var setActiveRoom = function(room) {
|
var setActiveRoom = function(room) {
|
||||||
var frontRoom;
|
var frontRoom;
|
||||||
if (frontRoomName!=='') {
|
if (frontRoomName!=='') {
|
||||||
@ -93,9 +91,19 @@
|
|||||||
$("#sel_"+room).removeClass("btn-primary");
|
$("#sel_"+room).removeClass("btn-primary");
|
||||||
frontRoom.removeClass("hidden");
|
frontRoom.removeClass("hidden");
|
||||||
}
|
}
|
||||||
|
var chatbar = $('<div class="chatbar"></div>');
|
||||||
|
|
||||||
|
var roomjoin = $('<div class="chatctl" class=\"form-control\"></div>');
|
||||||
|
|
||||||
var roomlist = $('<div class="roomlist"></div>');
|
var roomlist = $('<div class="roomlist"></div>');
|
||||||
roomlist.appendTo($view);
|
roomlist.appendTo(chatbar);
|
||||||
|
$("<label for=\"channame\">Join :</label>")
|
||||||
|
.appendTo(roomjoin);
|
||||||
|
var chanName = $("<input id=\"channame\" title=\"channel name\" hint=\"yavsc\" >");
|
||||||
|
chanName.appendTo(roomjoin);
|
||||||
|
roomjoin.appendTo(chatbar);
|
||||||
|
|
||||||
|
chatbar.appendTo($view);
|
||||||
var chatlist = $('<div class="chatlist" ></div>');
|
var chatlist = $('<div class="chatlist" ></div>');
|
||||||
chatlist.appendTo($view);
|
chatlist.appendTo($view);
|
||||||
|
|
||||||
@ -123,7 +131,7 @@
|
|||||||
.keydown(function(ev) {
|
.keydown(function(ev) {
|
||||||
if (ev.which == 13) {
|
if (ev.which == 13) {
|
||||||
if (this.value.length==0) return;
|
if (this.value.length==0) return;
|
||||||
console.log("sending to "+room+" "+this.value)
|
|
||||||
chat.server.send(room, this.value);
|
chat.server.send(room, this.value);
|
||||||
this.value="";
|
this.value="";
|
||||||
}}).appendTo(roomview);
|
}}).appendTo(roomview);
|
||||||
@ -144,7 +152,7 @@
|
|||||||
|
|
||||||
chans.forEach(function(room) {
|
chans.forEach(function(room) {
|
||||||
chat.server.join(room).done(function(chatInfo)
|
chat.server.join(room).done(function(chatInfo)
|
||||||
{console.log(chatInfo);
|
{
|
||||||
setActiveRoom(chatInfo.Name);
|
setActiveRoom(chatInfo.Name);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@ -170,20 +178,13 @@
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$("<label for=\"channame\">> </label>")
|
|
||||||
.appendTo($view);
|
|
||||||
var chanName = $("<input name=\"channame\" title=\"channel name\" hint=\"yavsc\">");
|
|
||||||
chanName.appendTo($view);
|
|
||||||
|
|
||||||
chanName.keydown(
|
chanName.keydown(
|
||||||
function (event) {
|
function (event) {
|
||||||
if (event.which == 13) {
|
if (event.which == 13) {
|
||||||
if (this.value.length==0) return;
|
if (this.value.length==0) return;
|
||||||
buildRoom(this.value);
|
buildRoom(this.value);
|
||||||
chat.server.join(this.value).done(function(chatInfo)
|
chat.server.join(this.value).done(function(chatInfo)
|
||||||
{console.log(chatInfo);
|
{
|
||||||
setActiveRoom(chatInfo.Name);
|
setActiveRoom(chatInfo.Name);
|
||||||
});
|
});
|
||||||
this.value=""
|
this.value=""
|
||||||
@ -192,10 +193,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var ulist = $("<ul></ul>").addClass('userlist');
|
|
||||||
|
|
||||||
ulist.appendTo($view);
|
|
||||||
|
|
||||||
|
|
||||||
var pvuis
|
var pvuis
|
||||||
// TODO get this data from the chatview element
|
// TODO get this data from the chatview element
|
||||||
@ -225,30 +222,25 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function addChatUser (ulist, uname, cxids) {
|
var addChatUser = function (uname) {
|
||||||
|
|
||||||
|
$("#u_"+uname).remove();
|
||||||
|
// ulist.remove("li.user[data='"+uname+"']");
|
||||||
|
|
||||||
$('<li class="user"><img src="/Avatars/' + uname + '.xs.png"> ' + uname + '</li>')
|
$('<li class="user"><img src="/Avatars/' + uname + '.xs.png"> ' + uname + '</li>')
|
||||||
.data('name', uname)
|
.prop('id', 'u_'+uname)
|
||||||
.data('cxids', cxids)
|
|
||||||
.css('cursor', 'pointer')
|
.css('cursor', 'pointer')
|
||||||
.click(function () { setPrivateTarget(this); })
|
.click(function () { setPrivateTarget(this); })
|
||||||
.appendTo(ulist)
|
.appendTo(ulist)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getUsers (ulist) {
|
var getUsers = function () {
|
||||||
$('#userlist').empty()
|
|
||||||
$('#to').empty()
|
|
||||||
$.get('/api/chat/users').done(
|
$.get('/api/chat/users').done(
|
||||||
function (users) {
|
function (users) {
|
||||||
$.each(users, function () {
|
$.each(users, function () {
|
||||||
var user = this
|
var user = this
|
||||||
var existent = $('#userlist li').filterByData('name', user.UserName)
|
addChatUser(user.UserName)
|
||||||
if (existent.length > 0) existent.remove()
|
|
||||||
var cxids = []
|
|
||||||
$.each(user.Connections, function () {
|
|
||||||
cxids.push(this.ConnectionId)
|
|
||||||
})
|
|
||||||
addChatUser(ulist,user.UserName, cxids)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -276,28 +268,13 @@
|
|||||||
$('#pubChan').css('cursor', 'pointer')
|
$('#pubChan').css('cursor', 'pointer')
|
||||||
$('#pubChan').click(setPublic)
|
$('#pubChan').click(setPublic)
|
||||||
setPublic()
|
setPublic()
|
||||||
// Reference the auto-generated proxy for the hub.
|
|
||||||
|
|
||||||
|
|
||||||
var onUserDisconnected = function (cxid) {
|
var onUserDisconnected = function (uname) {
|
||||||
$('#userlist li').filter(function () {
|
$("#u_"+uname).remove();
|
||||||
var nids = $(this).data('cxids').filter(function () {
|
|
||||||
return $(this) !== cxid
|
|
||||||
});
|
|
||||||
if (nids.length==0) $(this).remove()
|
|
||||||
else $(this).data('cxids', nids)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var onUserConnected = function (ulist, cxid, username) {
|
var onUserConnected = function (username) {
|
||||||
var connected = $('#userlist li').filterByData('name', username)
|
addChatUser(username)
|
||||||
if (connected.length > 0) {
|
|
||||||
var ids = connected.data('cxids')
|
|
||||||
ids.push(cxid)
|
|
||||||
connected.data('cxids', ids)
|
|
||||||
} else {
|
|
||||||
addChatUser(ulist, username, [cxid])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$(window).unload(function () { chat.server.abort(); })
|
$(window).unload(function () { chat.server.abort(); })
|
||||||
|
2
src/Yavsc/wwwroot/js/chat.min.js
vendored
2
src/Yavsc/wwwroot/js/chat.min.js
vendored
@ -1 +1 @@
|
|||||||
!function(y){var i=function(n,i){if(!i)throw"not implemented";var e,a=Array(),s=y.connection.chatHub;s.client.addMessage=function(n,i,e){y("#room_"+i).append('<li class="discussion"><strong>'+f(n)+"</strong>: "+f(e)+"</li>")},s.client.addPV=function(n,i){y("#mute").prop("checked")||h.play(),y("#pv_"+n).append('<li class="pv"><strong>'+f(n)+"</strong>: "+f(i)+"</li>")},s.client.notify=function(n,i,e){e&&("connected"===n?(g(p,i,e),y("#notifications").append('<li class="notif"><i>'+f(n)+"</i> "+f(e)+"</li>")):"disconnected"===n?(b(p,i,e),y("#notifications").append('<li class="notif"><i>'+f(n)+"</i> "+f(e)+"</li>")):y("#notifications").append('<li class="notif"><i>'+f(n)+"</i> "+f(i)+" : <code>"+f(e)+"</code></li>"))},y.fn.filterByData=function(n,i){return this.filter(function(){return y(this).data(n)==i})};var o=function(n){var i;""!==e&&((i=y("#vroom_"+e)).addClass("hidden"),y("#sel_"+e).addClass("btn-primary")),i=y("#vroom_"+(e=n)),y("#sel_"+n).removeClass("btn-primary"),i.removeClass("hidden")},c=y('<div class="roomlist"></div>');c.appendTo(n);var d=y('<div class="chatlist" ></div>');d.appendTo(n);var t=function(i){var n=y("<a>"+i+"</a>").addClass("btn");n.prop("id","sel_"+i).click(function(){o(i),y(this).removeClass("btn-primary")}),n.appendTo(c);var e=y("<div></div>").addClass("container");e.appendTo(d),e.prop("id","vroom_"+i);var t=y("<ul></ul>").addClass("mesglist");t.prop("id","room_"+i),t.appendTo(e),y('<input type="text">').prop("id","inp_"+i).prop("enable",!1).prop("hint","hello").prop("title","send to "+i).addClass("form-control").keydown(function(n){if(13==n.which){if(0==this.value.length)return;console.log("sending to "+i+" "+this.value),s.server.send(i,this.value),this.value=""}}).appendTo(e),a.push(i),o(i)};function r(){setTimeout(function(){var e;y("#userlist").empty(),y("#to").empty(),y.get("/api/chat/users").done(function(n){y.each(n,function(){var n=y("#userlist li").filterByData("name",this.UserName);0<n.length&&n.remove();var i=[];y.each(this.Connections,function(){i.push(this.ConnectionId)}),v(e,this.UserName,i)})})},120),y("#chatview").removeClass("disabled"),a.forEach(function(n){s.server.join(n).done(function(n){console.log(n),o(n.Name)})})}n.data("chans").split(",").forEach(function(n){t(n)}),y.connection.hub.start().done(function(){r()}),y.connection.hub.disconnected(function(){y("#chatview").addClass("disabled"),setTimeout(function(){y.connection.hub.start().done(function(){r()},3e4)})}),y('<label for="channame">> </label>').appendTo(n);var l=y('<input name="channame" title="channel name" hint="yavsc">');l.appendTo(n),l.keydown(function(n){if(13==n.which){if(0==this.value.length)return;t(this.value),s.server.join(this.value).done(function(n){console.log(n),o(n.Name)}),this.value=""}});var u,p=y("<ul></ul>").addClass("userlist");p.appendTo(n);var h=new Audio("/sounds/bell.mp3");function v(n,i,e){y('<li class="user"><img src="/Avatars/'+i+'.xs.png"> '+i+"</li>").data("name",i).data("cxids",e).css("cursor","pointer").click(function(){m(this)}).appendTo(n)}function f(n){return y("<div />").text(n).html()}y("#pv").keydown(function(n){var i;13==n.which&&(i=y("#pv").val(),y.each(u.CXs,function(){s.server.sendPV(this,i)}),y("#discussion").append('<li class="pv">'+f(u.UserName)+"<< "+f(i)+"</li>"),y("#pv").val(""))}),y("#command").keydown(function(n){13==n.which&&sendCommand()});var m=function(n){y("#rooms").addClass("hidden"),y("#sendpvbox").removeClass("hidden"),u={CXs:y(n).data("cxids"),UserName:y(n).data("name")},y("#sendpvdest").html(u.UserName),y("#pvs").focus()},C=function(){y("#rooms").removeClass("hidden"),y("#sendpvbox").addClass("hidden"),y("#message").focus()};y("#pubChan").css("cursor","pointer"),y("#pubChan").click(C),C();var b=function(i){y("#userlist li").filter(function(){var n=y(this).data("cxids").filter(function(){return y(this)!==i});0==n.length?y(this).remove():y(this).data("cxids",n)})},g=function(n,i,e){var t=y("#userlist li").filterByData("name",e);if(0<t.length){var a=t.data("cxids");a.push(i),t.data("cxids",a)}else v(n,e,[i])};y(window).unload(function(){s.server.abort()})};y(document).ready(function(n){i(n("#chatview"),!0)})}(jQuery);
|
!function(k){k.fn.filterByData=function(n,e){return this.filter(function(){return k(this).data(n)==e})};var e=function(n,e){if(!e)throw"not implemented";var a,i=Array(),o=(Array(),k("<ul></ul>").addClass("userlist")),s=k("<ul></ul>").addClass("notifs");o.appendTo(n),s.appendTo(n);var t=k.connection.chatHub;t.client.addMessage=function(n,e,a){k("#room_"+e).append('<li class="discussion"><strong>'+y(n)+"</strong>: "+y(a)+"</li>")},t.client.addPV=function(n,e){k("#mute").prop("checked")||m.play(),k("#pv_"+n).append('<li class="pv"><strong>'+y(n)+"</strong>: "+y(e)+"</li>")},t.client.notify=function(n,e){"connected"===n||"reconnected"===n?g(e):"disconnected"===n&&_(e),k("<li></li>").append(n+": ").append(e).addClass(n).appendTo(s)};var d=function(n){var e;""!==a&&((e=k("#vroom_"+a)).addClass("hidden"),k("#sel_"+a).addClass("btn-primary")),e=k("#vroom_"+(a=n)),k("#sel_"+n).removeClass("btn-primary"),e.removeClass("hidden")},c=k('<div class="chatbar"></div>'),r=k('<div class="chatctl" class="form-control"></div>'),l=k('<div class="roomlist"></div>');l.appendTo(c),k('<label for="channame">Join :</label>').appendTo(r);var p=k('<input id="channame" title="channel name" hint="yavsc" >');p.appendTo(r),r.appendTo(c),c.appendTo(n);var u=k('<div class="chatlist" ></div>');u.appendTo(n);var v,h=function(e){var n=k("<a>"+e+"</a>").addClass("btn");n.prop("id","sel_"+e).click(function(){d(e),k(this).removeClass("btn-primary")}),n.appendTo(l);var a=k("<div></div>").addClass("container");a.appendTo(u),a.prop("id","vroom_"+e);var o=k("<ul></ul>").addClass("mesglist");o.prop("id","room_"+e),o.appendTo(a),k('<input type="text">').prop("id","inp_"+e).prop("enable",!1).prop("hint","hello").prop("title","send to "+e).addClass("form-control").keydown(function(n){if(13==n.which){if(0==this.value.length)return;t.server.send(e,this.value),this.value=""}}).appendTo(a),i.push(e),d(e)};function f(){setTimeout(function(){b()},120),k("#chatview").removeClass("disabled"),i.forEach(function(n){t.server.join(n).done(function(n){d(n.Name)})})}n.data("chans").split(",").forEach(function(n){h(n)}),k.connection.hub.start().done(function(){f()}),k.connection.hub.disconnected(function(){k("#chatview").addClass("disabled"),setTimeout(function(){k.connection.hub.start().done(function(){f()},3e4)})}),p.keydown(function(n){if(13==n.which){if(0==this.value.length)return;h(this.value),t.server.join(this.value).done(function(n){d(n.Name)}),this.value=""}});var m=new Audio("/sounds/bell.mp3");k("#pv").keydown(function(n){var e;13==n.which&&(e=k("#pv").val(),k.each(v.CXs,function(){t.server.sendPV(this,e)}),k("#discussion").append('<li class="pv">'+y(v.UserName)+"<< "+y(e)+"</li>"),k("#pv").val(""))}),k("#command").keydown(function(n){13==n.which&&sendCommand()});var C=function(n){k("#u_"+n).remove(),k('<li class="user"><img src="/Avatars/'+n+'.xs.png"> '+n+"</li>").prop("id","u_"+n).css("cursor","pointer").click(function(){T(this)}).appendTo(o)},b=function(){k.get("/api/chat/users").done(function(n){k.each(n,function(){C(this.UserName)})})};function y(n){return k("<div />").text(n).html()}var T=function(n){k("#rooms").addClass("hidden"),k("#sendpvbox").removeClass("hidden"),v={CXs:k(n).data("cxids"),UserName:k(n).data("name")},k("#sendpvdest").html(v.UserName),k("#pvs").focus()},w=function(){k("#rooms").removeClass("hidden"),k("#sendpvbox").addClass("hidden"),k("#message").focus()};k("#pubChan").css("cursor","pointer"),k("#pubChan").click(w),w();var _=function(n){k("#u_"+n).remove()},g=function(n){C(n)};k(window).unload(function(){t.server.abort()})};k(document).ready(function(n){e(n("#chatview"),!0)})}(jQuery);
|
Reference in New Issue
Block a user