Line 1: ' Line 2: ' DotNetNuke® - http://www.dotnetnuke.com Line 3: ' Copyright (c) 2002-2006 Line 4: ' by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca ) Line 5: ' Line 6: ' Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated Line 7: ' documentation files (the "Software"), to deal in the Software without restriction, including without limitation Line 8: ' the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and Line 9: ' to permit persons to whom the Software is furnished to do so, subject to the following conditions: Line 10: ' Line 11: ' The above copyright notice and this permission notice shall be included in all copies or substantial portions Line 12: ' of the Software. Line 13: ' Line 14: ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED Line 15: ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL Line 16: ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF Line 17: ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER Line 18: ' DEALINGS IN THE SOFTWARE. Line 19: ' Line 20: Line 21: Imports System Line 22: Imports System.ComponentModel Line 23: Imports System.Text Line 24: Imports System.Web Line 25: Imports System.Web.UI Line 26: Imports System.Web.UI.WebControls Line 27: Imports System.Web.UI.HtmlControls Line 28: Line 29: Imports DotNetNuke.Entities.Modules Line 30: Imports DotNetNuke.UI.Utilities Line 31: Line 32: Namespace DotNetNuke.Modules.Chat Line 33: Public Enum MessageType Line 34: UNDEFINED = 0 Line 35: ENTER = 1 Line 36: LEAVE = 2 Line 37: CHAT = 3 Line 38: POLL = 4 Line 39: End Enum Line 40: Line 41: <DefaultProperty("Text"), ToolboxData("<{0}:DnnChat runat=server></{0}:DnnChat>")> _ Line 42: Public Class DnnChat Line 43: Inherits WebControl Line 44: Implements INamingContainer, DotNetNuke.UI.Utilities.IClientAPICallbackEventHandler 'System.Web.UI.ICallbackEventHandler, Line 45: Line 46: 'private variables Line 47: Private _Messages As DnnChatMessageCollection Line 48: Private _pnlMessages As Panel = New Panel Line 49: Private _pnlChat As Panel = New Panel Line 50: Private _txt As TextBox = New TextBox Line 51: Const _txtBoxHeight As Integer = 15 Line 52: Line 53: 'constructor Line 54: Public Sub New() Line 55: 'set default size Line 56: MyBase.Width = New Unit(350, UnitType.Pixel) Line 57: MyBase.Height = New Unit(200, UnitType.Pixel) Line 58: Line 59: End Sub Line 60: Line 61: #Region " Public Properties " Line 62: Line 63: ''' <summary> Line 64: ''' The number of chat messages will be cached in application state Line 65: ''' </summary> Line 66: ''' <remarks></remarks> Line 67: Private ReadOnly Property HistoryCapacity() As Integer Line 68: Get Line 69: Return GetSetting(Of Integer)("dnnChat_History", 50) Line 70: End Get Line 71: End Property Line 72: Line 73: ''' <summary> Line 74: ''' The number of chat messages will be cached in application state Line 75: ''' </summary> Line 76: ''' <remarks></remarks> Line 77: Private ReadOnly Property DisplayCapacity() As Integer Line 78: Get Line 79: Return GetSetting(Of Integer)("dnnChat_DisplayCapacity", 10) Line 80: End Get Line 81: End Property Line 82: Line 83: ''' <summary> Line 84: ''' The number of seconds between chat update requests Line 85: ''' </summary> Line 86: ''' <remarks></remarks> Line 87: Public ReadOnly Property PollingInterval() As Integer Line 88: Get Line 89: Return GetSetting(Of Integer)("dnnChat_PollingInterval", 2000) Line 90: End Get Line 91: End Property Line 92: Line 93: ''' <summary> Line 94: ''' The style of the message display area Line 95: ''' </summary> Line 96: ''' <remarks></remarks> Line 97: Private _MessageAreaStyle As Style Line 98: <Bindable(False), Category("Appearance"), Description("Sets or gets the style of the message display area"), _ Line 99: PersistenceMode(PersistenceMode.InnerProperty)> Public Property MessageAreaStyle() As Style Line 100: Get Line 101: Return _MessageAreaStyle Line 102: End Get Line 103: Set(ByVal value As Style) Line 104: _MessageAreaStyle = value Line 105: End Set Line 106: End Property Line 107: Line 108: ''' <summary> Line 109: ''' The style of the send message area Line 110: ''' </summary> Line 111: ''' <remarks></remarks> Line 112: Private _SendAreaStyle As Style Line 113: <Bindable(False), Category("Appearance"), Description("Sets or gets the style of the send message area"), PersistenceMode(PersistenceMode.InnerProperty)> _ Line 114: Public Property SendAreaStyle() As Style Line 115: Get Line 116: Return _SendAreaStyle Line 117: End Get Line 118: Set(ByVal value As Style) Line 119: _SendAreaStyle = value Line 120: End Set Line 121: End Property Line 122: Line 123: ''' <summary> Line 124: ''' The css class to apply to the sender of each message Line 125: ''' </summary> Line 126: ''' <remarks></remarks> Line 127: Public ReadOnly Property SenderCssClass() As String Line 128: Get Line 129: Return GetSetting(Of String)("dnnChat_SenderCssClass", "NormalBold") Line 130: End Get Line 131: End Property Line 132: Line 133: ''' <summary> Line 134: ''' The css class to apply to the body of each message Line 135: ''' </summary> Line 136: ''' <remarks></remarks> Line 137: Public ReadOnly Property MessageCssClass() As String Line 138: Get Line 139: Return GetSetting(Of String)("dnnChat_MessageCssClass", "Normal") Line 140: End Get Line 141: End Property Line 142: Line 143: Public ReadOnly Property ExitedMessage() As String Line 144: Get Line 145: Return GetSetting(Of String)("dnnChat_ExitedMessage", "NormalRed") Line 146: End Get Line 147: End Property Line 148: Line 149: ''' <summary> Line 150: ''' Sets or gets the message that is displayed when a user enters Line 151: ''' </summary> Line 152: Public ReadOnly Property EnteredMessage() As String Line 153: Get Line 154: Return GetSetting(Of String)("dnnChat_EnteredMessage", "NormalRed") Line 155: End Get Line 156: End Property Line 157: ''' <summary> Line 158: ''' Sets or gets the message that is displayed when a user enters Line 159: ''' </summary> Line 160: Public ReadOnly Property SenderText() As String Line 161: Get Line 162: Return GetSetting(Of String)("dnnChat_SenderText", Localization.GetString("SenderTextDefault.Text", ParentModule.LocalResourceFile)) Line 163: End Get Line 164: End Property Line 165: Line 166: Public ReadOnly Property AllowFormatting() As Boolean Line 167: Get Line 168: Return GetSetting(Of Boolean)("dnnChat_AllowFormatting", True) Line 169: End Get Line 170: End Property Line 171: #End Region Line 172: Line 173: #Region " Private Properties " Line 174: Private _rootImageUrl As String = String.Empty Line 175: Private ReadOnly Property ChatRootImageUrl() As String Line 176: Get Line 177: If _rootImageUrl.Length = 0 Then Line 178: _rootImageUrl = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + Me.ParentModule.TemplateSourceDirectory + "/Images/" Line 179: End If Line 180: Return _rootImageUrl Line 181: End Get Line 182: End Property Line 183: Line 184: Private _ParentModule As PortalModuleBase Line 185: Private ReadOnly Property ParentModule() As PortalModuleBase Line 186: Get Line 187: If _ParentModule Is Nothing Then Line 188: Dim CurrentControl As Control = Me Line 189: While CurrentControl IsNot Nothing AndAlso Not CurrentControl.Parent.Equals(CurrentControl) Line 190: If TypeOf CurrentControl Is PortalModuleBase Then Line 191: _ParentModule = CurrentControl Line 192: Exit While Line 193: Else Line 194: CurrentControl = CurrentControl.Parent Line 195: End If Line 196: End While Line 197: End If Line 198: Return _ParentModule Line 199: End Get Line 200: End Property Line 201: Private ReadOnly Property DnnChatSessionMessagesKey() As String Line 202: Get Line 203: Return String.Format("DnnChatSessionMessages_{0}", Me.ParentModule.ModuleId()) Line 204: End Get Line 205: End Property Line 206: Private ReadOnly Property DnnChatSessionMessageCountKey() As String Line 207: Get Line 208: Return String.Format("DnnChatSessionMessageCount_{0}_{1}", Me.ParentModule.ModuleId(), "MessageCount") Line 209: End Get Line 210: End Property Line 211: Private Property DnnChatSessionMessages() As DnnChatMessageCollection Line 212: Get Line 213: Dim retval As DnnChatMessageCollection Line 214: retval = DataCache.GetCache(DnnChatSessionMessagesKey) Line 215: If retval Is Nothing Then Line 216: retval = New DnnChatMessageCollection Line 217: Me.DnnChatSessionMessages = retval Line 218: End If Line 219: Line 220: Return retval Line 221: End Get Line 222: Set(ByVal value As DnnChatMessageCollection) Line 223: DataCache.SetCache(DnnChatSessionMessagesKey, value) Line 224: 'Web.HttpContext.Current.Cache.Insert(WebChatTopicMessagesKey, value) Line 225: End Set Line 226: End Property Line 227: Private Property DnnChatSessionLastMessageID() As Long Line 228: Get Line 229: Return DataCache.GetCache(DnnChatSessionMessageCountKey) Line 230: End Get Line 231: Set(ByVal value As Long) Line 232: DataCache.SetCache(DnnChatSessionMessageCountKey, value) Line 233: End Set Line 234: End Property Line 235: Private ReadOnly Property DnnChatUsersCacheKey() As String Line 236: Get Line 237: Return String.Format("DnnChatUsers_{0}", ParentModule.ModuleId) Line 238: End Get Line 239: End Property Line 240: Private _dnnChatUsers As Generic.Dictionary(Of Guid, DnnChatUser) = Nothing Line 241: Private Property DnnChatUsers() As Generic.Dictionary(Of Guid, DnnChatUser) Line 242: Get Line 243: 'Get from Cache only once per request Line 244: If _dnnChatUsers Is Nothing Then Line 245: _dnnChatUsers = CType(DataCache.GetCache(DnnChatUsersCacheKey), Generic.Dictionary(Of Guid, DnnChatUser)) Line 246: End If Line 247: 'If it's still nothing we need to put a new one into cache Line 248: If _dnnChatUsers Is Nothing Then Line 249: _dnnChatUsers = New Generic.Dictionary(Of Guid, DnnChatUser) Line 250: DataCache.SetCache(DnnChatUsersCacheKey, _dnnChatUsers) Line 251: End If Line 252: Line 253: Return _dnnChatUsers Line 254: End Get Line 255: Set(ByVal value As Generic.Dictionary(Of Guid, DnnChatUser)) Line 256: DataCache.SetCache(DnnChatUsersCacheKey, value) Line 257: End Set Line 258: End Property Line 259: #End Region Line 260: Line 261: #Region " HTML Rendering " Line 262: Protected Overrides Sub RenderContents(ByVal output As HtmlTextWriter) Line 263: Line 264: Dim lvstrPrefix As String = String.Format("{0}_{1}_", Me.ID, ParentModule.ModuleId) Line 265: Dim lvstrChatwindowPanelId As String = String.Format("{0}{1}", lvstrPrefix, "pnl") Line 266: Dim lvstrChatwindowButtonId As String = String.Format("{0}{1}", lvstrPrefix, "btn") Line 267: Dim lvstrChatwindowTextboxId As String = String.Format("{0}{1}", lvstrPrefix, "txt") Line 268: Line 269: Dim lvblnIsAllowedToChat As Boolean = Security.HasPermission(Security.GetPermissions(Me.ParentModule.ModuleId, Me.ParentModule.TabId), Security.Permissions.ChatPermission) Line 270: Line 271: Line 272: 'The context is used for passing through the name of the chatwindow Line 273: Dim strContext As String = String.Format("document.getElementById('{0}')", lvstrChatwindowPanelId) Line 274: Dim strCallback As String = DotNetNuke.UI.Utilities.ClientAPI.GetCallbackEventReference(Me, String.Format("getChatMessageXML({0})", lvstrChatwindowTextboxId), "receiveChatMessage", strContext, "receiveChatMessageError") ' String.Format("sendChatMessage(document.getElementById('{0}'));", _txt.ID) Line 275: Line 276: 'create the containing panel Line 277: 'this panel conatins the panel with the messages and a table for the user input controls Line 278: _pnlChat.Height = Me.Height Line 279: _pnlChat.Width = Me.Width Line 280: 'create the message display panel Line 281: _pnlMessages.ID = lvstrChatwindowPanelId Line 282: _pnlMessages.Height = New Unit(_pnlChat.Height.Value - ((New DnnChatFormattingToolbar).HeightInPixels) - _txtBoxHeight, UnitType.Pixel) Line 283: '_pnlMessages.BorderStyle = WebControls.BorderStyle.Solid Line 284: _pnlMessages.BorderWidth = New Unit(1, UnitType.Pixel) Line 285: _pnlMessages.Style.Add(HtmlTextWriterStyle.Overflow, "scroll") Line 286: _pnlMessages.ControlStyle.MergeWith(Me.MessageAreaStyle) Line 287: _pnlChat.Controls.Add(_pnlMessages) Line 288: Line 289: Line 290: 'create the button Line 291: Dim btn As Button = New Button Line 292: btn.ID = lvstrChatwindowButtonId Line 293: btn.UseSubmitBehavior = False Line 294: btn.Text = Localization.GetString("SendButton.Text", ParentModule.LocalResourceFile) Line 295: btn.Enabled = lvblnIsAllowedToChat Line 296: btn.Attributes("onClick") = strCallback Line 297: Line 298: 'create the textbox Line 299: _txt.ID = lvstrChatwindowTextboxId Line 300: _txt.Width = New Unit(99, UnitType.Percentage) Line 301: _txt.Enabled = lvblnIsAllowedToChat Line 302: 'This handles the Enter key Line 303: 'TODO: Use DotNetNuke.Utilities.ClientAPI Line 304: _txt.Attributes("onkeydown") = "if ((event.keyCode == 13)) {" & strCallback & ";return false;} else return true;" Line 305: Line 306: 'Create the table for the user input controls Line 307: Dim tbl As Table = New Table Line 308: tbl.Height = New Unit((_pnlChat.Height.Value - _pnlMessages.Height.Value), UnitType.Pixel) Line 309: tbl.Width = Me.Width Line 310: tbl.ToolTip = Me.ToolTip Line 311: Line 312: 'create a new table row for textbox & button Line 313: Dim tr As TableRow = New TableRow Line 314: Dim tdTextbox As TableCell = New TableCell Line 315: Dim tdButton As TableCell = New TableCell Line 316: tr.Height = New Unit(_txtBoxHeight, UnitType.Pixel) Line 317: tr.ControlStyle.MergeWith(Me.SendAreaStyle) Line 318: Line 319: tdTextbox.Width = New Unit(90, UnitType.Percentage) Line 320: tdTextbox.Controls.Add(_txt) Line 321: tr.Cells.Add(tdTextbox) Line 322: tdButton.HorizontalAlign = HorizontalAlign.Right Line 323: tdButton.Controls.Add(btn) Line 324: tr.Cells.Add(tdButton) Line 325: Line 326: tbl.Rows.Add(tr) Line 327: Line 328: Line 329: If Me.AllowFormatting Then msAddFormattingToolbar(tbl, lvstrChatwindowTextboxId, lvblnIsAllowedToChat) Line 330: Line 331: 'Shout around that someone has entered Line 332: strCallback = DotNetNuke.UI.Utilities.ClientAPI.GetCallbackEventReference(Me, _ Line 333: String.Format("getMessageXML('{0}', MSG_TYPE_ENTER)", getArrivalText(lvblnIsAllowedToChat)), _ Line 334: "receiveChatMessage", _ Line 335: strContext, _ Line 336: "receiveChatMessageError") Line 337: ClientAPI.RegisterStartUpScript(Me.Page, _ Line 338: "enterChat_" & ParentModule.ModuleId.ToString, _ Line 339: "<script>" & strCallback & "</script>" _ Line 340: ) Line 341: Line 342: 'Have the thing poll every now and then Line 343: strCallback = DotNetNuke.UI.Utilities.ClientAPI.GetCallbackEventReference(Me, _ Line 344: "getMessageXML(null, MSG_TYPE_POLL)", _ Line 345: "receiveChatMessage", _ Line 346: strContext, _ Line 347: "receiveChatMessageError") Line 348: Line 349: 'Remove the trailing semicolon Line 350: If strCallback.EndsWith(";") Then strCallback = strCallback.Remove(strCallback.LastIndexOf(";"c)) Line 351: Line 352: 'quote it Line 353: strCallback = """" & strCallback & """" Line 354: Line 355: Line 356: ClientAPI.RegisterStartUpScript(Me.Page, _ Line 357: "refreshChat_" & ParentModule.ModuleId.ToString, _ Line 358: "<script>window.setInterval(" & strCallback & "," & CType(Me.PollingInterval, String) & ");</script>" _ Line 359: ) Line 360: Line 361: _pnlChat.Controls.Add(tbl) Line 362: _pnlChat.RenderControl(output) Line 363: Line 364: End Sub Line 365: Private Sub msAddFormattingToolbar(ByRef pTable As Table, ByVal pChatwindowTextboxId As String, ByVal pEnableButtons As Boolean) Line 366: Line 367: Dim lTableRow As TableRow = New TableRow Line 368: Dim lTableCell As New TableCell Line 369: lTableCell.Attributes("colspan") = "2" Line 370: lTableCell.Controls.Add(New DnnChatFormattingToolbar(pChatwindowTextboxId, ChatRootImageUrl, ParentModule.LocalResourceFile, pEnableButtons)) Line 371: Line 372: lTableRow.Cells.Add(lTableCell) Line 373: lTableRow.Height = New Unit(20, UnitType.Pixel) Line 374: pTable.Rows.Add(lTableRow) Line 375: Line 376: End Sub Line 377: Private Function getArrivalText(ByVal bIsAllowedToChat As Boolean) As String Line 378: Dim _text As String Line 379: Line 380: If bIsAllowedToChat Then Line 381: _text = Localization.GetString("UserHasJoined", Me.ParentModule.LocalResourceFile) Line 382: Else Line 383: _text = Localization.GetString("UserIsReading", Me.ParentModule.LocalResourceFile) Line 384: End If Line 385: Line 386: Return String.Format(_text, GetSenderName) Line 387: Line 388: End Function Line 389: Line 390: #End Region Line 391: Line 392: Private Sub DnnChat_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init Line 393: Me.Height = Unit.Parse(GetSetting(Of String)("dnnChat_Height", "200px")) Line 394: End Sub Line 395: Line 396: Private Sub DnnChat_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Line 397: Line 398: 'Make sure there's an ID created Line 399: Dim dummy As Guid = ChatClientID Line 400: Line 401: If Me.Visible Then Line 402: Me.EnsureChildControls() Line 403: RegisterJavaScript() Line 404: End If Line 405: End Sub Line 406: Line 407: Private Sub RegisterJavaScript() Line 408: Dim key As String = "DotNetNuke_Chat" Line 409: Line 410: If Not Page.ClientScript.IsClientScriptBlockRegistered(key) Then Line 411: Page.ClientScript.RegisterClientScriptInclude(key, IO.Path.Combine(ParentModule.ModulePath, "DnnChat.js")) Line 412: End If Line 413: Line 414: 'TODO somewhere else Line 415: key = "DnnChatBBcode_script" Line 416: If Not Page.ClientScript.IsClientScriptBlockRegistered(key) Then Line 417: Page.ClientScript.RegisterClientScriptInclude(key, IO.Path.Combine(ParentModule.ModulePath, "DnnChatBBcode.js")) Line 418: End If Line 419: 'TODO somewhere else Line 420: Line 421: Line 422: ClientAPI.RegisterClientReference(Me.Page, ClientAPI.ClientNamespaceReferences.dnn) Line 423: ClientAPI.RegisterClientReference(Me.Page, ClientAPI.ClientNamespaceReferences.dnn_xml) Line 424: ClientAPI.RegisterClientReference(Me.Page, ClientAPI.ClientNamespaceReferences.dnn_xmlhttp) Line 425: Line 426: Page.ClientScript.RegisterClientScriptBlock(Me.GetType, "DnnChat_Variables_" & Me.ParentModule.ModuleId.ToString, GetScriptVariables, True) Line 427: Line 428: End Sub Line 429: Line 430: Private Function GetScriptVariables() As String Line 431: Dim retval As New StringBuilder Line 432: Line 433: 'TODO: make sure the {1} will be replaced with js-safe values Line 434: retval.AppendLine(String.Format("var cssClassSender_{0} = '{1}';", Me.ParentModule.ModuleId, Me.SenderCssClass)) Line 435: retval.AppendLine(String.Format("var cssClassMessage_{0} = '{1}';", Me.ParentModule.ModuleId, Me.MessageCssClass)) Line 436: retval.AppendLine(String.Format("var DisplayCapacity_{0} = {1};", Me.ParentModule.ModuleId, Me.DisplayCapacity)) Line 437: retval.AppendLine(String.Format("var last_previous_{0} = -1;", Me.ParentModule.ModuleId)) Line 438: retval.AppendLine(String.Format("var last_current_{0} = -1;", Me.ParentModule.ModuleId)) Line 439: retval.AppendLine(String.Format("var max_msgs_displayed_{0} = 0;", Me.ParentModule.ModuleId)) Line 440: retval.AppendLine(String.Format("var senderText_{0} = '{1}';", Me.ParentModule.ModuleId, Me.SenderText)) Line 441: Line 442: Return retval.ToString Line 443: End Function Line 444: Line 445: Private Overloads Sub CollectIncomingMessage(ByVal eventArgument As String) Line 446: 'EventArgument should give us the xml message from the client Line 447: 'This message should be Deserialzed Line 448: ' and must be decoded for formatting Line 449: 'and we'll need to drop it on the stack / in the queue, whatever... Line 450: Line 451: Dim _message As DnnChatMessage Line 452: Line 453: _message = DnnChatMessageCollection.DeserializeDnnChatmessage(eventArgument, Me.ChatRootImageUrl, Me.AllowFormatting) Line 454: Line 455: CollectIncomingMessage(_message) Line 456: Line 457: End Sub Line 458: Line 459: Private Sub RegisterUser() Line 460: Dim lChatUser As DnnChatUser = New DnnChatUser() Line 461: lChatUser.ChatSessionGuid = ChatClientID Line 462: If ParentModule.UserInfo Is Nothing Then Line 463: lChatUser.UserID = Null.NullInteger Line 464: Else Line 465: lChatUser.UserID = ParentModule.UserInfo.UserID Line 466: End If Line 467: lChatUser.Nickname = GetSenderName() Line 468: Line 469: If DnnChatUsers.ContainsKey(ChatClientID) = False Then Line 470: DnnChatUsers.Add(ChatClientID, lChatUser) Line 471: End If Line 472: Line 473: 'This statement seems fishy, but it actually writes the updated ChatUsers-list to the cache Line 474: DnnChatUsers = DnnChatUsers Line 475: Line 476: End Sub Line 477: Line 478: Private Sub UnregisterUser() Line 479: Line 480: If DnnChatUsers.ContainsKey(ChatClientID) Then Line 481: DnnChatUsers.Remove(ChatClientID) Line 482: Line 483: 'This statement seems fishy, but it actually writes the updated ChatUsers-list to the cache Line 484: DnnChatUsers = DnnChatUsers Line 485: End If Line 486: Line 487: End Sub Line 488: Line 489: Private Overloads Sub CollectIncomingMessage(ByVal msg As DnnChatMessage) Line 490: Line 491: 'We'll ignore themessage if it's empty: Line 492: If msg.Content.Length = 0 Then Line 493: Exit Sub Line 494: End If Line 495: Line 496: 'Does the conversation need instantiation? Line 497: If Me.DnnChatSessionMessages Is Nothing Then Line 498: Line 499: 'no existing queue found so create a new queue Line 500: _Messages = New DnnChatMessageCollection(Me.ParentModule.ModuleId) Line 501: Line 502: Else Line 503: Line 504: 'existing Queue found, so use it Line 505: _Messages = Me.DnnChatSessionMessages Line 506: Line 507: End If Line 508: Line 509: msg.SenderName = GetSenderName() Line 510: msg.ID = DnnChatSessionLastMessageID + 1 Line 511: DnnChatSessionLastMessageID = msg.ID Line 512: Line 513: msg.DateTime = Now Line 514: Line 515: 'Add the message to the stack Line 516: _Messages.Add(msg) Line 517: Line 518: 'purge stale messages Line 519: While _Messages.Count > HistoryCapacity Line 520: _Messages.RemoveAt(0) Line 521: End While Line 522: Line 523: 'Put the stack back in the cache Line 524: Me.DnnChatSessionMessages = _Messages Line 525: Line 526: 'SKA: What's the use of this? Line 527: Select Case msg.MessageType Line 528: Case MessageType.CHAT Line 529: 'nothing special Line 530: Case MessageType.ENTER Line 531: RegisterUser() Line 532: LastSentMessageID = msg.ID - 1 Line 533: Case MessageType.LEAVE Line 534: LastSentMessageID = Integer.MaxValue Line 535: UnregisterUser() Line 536: Case Else Line 537: 'emmm Line 538: End Select Line 539: Line 540: End Sub Line 541: Line 542: Private Function GetSenderName() As String Line 543: Line 544: If ParentModule.UserId > 0 Then Line 545: Return ParentModule.UserInfo.Username Line 546: Else Line 547: Return "Anonymous" '// TODO localize Line 548: End If Line 549: Line 550: End Function Line 551: Private Function GetReturnMessage() As String Line 552: 'This function should return the XML with all messages for the current client Line 553: Dim _retval As String = String.Empty Line 554: Dim _cmcReturn As New DnnChatMessageCollection(Me.ParentModule.ModuleId) Line 555: Line 556: Dim _lastMessageID As Integer = 0 Line 557: Dim _currentMessageID As Integer = 0 Line 558: Line 559: Line 560: If Not Me.DnnChatSessionMessages Is Nothing Then Line 561: Line 562: _lastMessageID = LastSentMessageID Line 563: _currentMessageID = _lastMessageID Line 564: Line 565: For Each Msg As DnnChatMessage In Me.DnnChatSessionMessages Line 566: If Msg.ID > _lastMessageID Then Line 567: _cmcReturn.Add(Msg) Line 568: _currentMessageID = Msg.ID Line 569: End If Line 570: Next Line 571: If _currentMessageID <> _lastMessageID Then Line 572: LastSentMessageID = _currentMessageID Line 573: End If Line 574: Line 575: End If Line 576: Line 577: Line 578: _retval = _cmcReturn.Serialize Line 579: Line 580: Return _retval Line 581: Line 582: End Function Line 583: Line 584: Private _LastSentMessageID As Integer = Null.NullInteger Line 585: Line 586: Private ReadOnly Property lastSentMessageIDsKey() As String Line 587: Get Line 588: Return String.Format("{0}_{1}", "dnnChat_LM", Me.ParentModule.ModuleId) Line 589: End Get Line 590: End Property Line 591: Line 592: Private _LastSentMessageIDs As Generic.Dictionary(Of Guid, Integer) Line 593: Private Property LastSentMessageID() As Integer Line 594: Get Line 595: 'Get from cache only once per request Line 596: If _LastSentMessageID = Nothing OrElse _LastSentMessageID <= 0 Then Line 597: 'Appearently there's no chached object yet Line 598: Dim obj As Object = DataCache.GetCache(lastSentMessageIDsKey) Line 599: If obj Is Nothing Then Line 600: 'LastSentMessageIDs are currently not in cache Line 601: _LastSentMessageID = Null.NullInteger Line 602: Else Line 603: 'Cache found Line 604: _LastSentMessageIDs = CType(obj, Generic.Dictionary(Of Guid, Integer)) Line 605: Line 606: 'Get this client's LastSentMessageID from the cached object Line 607: If _LastSentMessageIDs.ContainsKey(ChatClientID) Then Line 608: _LastSentMessageID = _LastSentMessageIDs(ChatClientID) Line 609: End If Line 610: End If Line 611: End If Line 612: Line 613: Return _LastSentMessageID Line 614: End Get Line 615: Set(ByVal Value As Integer) Line 616: Dim lLastSentMessageIDs As Generic.Dictionary(Of Guid, Integer) Line 617: Dim obj As Object = DataCache.GetCache(lastSentMessageIDsKey) Line 618: Line 619: If obj Is Nothing Then Line 620: lLastSentMessageIDs = New Generic.Dictionary(Of Guid, Integer) Line 621: Else Line 622: lLastSentMessageIDs = CType(obj, Generic.Dictionary(Of Guid, Integer)) Line 623: End If Line 624: Line 625: If lLastSentMessageIDs.ContainsKey(ChatClientID) Then Line 626: lLastSentMessageIDs(ChatClientID) = Value Line 627: Else Line 628: lLastSentMessageIDs.Add(ChatClientID, Value) Line 629: End If Line 630: Line 631: DataCache.SetCache(lastSentMessageIDsKey, lLastSentMessageIDs) Line 632: Line 633: End Set Line 634: End Property Line 635: Line 636: Public Function RaiseClientAPICallbackEvent(ByVal eventArgument As String) As String Implements UI.Utilities.IClientAPICallbackEventHandler.RaiseClientAPICallbackEvent Line 637: Line 638: 'When there a message in the argument, we'll need to process it Line 639: 'When it's empty, the client is only polling Line 640: If eventArgument.Length > 0 Then Line 641: CollectIncomingMessage(eventArgument) Line 642: End If Line 643: Line 644: Return GetReturnMessage() Line 645: End Function Line 646: Private Function chatClientCookieKey() As String Line 647: Return String.Format("chatclient_{0}_{1}", Me.ParentModule.TabId, Me.ParentModule.ModuleId) Line 648: End Function Line 649: Line 650: Private ReadOnly Property ChatClientID() As Guid Line 651: Get Line 652: Try Line 653: Dim req As HttpRequest = HttpContext.Current.Request Line 654: Line 655: ' save the chatclientid as a cookie Line 656: ' we just use a guid for it. It should identify the user's Line 657: ' chat session, even in e webfarm environment en prevent from Line 658: ' sending too many messages to the client Line 659: Dim cookie As System.Web.HttpCookie = Nothing Line 660: Dim cookieValue As Guid = Guid.Empty Line 661: Line 662: cookie = req.Cookies.Get(chatClientCookieKey) Line 663: Line 664: If (cookie Is Nothing) Then Line 665: 'This sets the cookie Line 666: cookieValue = Guid.NewGuid() Line 667: HttpContext.Current.Response.Cookies.Add(New System.Web.HttpCookie(chatClientCookieKey, cookieValue.ToString)) Line 668: Else Line 669: Try Line 670: cookieValue = New GuidConverter().ConvertFromString(cookie.Value) Line 671: Catch ex As Exception Line 672: 'Current cookie is broken. make a new one... Line 673: cookieValue = Guid.NewGuid() Line 674: HttpContext.Current.Response.Cookies.Add(New System.Web.HttpCookie(chatClientCookieKey, cookieValue.ToString)) Line 675: End Try Line 676: End If Line 677: Line 678: Return cookieValue Line 679: Catch Line 680: Return Guid.Empty Line 681: End Try Line 682: End Get Line 683: End Property Line 684: Line 685: Line 686: Protected Function GetSetting(Of TSetting)(ByVal strSetting As String, ByVal defaultValue As TSetting) As TSetting Line 687: Dim obj As Object = ParentModule.Settings.Item(strSetting) Line 688: If obj Is Nothing Then Line 689: Return defaultValue Line 690: Else Line 691: Return Convert.ChangeType(obj, GetType(TSetting)) Line 692: End If Line 693: End Function Line 694: Line 695: End Class Line 696: Line 697: End Namespace Line 698:
|