HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/RMourik/bassol.nl/CMS/CMSModules/Chat/Controls/SupportChatManager.js
var ChatSupportManager = (function () {
	var my = {},
		windowNameOnline = 'chat_support_online',
		lastChangeTimestamp = null,
		onlineSupportID = null,
		pingTimeout = null,
		proxy = null,
		isOnline = false,
		rooms = {},
		roomsInitiatedUserId = {},
		roomsInitiatedContactId = {};

	my.config = {
			tick: 5000,
			popupWindowUrl: "",
			resPopupWindowError: ""
		};
	my.ready = false;
	my.callbackError = $cmsj.Callbacks();
	my.callbackGoOnline = $cmsj.Callbacks();
	my.callbackGoOffline = $cmsj.Callbacks();
	my.callbackUpdateRooms = $cmsj.Callbacks();

	my.getOnlineStatus = function() {
		return isOnline;
	};

	my.goOnline = function (callback) {
		callSupportWebService('EnterSupport', function() {
			if (!window.name) {
				window.name = windowNameOnline;
			}
			processGoOnline();
			if (callback != null) {
				callback();
			}
		}, handleError, []);
	};

	my.goOffline = function () {
		callSupportWebService('LeaveSupport', processGoOffline, function(response) {
			handleError(response);
			processGoOffline();
		}, []);
	};

	my.takeSupportRoom = function (roomId) {
		var room = rooms[roomId];
		if (!room) {
			return;
		}
		// Always call service and take room, so taken date time will be updated on the server side and correct number of unread messages will be send to all windows
		callSupportWebService('SupportTakeRoom', function() {
			room.unreadMessagesCount = 0;
			room.isTaken = true;
			room.popup();
			my.callbackUpdateRooms.fire(rooms);
		}, handleError, [room.roomId]);
	};

	my.leaveSupportRoom = function (roomId, fnOk) {
		callSupportWebService('SupportLeaveRoom', function() {
			if (rooms[roomId]) {
				delete rooms[roomId];
				my.callbackUpdateRooms.fire(rooms);
			}
			if (fnOk) {
				fnOk();
			}
		}, handleError,
			[roomId]);
	};

	my.initiateChat = function(userId, contactId) {
		if (userId <= 0 && contactId <= 0) {
			return;
		}		

		// If userId is not set, use contactId and mark isContact as true (keep userId otherwise)
		var isContact = false;
		if (userId <= 0) {
			userId = contactId;
			isContact = true;
		}
		if (!isOnline) {
			my.goOnline(function() {
				initiateChatInternal(userId, isContact);
			});
		} else {
			initiateChatInternal(userId, isContact);
		}
	};

	my.init = function (options) {
		$cmsj.extend(my.config, options);

		if ((typeof (window.chat) !== 'undefined') && (window.chat) && (window.chat.IChatSupportService)) {
			proxy = window.chat.IChatSupportService;
			my.ready = true;
		} else {
			my.ready = false;
		}

		if (window.name == windowNameOnline) {
			// Behave as on-line user (it is not necessary to send EnterSupport request)
			my.goOnline();
		} else {
			// User is off-line
			processGoOffline();
		}
	};
	
	function processGoOnline() {
		isOnline = true;
		lastChangeTimestamp = null;
		my.callbackGoOnline.fire();
		ping();
	}
	
	function processGoOffline() {
		clearPingTimeout();
		isOnline = false;
		lastChangeTimestamp = null;
		onlineSupportID = null;
		rooms = {};
		roomsInitiatedContactId = {};
		roomsInitiatedUserId = {};
		if (window.name == windowNameOnline) {
			window.name = '';
		}
		my.callbackGoOffline.fire();
	}
	
	function initiateChatInternal(userContactId, isContact) {
		var roomId,
			room;

		if (isContact) {
			roomId = roomsInitiatedContactId[userContactId];
		} else {
			roomId = roomsInitiatedUserId[userContactId];
		}

		if (roomId) {
			room = rooms[roomId];
		}
		
		if (room) {
			room.take();
		} else {
			callSupportWebService(isContact ? 'InitiateChatByContactID' : 'InitiateChatByUserID', function (roomResponse) {
				var contactId = isContact ? userContactId : 0,
					userId = !isContact ? userContactId : 0,
					roomId = roomResponse.ChatRoomID;
				
				room = addRoom(roomId, roomResponse.DisplayName, roomResponse.UnreadMessagesCount, true, userId, contactId);
				if (isContact) {
					roomsInitiatedContactId[contactId] = roomId;
				}
				else {
					roomsInitiatedUserId[userId] = roomId;
				}
				room.popup();
				my.callbackUpdateRooms.fire(rooms);
			}, handleError, [userContactId]);
		}
	}
	
	function addRoom(roomId, name, messagesCount, isTaken, userId, contactId) {
		var room = new ChatSupportRoom(roomId, name, messagesCount, {
			isTaken: isTaken,
			userId: userId,
			contactId: contactId
		});
		rooms[roomId] = room;
		return room;
	};

	function ping() {
		callSupportWebService('SupportPing', processPingResponse, function(response) {
			resetPingTimeout();
			handleError(response);
		}, [lastChangeTimestamp]);
	}

	function resetPingTimeout() {
		clearPingTimeout();
		pingTimeout = setTimeout(ping, my.config.tick);
	}

	function clearPingTimeout() {
		if (pingTimeout !== null) {
			clearTimeout(pingTimeout);
		}
	}

	function processPingResponse(response) {
		var supporterID = response.OnlineSupportChatUserID;
		if (!supporterID) {
			// Supporter is not online anymore.
			processGoOffline();
			return;
		}
		
		if (!onlineSupportID) {
			onlineSupportID = supporterID;
		} else if (supporterID !== onlineSupportID) {
			// Different user logged in.
			processGoOffline();
			return;
		}

		var responseRooms = response.Rooms;
		if (responseRooms) {
			if (responseRooms.LastChange) {
				lastChangeTimestamp = responseRooms.LastChange;
			}
			processRooms(responseRooms.List);
		}
		resetPingTimeout();
	}
	
	function processRooms(list) {
		if (!list || !list.length) {
			return;
		}
		for (var i = 0; i < list.length; i++) {
			var receivedRoom = list[i],
			    roomId = receivedRoom.ChatRoomID,
				room = rooms[roomId];
			if (receivedRoom.IsRemoved) {
				if (room) {
					delete rooms[roomId];
				}
				continue;
			}
			if (!room) {
				addRoom(roomId, receivedRoom.DisplayName, receivedRoom.UnreadMessagesCount, receivedRoom.IsTaken);
			} else {
				room.lastChange = new Date();
				room.unreadMessagesCount = receivedRoom.UnreadMessagesCount;
				room.isTaken = receivedRoom.IsTaken;
			}
		}
		my.callbackUpdateRooms.fire(rooms);
	}

	function handleError(error) {
		var message;
		if (error.StatusMessage) {
			message = error.StatusMessage;
		} else if (error.get_message) {
			message = error.get_message();
		} else {
			message = error;
		}

		if (message) {
		    if (typeof (console) !== "undefined") {
				console.log(message);
			}
			my.callbackError.fire(message);
		}
	}	

	// Call webservice function and process response
	function callSupportWebService(fn, fnOk, fnErr, args) {
		if (!proxy) {
			return;
		}
		if (!args) {
			args = [];
		}
		args.push(function(response) {
			// 0 is OK
			if (response.StatusCode == 0) {
				if (fnOk) {
					if (response.Data) {
						fnOk(response.Data);
					} else {
						fnOk();
					}
				}
			} else if (fnErr){
				fnErr(response);
			}
		});
		args.push(function (response) {
			if (!response.get_timedOut() && response.get_message().match(/The server method '.+' failed./i)) {
				// This is typically caused by unloading the page during service request
				return;
			}

			fnErr(response);
			
			// User has logged out in another window
			if (response.get_statusCode() == 401) {
				processGoOffline();
			}
		});
		args.push(null);
		proxy[fn].apply(proxy, args);
	}

	return my;
}());


