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:
|