public static async Task<ChatContextVM> ListChatRooms(string uId)
 {
     UserGroupServiceProxy gsvc = new UserGroupServiceProxy();
     var m = new ChatContextVM();
     var cntx = Cntx;
     QueryExpresion qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "GroupName" }
     });
     qexpr.FilterTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "GroupTypeID == " + ApplicationContext.ChatGroupTypeID + " && ParentID is null" }
     });
     m.TopRooms = new List<EntityAbs<UserGroup>>();
     var roots = await gsvc.QueryDatabaseAsync(cntx, new UserGroupSet(), qexpr);
     foreach (var r in roots)
     {
         var top = await gsvc.LoadEntityFullHierarchyRecursAsync(cntx, r);
         if (top != null)
             m.TopRooms.Add(top);
     }
     UserGroupMemberServiceProxy uigsvc = new UserGroupMemberServiceProxy();
     qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "UserID" }
     });
     qexpr.FilterTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "UserGroupRef.GroupTypeID == " + ApplicationContext.ChatGroupTypeID + " && UserID == \"" + uId + "\""  }
     });
     var recs = await uigsvc.QueryDatabaseAsync(cntx, new UserGroupMemberSet(), qexpr);
     if (recs.Count() > 0)
         m.MemberIds = (from d in recs select d.UserGroupID).ToArray();
     else
         m.MemberIds = new string[] { };
     return m;
 }
 public static async Task<string[]> UserGroupChatMembers(string userId)
 {
     var svc = new UserGroupMemberServiceProxy();
     var qexpr = new QueryExpresion();
     qexpr.FilterTks = new List<QToken>(new QToken[] {
         new QToken { TkName = "UserID == \"" + userId + "\" && UserGroupRef.GroupTypeID == " + ApplicationContext.ChatGroupTypeID }
     });
     var gl = await svc.QueryDatabaseAsync(Cntx, new UserGroupMemberSet(), qexpr);
     return gl == null ? null : (from d in gl select d.UserGroupID).ToArray();
 }
 public static async Task<UserGroup[]> UserGroupChatGroups(string userId)
 {
     var svc = new UserGroupServiceProxy();
     var qexpr = new QueryExpresion();
     // check this
     qexpr.OrderTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "ID" },
         new QToken { TkName = "asc" }
     });
     qexpr.FilterTks = new List<QToken>(new QToken[] {
         new QToken { TkName = "GroupTypeID == " + ApplicationContext.ChatGroupTypeID + " && UserGroupMember.UserID == \"" + userId + "\"" }
     });
     var gl = await svc.QueryDatabaseAsync(Cntx, new UserGroupSet(), qexpr);
     return gl == null ? null : (from d in gl select d).ToArray();
 }
 private bool PollMessages(CallContext cntx, ulong lastId)
 {
     var msgsvc = new SignalRMessageServiceProxy();
     DateTime dt = DateTime.UtcNow.AddHours(-config.TimeWindowInHours);
     QueryExpresion qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "ID" },
         new QToken { TkName = "desc" }
     });
     qexpr.FilterTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "ApplicationID == \"" + config.App.ID + "\" && ID > " + lastId + " && TimeStamp > " + dt.Ticks }
     });
     var msgs = msgsvc.QueryDatabaseLimited(cntx, new SignalRMessageSet(), qexpr, config.MaxBacklogMessages).ToArray();
     if (msgs.Length > 0)
     {
         LastMessageId = (ulong)msgs[0].ID;
         IsLastMessageIdChanged = true;
         foreach (var e in from d in msgs orderby d.ID ascending select d)
         {
             var smsg = ScaleoutMessage.FromBytes(e.MesssageData);
             forwardMessage((ulong)e.ID, smsg);
         }
     }
     return msgs.Length > 0;
 }
 public static async Task<List<MemberNotificationType>> GetRecentCategorized(string userId, SimpleMessage[] msgs, int? typeId, int max)
 {
     var cntx = Cntx;
     MembershipPlusServiceProxy svc = new MembershipPlusServiceProxy();
     MemberNotificationTypeServiceProxy tsvc = new MemberNotificationTypeServiceProxy();
     MemberNotificationServiceProxy nsvc = new MemberNotificationServiceProxy();
     var categs = await tsvc.QueryDatabaseAsync(cntx, new MemberNotificationTypeSet(), null);
     List<MemberNotificationType> tlist = new List<MemberNotificationType>();
     DateTime dt = DateTime.UtcNow.AddDays(-1);
     foreach (var categ in categs)
     {
         if (typeId.HasValue && categ.ID != typeId.Value)
             continue;
         var cond = new MemberNotificationSetConstraints
         {
             ApplicationIDWrap = new ForeignKeyData<string> { KeyValue = AppId },
             UserIDWrap = new ForeignKeyData<string> { KeyValue = userId },
             TypeIDWrap = new ForeignKeyData<int> { KeyValue = categ.ID }
         };
         QueryExpresion qexpr = new QueryExpresion();
         qexpr.OrderTks = new List<QToken>(new QToken[] { 
             new QToken { TkName = "PriorityLevel" },
             new QToken { TkName = "desc" },
             new QToken { TkName = "CreatedDate" },
             new QToken { TkName = "desc" }
         });
         qexpr.FilterTks = new List<QToken>(new QToken[] { 
             new QToken { TkName = "ReadCount == 0 && CreatedDate >= " + svc.FormatRepoDateTime(dt) }
         });
         foreach (var msg in msgs)
         {
             qexpr.FilterTks.Add(new QToken
             {
                 TkName = " && ID != \"" + msg.Id + "\""
             });
         }
         var list = (await nsvc.ConstraintQueryLimitedAsync(cntx, new MemberNotificationSet(), cond, qexpr, max)).ToList();
         if (list.Count > 0)
         {
             categ.ChangedMemberNotifications = list.ToArray();
             tlist.Add(categ);
         }
     }
     return tlist;
 }
        public static async Task<string[]> LoadMessages(string peerId, string userId, int maxMessages, bool dialog)
        {
            var svc = new MembershipPlusServiceProxy();
            var usvc = new UserServiceProxy();
            var msgsvc = new ShortMessageServiceProxy();
            var cntx = Cntx;
            var peer = await usvc.LoadEntityByKeyAsync(cntx, peerId);
            DateTime dt = DateTime.UtcNow.AddMinutes(-InitMsgTimeWindow);
            var cond = new ShortMessageSetConstraints
            {
                ApplicationIDWrap = new ForeignKeyData<string> { KeyValue = AppId },
                TypeIDWrap = new ForeignKeyData<int> { KeyValue = 1 },
                GroupIDWrap = new ForeignKeyData<string> { KeyValue = null }
            };
            var qexpr = new QueryExpresion();
            qexpr.OrderTks = new List<QToken>(new QToken[] { 
                new QToken { TkName = "CreatedDate" },
                new QToken { TkName = "desc" }
            });
            //                ToIDWrap = new ForeignKeyData<string> { KeyValue = peerId },

            qexpr.FilterTks = new List<QToken>(new QToken[] {
                new QToken { TkName = "( FromID ==  \"" + peerId + "\" && ToID == \"" + userId + "\" || FromID ==  \"" + userId + "\" && ToID == \"" + peerId + "\" ) && CreatedDate > " + svc.FormatRepoDateTime(dt) }
            });
            if (dialog)
            {
                qexpr.FilterTks.Add(new QToken { TkName = " && ReplyToID is null" });
            }
            var msgs = (await msgsvc.ConstraintQueryLimitedAsync(cntx, new ShortMessageSet(), cond, qexpr, maxMessages)).ToArray();
            List<string> jsonMsgs = new List<string>();
            if (msgs.Length > 0)
            {
                for (int i = msgs.Length - 1; i >= 0; i--)
                {
                    EntitySetType[] excludes;
                    if (dialog)
                    {
                        excludes = new EntitySetType[]
                                {
                                    EntitySetType.UserGroup,
                                    //EntitySetType.ShortMessageAudience,
                                    EntitySetType.ShortMessageAttachment
                                };
                    }
                    else
                    {
                        excludes = new EntitySetType[]
                                {
                                    EntitySetType.UserGroup,
                                    //EntitySetType.ShortMessageAudience,
                                    EntitySetType.ShortMessageAttachment,
                                    EntitySetType.ShortMessage
                                };
                    }
                    msgs[i] = await msgsvc.LoadEntityGraphRecursAsync(cntx, msgs[i].ID, excludes, null);
                    jsonMsgs.Add(GetJsonMessage(msgs[i], userId, peer, dialog));
                }
            }
            return jsonMsgs.ToArray();
        }
 public static async Task<MemberCallback> FindPeer(string chatHubId, string userId, string peerId)
 {
     var cntx = Cntx;
     MembershipPlusServiceProxy svc = new MembershipPlusServiceProxy();
     DateTime dt = DateTime.UtcNow.AddMinutes(-ApplicationContext.OnlineUserInactiveTime);
     MemberCallbackServiceProxy mcbsvc = new MemberCallbackServiceProxy();
     var qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "UserID" },
         new QToken { TkName = "asc" }
     });
     qexpr.FilterTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "HubID == \"" + chatHubId + "\" && ChannelID == \"" + userId + "\" && ConnectionID is not null && IsDisconnected == false" },
         new QToken { TkName = "&&" },
         new QToken { TkName = "ApplicationID == \"" + AppId + "\" && UserID == \"" + peerId + "\"" },
         new QToken { TkName = "&&" },
         new QToken { TkName = "UserAppMemberRef.LastActivityDate > " + svc.FormatRepoDateTime(dt) }
     });
     MemberCallbackServiceProxy cbsv = new MemberCallbackServiceProxy();
     return (await cbsv.QueryDatabaseAsync(cntx, new MemberCallbackSet(), qexpr)).SingleOrDefault();
 }
 public static async Task<PeerShotMessage> UpdateUserMessage(string chatHubId, string userId, string peerId, string msgId, string message)
 {
     var cntx = Cntx;
     UserServiceProxy usvc = new UserServiceProxy();
     var u = await usvc.LoadEntityByKeyAsync(cntx, userId);
     var peer = await usvc.LoadEntityByKeyAsync(cntx, peerId);
     ShortMessageServiceProxy msvc = new ShortMessageServiceProxy();
     PeerShotMessage m = new PeerShotMessage();
     ShortMessage msg = await msvc.LoadEntityByKeyAsync(cntx, msgId);
     if (msg == null || msg.FromID != userId || msg.ToID != peerId)
         return null;
     var now = DateTime.UtcNow;
     msg.MsgText = message;
     msg.LastModified = now;
     var r = await msvc.AddOrUpdateEntitiesAsync(cntx, new ShortMessageSet(), new ShortMessage[] { msg });
     var _msg = r.ChangedEntities[0].UpdatedItem;
     _msg.User_FromID = u;
     m.msg = GetJsonMessage(_msg, userId, peer, false);
     UserAssociationServiceProxy uasvc = new UserAssociationServiceProxy();
     var utop = await uasvc.LoadEntityByKeyAsync(cntx, userId, peerId, ApplicationContext.ChatAssocTypeId);
     if (utop != null)
     {
         utop.InteractCount = utop.InteractCount == null ? 1 : utop.InteractCount + 1;
         utop.LastInteract = DateTime.UtcNow;
         await uasvc.AddOrUpdateEntitiesAsync(cntx, new UserAssociationSet(), new UserAssociation[] { utop });
     }
     MembershipPlusServiceProxy svc = new MembershipPlusServiceProxy();
     DateTime dt = DateTime.UtcNow.AddMinutes(-ApplicationContext.OnlineUserInactiveTime);
     MemberCallbackServiceProxy mcbsvc = new MemberCallbackServiceProxy();
     var qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "UserID" },
         new QToken { TkName = "asc" }
     });
     qexpr.FilterTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "HubID == \"" + chatHubId + "\" && ChannelID == \"" + userId + "\" && ConnectionID is not null && IsDisconnected == false" },
         new QToken { TkName = "&&" },
         new QToken { TkName = "ApplicationID == \"" + AppId + "\" && UserID == \"" + peerId + "\"" },
         new QToken { TkName = "&&" },
         new QToken { TkName = "UserAppMemberRef.LastActivityDate > " + svc.FormatRepoDateTime(dt) }
     });
     MemberCallbackServiceProxy cbsv = new MemberCallbackServiceProxy();
     m.peer = (await cbsv.QueryDatabaseAsync(cntx, new MemberCallbackSet(), qexpr)).SingleOrDefault();
     return m;
 }
 public static async Task<UserDetailsVM> GetUserDetails(string id, bool direct = false)
 {
     UserDetailServiceProxy udsvc = new UserDetailServiceProxy();
     var cntx = Cntx;
     cntx.DirectDataAccess = direct;
     var details = await udsvc.LoadEntityByKeyAsync(cntx, ApplicationContext.App.ID, id);
     UserDetailsVM m = null;
     if (details != null)
     {
         if (!details.IsDescriptionLoaded)
         {
             details.Description = udsvc.LoadEntityDescription(cntx, ApplicationContext.App.ID, id);
             details.IsDescriptionLoaded = true;
         }
         m = new UserDetailsVM { Details = details };
         m.IsPhotoAvailable = !string.IsNullOrEmpty(details.PhotoMime);
     }
     else
     {
         m = new UserDetailsVM();
         m.IsPhotoAvailable = false;
     }
     UserDetailSet uds = new UserDetailSet();
     m.Genders = uds.GenderValues;
     QueryExpresion qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "ID" },
         new QToken { TkName = "asc" }
     });
     CommunicationTypeServiceProxy ctsvc = new CommunicationTypeServiceProxy();
     var lct = await ctsvc.QueryDatabaseAsync(Cntx, new CommunicationTypeSet(), qexpr);
     m.ChannelTypes = lct.ToArray();
     CommunicationServiceProxy csvc = new CommunicationServiceProxy();
     //qexpr = new QueryExpresion();
     //qexpr.OrderTks = new List<QToken>(new QToken[] { 
     //    new QToken { TkName = "TypeID" },
     //    new QToken { TkName = "asc" }
     //});
     //qexpr.FilterTks = new List<QToken>(new QToken[] { 
     //    new QToken { TkName = "UserID" },
     //    new QToken { TkName = "==" },
     //    new QToken { TkName = "\"" + id + "\"" },
     //    new QToken { TkName = "&&" },
     //    new QToken { TkName = "ApplicationID" },
     //    new QToken { TkName = "==" },
     //    new QToken { TkName = "\"" + ApplicationContext.App.ID + "\"" }
     //});
     //var lc = await csvc.QueryDatabaseAsync(Cntx, new CommunicationSet(), qexpr);
     var fkeys = new CommunicationSetConstraints
     {
         ApplicationIDWrap = new ForeignKeyData<string> { KeyValue = ApplicationContext.App.ID },
         TypeIDWrap = null, // no restriction on types
         UserIDWrap = new ForeignKeyData<string> { KeyValue = id }
     };
     var lc = await csvc.ConstraintQueryAsync(Cntx, new CommunicationSet(), fkeys, null);
     foreach (var c in lc)
     {
         c.Comment = await csvc.LoadEntityCommentAsync(Cntx, c.ID);
         c.IsCommentLoaded = true;
         c.CommunicationTypeRef = await csvc.MaterializeCommunicationTypeRefAsync(Cntx, c);
         m.Channels.Add(new { id = c.ID, label = c.DistinctString, addr = c.AddressInfo, comment = c.Comment, typeId = c.CommunicationTypeRef.TypeName });
     }
     return m;
 }
 private static QueryExpresion getConnectedGroupMemberFilter(string hubId, string groupId, bool supervisor = false)
 {
     MembershipPlusServiceProxy svc = new MembershipPlusServiceProxy();
     DateTime dt = DateTime.UtcNow.AddMinutes(-ApplicationContext.OnlineUserInactiveTime);
     QueryExpresion qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "UserID" },
         new QToken { TkName = "asc" }
     });
     qexpr.FilterTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "HubID == \"" + hubId + "\" && ChannelID == \"" + groupId + "\" && ConnectionID is not null && IsDisconnected == false" + (!supervisor ? "" : " && SupervisorMode is not null && SupervisorMode == true") },
         new QToken { TkName = "&&" },
         new QToken { TkName = "ApplicationID == \"" + AppId + "\"" },
         new QToken { TkName = "&&" },
         new QToken { TkName = "UserAppMemberRef.UserRef.UserGroupMember.UserGroupID == \"" + groupId + "\"" },
         new QToken { TkName = "&&" },
         new QToken { TkName = "UserAppMemberRef.LastActivityDate > " + svc.FormatRepoDateTime(dt) }
     });
     return qexpr;
 }
 public static async Task<ShotMessageNotice> UpdateUserMessage(string noticeHubId, string chatHubId, string userId, string groupId, string msgId, string message)
 {
     var cntx = Cntx;
     UserGroupServiceProxy gsvc = new UserGroupServiceProxy();
     var g = await gsvc.LoadEntityByKeyAsync(cntx, groupId);
     ShortMessageServiceProxy msvc = new ShortMessageServiceProxy();
     var msg = await msvc.LoadEntityByKeyAsync(cntx, msgId);
     if (msg == null || msg.FromID != userId)
         return null;
     if (msg.MsgText == message)
         return null;
     var now = DateTime.UtcNow;
     msg.MsgTitle = GetLeadText(message);
     msg.MsgText = message;
     msg.LastModified = now;
     await msvc.AddOrUpdateEntitiesAsync(cntx, new ShortMessageSet(), new ShortMessage[] { msg });
     UserServiceProxy usvc = new UserServiceProxy();
     var u = await usvc.LoadEntityByKeyAsync(cntx, userId);
     msg.User_FromID = u;
     UserGroupMemberServiceProxy gmsvc = new UserGroupMemberServiceProxy();
     var cond = new UserGroupMemberSetConstraints
     {
         UserGroupIDWrap = new ForeignKeyData<string> { KeyValue = groupId }
     };
     var qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>(new QToken[] { new QToken { TkName = "UserID" } });
     qexpr.FilterTks = new List<QToken>(new QToken[] {
         new QToken 
         {
             TkName = "SubscribedTo is not null && SubscribedTo == true"
         }
     });
     var gmbs = await gmsvc.ConstraintQueryAsync(cntx, new UserGroupMemberSet(), cond, qexpr);
     List<MemberNotification> notices = new List<MemberNotification>();
     List<MemberCallback> noteCbks = new List<MemberCallback>();
     MemberCallbackServiceProxy mcbsvc = new MemberCallbackServiceProxy();
     string noticeMsg = "Group message by " + u.Username + " updated in " + g.DistinctString;
     MemberNotificationTypeServiceProxy ntsvc = new MemberNotificationTypeServiceProxy();
     var ntype = await ntsvc.LoadEntityByKeyAsync(cntx, ApplicationContext.NewMessageNoticeTypeId);
     foreach (var m in gmbs)
     {
         if (m.ActivityNotification.HasValue && m.ActivityNotification.Value)
         {
             var cb = await mcbsvc.LoadEntityByKeyAsync(cntx, groupId, noticeHubId, AppId, m.UserID);
             if (cb.ConnectionID != null && !cb.IsDisconnected)
             {
                 cb.UserAppMemberRef = await mcbsvc.MaterializeUserAppMemberRefAsync(cntx, cb);
                 noteCbks.Add(cb);
             }
         }
         notices.Add(new MemberNotification
         {
             ID = Guid.NewGuid().ToString(),
             Title = noticeMsg,
             CreatedDate = now,
             PriorityLevel = 0,
             ReadCount = 0,
             ApplicationID = AppId,
             TypeID = ApplicationContext.NewMessageNoticeTypeId,
             UserID = userId
         });
     }
     var peers = await ListConnectIds(chatHubId, groupId);
     List<ShortMessageAudience> laud = new List<ShortMessageAudience>();
     foreach (var peer in peers)
     {
         if (peer.UserID != userId)
         {
             var a = new ShortMessageAudience
             {
                 MsgID = msg.ID,
                 UserID = peer.UserID,
                 VoteCount = 0
             };
             laud.Add(a);
         }
     }
     if (laud.Count > 0)
     {
         ShortMessageAudienceServiceProxy audsvc = new ShortMessageAudienceServiceProxy();
         await audsvc.AddOrUpdateEntitiesAsync(cntx, new ShortMessageAudienceSet(), laud.ToArray());
     }
     if (notices.Count > 0)
     {
         MemberNotificationServiceProxy nsvc = new MemberNotificationServiceProxy();
         await nsvc.AddOrUpdateEntitiesAsync(cntx, new MemberNotificationSet(), notices.ToArray());
     }
     return new ShotMessageNotice { msg = GetJsonMessage(msg, userId, g, false), brief = noticeMsg, categ = ntype, peers = peers, callbacks = noteCbks };
 }
 public static async Task<dynamic> Subscribe(string userId, string groupId)
 {
     var cntx = Cntx;
     UserGroupMemberServiceProxy uigsvc = new UserGroupMemberServiceProxy();
     var uig = await uigsvc.LoadEntityByKeyAsync(cntx, groupId, userId);
     if (uig != null && uig.SubscribedTo.HasValue && uig.SubscribedTo.Value)
         return new { ok = false, msg = ResourceUtils.GetString("73cca337310dc88725934ac22120ffaf", "You are already a subscriber!") };
     QueryExpresion qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>();
     qexpr.OrderTks.Add(new QToken { TkName = "UserGroupID" });
     qexpr.FilterTks = new List<QToken>();
     qexpr.FilterTks.Add(new QToken
     {
         TkName = "UserID == \"" + userId + "\" && SubscribedTo is not null && SubscribedTo == true"
     });
     var uigs = await uigsvc.QueryDatabaseAsync(cntx, new UserGroupMemberSet(), qexpr);
     if (uigs.Count() >= MaxSubscriptions)
     {
         return new
         {
             ok = false,
             msg = ResourceUtils.GetString("06200770094b57284bc7b16e0c7ea274", "You number of subscriptions exeeds the allowed limit, please unsubscribe from some of the existing ones first.")
         };
     }
     if (uig == null)
     {
         uig = new UserGroupMember
         {
             UserID = userId,
             UserGroupID = groupId,
             SubscribedTo = true,
             ActivityNotification = false
         };
     }
     else
         uig.SubscribedTo = true;
     await uigsvc.AddOrUpdateEntitiesAsync(cntx, new UserGroupMemberSet(), new UserGroupMember[] { uig });
     return new { ok = true, msg = "" };
 }
 public static async Task<ChatRoomVM> LoadChatRoom(string hubId, string groupId, string userId, int maxMessages, bool dialog = false)
 {
     UserGroupServiceProxy gsvc = new UserGroupServiceProxy();
     var cntx = Cntx;
     ChatRoomVM m = new ChatRoomVM() { RoomExists = false, DialogMode = dialog };
     if (!string.IsNullOrEmpty(groupId))
     {
         var g = await gsvc.LoadEntityByKeyAsync(cntx, groupId);
         if (g != null)
         {
             m.RoomExists = true;
             m.ID = groupId;
             m.RoomPath = g.DistinctString.Split('/');
             m.RoomInfo = await gsvc.LoadEntityGroupDescriptionAsync(cntx, g.ID);
             UserGroupMemberServiceProxy gmsvc = new UserGroupMemberServiceProxy();
             UserGroupMember uig = await gmsvc.LoadEntityByKeyAsync(cntx, groupId, userId);
             if (uig == null)
             {
                 uig = new UserGroupMember
                 {
                     UserID = userId,
                     UserGroupID = groupId,
                     SubscribedTo = false,
                     ActivityNotification = false
                 };
                 await gmsvc.AddOrUpdateEntitiesAsync(cntx, new UserGroupMemberSet(), new UserGroupMember[] { uig });
             }
             cntx.DirectDataAccess = true;
             MemberCallbackServiceProxy cbsv = new MemberCallbackServiceProxy();
             var qexpr = getConnectedGroupMemberFilter(hubId, g.ID);
             var peers = (await cbsv.QueryDatabaseAsync(cntx, new MemberCallbackSet(), qexpr)).ToArray();
             List<string> jsonPeers = new List<string>();
             if (peers.Length > 0)
             {
                 for (int i = 0; i < peers.Length; i++)
                 {
                     // retrieve the related entity graph
                     peers[i] = await cbsv.LoadEntityGraphRecursAsync(cntx, groupId, hubId, AppId, peers[i].UserID, null, null);
                     jsonPeers.Add(GetJsonPeer(peers[i]));
                 }
             }
             m.ActivePeers = jsonPeers.ToArray();
             cntx.DirectDataAccess = false;
             ShortMessageServiceProxy msgsvc = new ShortMessageServiceProxy();
             var cond = new ShortMessageSetConstraints
             {
                 ApplicationIDWrap = new ForeignKeyData<string> { KeyValue = AppId },
                 TypeIDWrap = new ForeignKeyData<int> { KeyValue = ApplicationContext.ChatShortMsgTypeId },
                 GroupIDWrap = new ForeignKeyData<string> { KeyValue = groupId }
             };
             UserGroupMemberServiceProxy uigsvc = new UserGroupMemberServiceProxy();
             qexpr = new QueryExpresion();
             qexpr.OrderTks = new List<QToken>(new QToken[] { 
                 new QToken { TkName = "UserID" }
             });
             qexpr.FilterTks = new List<QToken>(new QToken[] { 
                 new QToken { TkName = "UserGroupID == \"" + g.ID + "\" && SubscribedTo is not null && SubscribedTo == true"  }
             });
             m.Subscribers = (int)(await uigsvc.QueryEntityCountAsync(cntx, new UserGroupMemberSet(), qexpr));
             var svc = new MembershipPlusServiceProxy();
             DateTime dt = DateTime.UtcNow.AddMinutes(-InitMsgTimeWindow);
             qexpr = new QueryExpresion();
             qexpr.OrderTks = new List<QToken>(new QToken[] { 
                 new QToken { TkName = "CreatedDate" },
                 new QToken { TkName = "desc" }
             });
             qexpr.FilterTks = new List<QToken>(new QToken[] {
                 new QToken { TkName = "ToID is null && CreatedDate > " + svc.FormatRepoDateTime(dt) }
             });
             if (dialog)
             {
                 qexpr.FilterTks.Add(new QToken { TkName = " && ReplyToID is null" });
             }
             var msgs = (await msgsvc.ConstraintQueryLimitedAsync(cntx, new ShortMessageSet(), cond, qexpr, maxMessages)).ToArray();
             List<string> jsonMsgs = new List<string>();
             if (msgs.Length > 0)
             {
                 for (int i = msgs.Length - 1; i >= 0; i--)
                 {
                     EntitySetType[] excludes;
                     if (dialog)
                     {
                         excludes = new EntitySetType[]
                         {
                             EntitySetType.UserGroup,
                             //EntitySetType.ShortMessageAudience,
                             EntitySetType.ShortMessageAttachment
                         };
                     }
                     else
                     {
                         excludes = new EntitySetType[]
                         {
                             EntitySetType.UserGroup,
                             //EntitySetType.ShortMessageAudience,
                             EntitySetType.ShortMessageAttachment,
                             EntitySetType.ShortMessage
                         };
                     }
                     msgs[i] = await msgsvc.LoadEntityGraphRecursAsync(cntx, msgs[i].ID, excludes, null);
                     jsonMsgs.Add(GetJsonMessage(msgs[i], userId, g, dialog));
                 }
             }
             m.RecentMsgs = jsonMsgs.ToArray();
         }
     }
     return m;
 }
 public static async Task<dynamic> LoadRoomSummary(string hubId, string id)
 {
     UserGroupServiceProxy gsvc = new UserGroupServiceProxy();
     var cntx = Cntx;
     string descr = await gsvc.LoadEntityGroupDescriptionAsync(cntx, id);
     MemberCallbackServiceProxy mcbsvc = new MemberCallbackServiceProxy();
     var qexpr = getConnectedGroupMemberFilter(hubId, id);
     long cnt = await mcbsvc.QueryEntityCountAsync(cntx, new MemberCallbackSet(), qexpr);
     UserGroupMemberServiceProxy uigsvc = new UserGroupMemberServiceProxy();
     qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "UserID" }
     });
     qexpr.FilterTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "UserGroupID == \"" + id + "\" && SubscribedTo is not null && SubscribedTo == true"  }
     });
     long scnt = await uigsvc.QueryEntityCountAsync(cntx, new UserGroupMemberSet(), qexpr);
     qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "Username" }
     });
     qexpr.FilterTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "UsersInRole_UserID.RoleRef.UserGroupAdminRole.GroupID == \"" + id + "\"" }
     });
     UserServiceProxy usvc = new UserServiceProxy();
     var admins = await usvc.QueryDatabaseAsync(cntx, new UserSet(), qexpr);
     List<dynamic> ladms = new List<dynamic>();
     if (admins.Count() > 0)
     {
         RoleServiceProxy rsvc = new RoleServiceProxy();
         foreach (var u in admins)
         {
             qexpr = new QueryExpresion();
             qexpr.OrderTks = new List<QToken>(new QToken[] { 
                 new QToken { TkName = "ID" }
             });
             qexpr.FilterTks = new List<QToken>(new QToken[] { 
                 new QToken { TkName = "UserGroupAdminRole.GroupID == \"" + id + "\" && UsersInRole.UserID == \"" + u.ID + "\"" }
             });
             var role = (await rsvc.QueryDatabaseAsync(cntx, new RoleSet(), qexpr)).First();
             ladms.Add(new { id = u.ID, name = u.Username, role = role.DisplayName });
         }
     }
     dynamic r = new { descr = descr, active = cnt, subscribers = scnt, admins = ladms };
     return r;
 }
 public static async Task<MemberCallback> OnUserDisconnected(string hubId, string connectId)
 {
     if (string.IsNullOrEmpty(connectId))
         return null;
     var cntx = Cntx;
     MemberCallbackServiceProxy cbksvc = new MemberCallbackServiceProxy();
     QueryExpresion qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "UserID" },
         new QToken { TkName = "asc" }
     });
     qexpr.FilterTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "ApplicationID == \"" + AppId + "\" && HubID == \"" + hubId + "\" && ConnectionID == \"" + connectId + "\"" }
     });
     var cbk = (await cbksvc.QueryDatabaseAsync(cntx, new MemberCallbackSet(), qexpr)).FirstOrDefault();
     if (cbk != null)
     {
         // top level entity does not need to set 'StartAutoUpdating' since it is done by the proxy:
         // cbk.StartAutoUpdating = true; 
         cbk.ConnectionID = null;
         cbk.LastActiveDate = DateTime.UtcNow;
         cbk.IsDisconnected = true;
         await cbksvc.AddOrUpdateEntitiesAsync(cntx, new MemberCallbackSet(), new MemberCallback[] { cbk });
     }
     return cbk;
 }
 private void Subscribe()
 {
     if (_notifier != null)
     {
         _trace.TraceWarning("Callback channel is broken. Try to re-establish ... ");
         _notifier.Closed -= _delClosed;
         _notifier.Faulted -= _delClosed;
     }
     _notifier = new InstanceContext(this);
     _notifier.Closed += _delClosed;
     _notifier.Faulted += _delClosed;
     try
     {
         svc = new MembershipPlusDuplexServiceProxy(_notifier);
         var sub = new SetSubscription
         {
             EntityType = EntitySetType.SignalRMessage,
             EntityFilter = null
         };
         var qexpr = new QueryExpresion
         {
             FilterTks = new List<QToken>()
         };
         qexpr.FilterTks.Add(new QToken
         {
             TkName = "ApplicationID == \"" + config.App.ID + "\""
         });
         sub.EntityFilter = qexpr;
         var cntx = Cntx;
         svc.SubscribeToUpdates(cntx, cntx.CallerID, cntx.CallerID, new SetSubscription[] { sub });
         _trace.TraceWarning("Subscription done.");
         CallbackFailed = false;
     }
     catch
     {
         _trace.TraceWarning("Subscription failed.");
         CallbackFailed = true;
         // the data service is down ... wait and try again ...
     }
 }