ChatSupportRoom = function(roomId, name, unreadMessagesCount, options) {
	this.roomId = roomId;
	this.name = name;
	this.unreadMessagesCount = unreadMessagesCount;
	this.lastChange = new Date();
	this.isTaken = options.isTaken ? options.isTaken : false;
	this.openedWindow = null;
	this.userId = options.userId ? options.userId : null;
	this.contactId = options.contactId ? options.contactId : null;

	var winUrl = ChatSupportManager.config.popupWindowUrl.replace("{RoomIDParam}", this.roomId);

	this.popup = function() {
		// Open window with empty address, so it won't be reloaded if it already exists (is open in another tab for example) http://stackoverflow.com/a/2455480/637677
		var height = 800,
			width = 600,
			win = window.open('', this.roomId, "width=" + width + ",height=" + height + ",location=0,scrollbars=1,resizable=1");
		if (win) {
			// If location is not correct url, window was not opened before and address should be set to the correct one
			if (win.location != winUrl) {
				win.location = winUrl;
			}
			win.focus();
			ensureWindow(win, width, height);
			this.openedWindow = win;
		} else {
			alert(ChatSupportManager.config.resPopupWindowError);
		}
	};

	this.take = function() {
		ChatSupportManager.takeSupportRoom(this.roomId);
	};

	function ensureWindow(win, width, height) {
	    if ($cmsj.browser.opera || $cmsj.browser.webkit) {
			setTimeout(function() {
				if (!win.closed && (win.innerHeight != height) && (win.innerWidth != width)) {
					alert(ChatSupportManager.config.resPopupWindowError);
				}
			}, 1000);
		}
	}
};