forked from cory/tildefriends
		
	A detachable multi-protocol chat client is starting to come together.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3232 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										126
									
								
								packages/cory/libchat/libchat.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								packages/cory/libchat/libchat.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| "use strict"; | ||||
|  | ||||
| exports.ChatService = class { | ||||
| 	static handleMessages(serviceClass) { | ||||
| 		let self = this; | ||||
| 		let sessions = {}; | ||||
|  | ||||
| 		core.register("onMessage", function(sender, options) { | ||||
| 			let service = sessions[options.name]; | ||||
| 			if (!service) { | ||||
| 				service = new serviceClass(options); | ||||
| 				sessions[options.name] = service; | ||||
| 			} else { | ||||
| 				service._service.addCallback(options.callback); | ||||
| 			} | ||||
| 			return service._service.makeInterface(service); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	constructor(callback) { | ||||
| 		this._callbacks = [callback]; | ||||
| 		this._conversations = {}; | ||||
| 		this._state = null; | ||||
| 	} | ||||
|  | ||||
| 	makeInterface(service) { | ||||
| 		let self = this; | ||||
| 		return { | ||||
| 			sendMessage: service.sendMessage.bind(service), | ||||
| 			disconnect: service.disconnect.bind(service), | ||||
|  | ||||
| 			getConversations: self.getConversations.bind(self), | ||||
| 			getHistory: self.getHistory.bind(self), | ||||
| 			getParticipants: self.getParticipants.bind(self), | ||||
| 		}; | ||||
| 	} | ||||
|  | ||||
| 	addCallback(callback) { | ||||
| 		if (this._callbacks.indexOf(callback) == -1) { | ||||
| 			this._callbacks.push(callback); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	_invokeCallback(message) { | ||||
| 		let self = this; | ||||
| 		for (let i = self._callbacks.length - 1; i >= 0; i--) { | ||||
| 			let callback = self._callbacks[i]; | ||||
| 			try { | ||||
| 				callback(message); | ||||
| 			} catch (error) { | ||||
| 				self._callbacks.splice(i, 1); | ||||
|  | ||||
| 				// XXX: Send it to the other connections? | ||||
| 				print(error); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	_getConversation(conversation) { | ||||
| 		if (!this._conversations[conversation]) { | ||||
| 			this._conversations[conversation] = {history: [], participants: []}; | ||||
| 		} | ||||
| 		return this._conversations[conversation]; | ||||
| 	} | ||||
|  | ||||
| 	notifyMessageReceived(conversation, message) { | ||||
| 		let fullMessage = {action: "message", conversation: conversation || "", message: message}; | ||||
| 		this._getConversation(conversation || "").history.push(fullMessage); | ||||
| 		this._invokeCallback(fullMessage); | ||||
| 	} | ||||
|  | ||||
| 	notifyPresenceChanged(conversation, user, state) { | ||||
| 		let leaving = state == "unavailable"; | ||||
| 		let participants = this._getConversation(conversation).participants; | ||||
| 		let index = participants.indexOf(user); | ||||
| 		if (leaving) { | ||||
| 			participants.splice(index, 1); | ||||
| 		} else if (index == -1) { | ||||
| 			participants.push(user); | ||||
| 		} | ||||
| 		this._invokeCallback({ | ||||
| 			action: "presence", | ||||
| 			conversation: conversation, | ||||
| 			user: user, | ||||
| 			presence: state, | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	notifyStateChanged(state) { | ||||
| 		this._state = state; | ||||
| 		this._invokeCallback({action: state}); | ||||
| 	} | ||||
|  | ||||
| 	reportError(error) { | ||||
| 		this._invokeCallback({ | ||||
| 			action: "error", | ||||
| 			error: error, | ||||
| 		}).catch(function(error) { | ||||
| 			print(error); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	isConversation(conversation) { | ||||
| 		return this._conversations[conversation] != null; | ||||
| 	} | ||||
|  | ||||
| 	getConversations() { | ||||
| 		return Object.keys(this._conversations); | ||||
| 	} | ||||
|  | ||||
| 	getHistory(conversation) { | ||||
| 		let result; | ||||
| 		if (this._conversations[conversation]) { | ||||
| 			result = this._conversations[conversation].history; | ||||
| 		} | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	getParticipants(conversation) { | ||||
| 		let result; | ||||
| 		if (this._conversations[conversation]) { | ||||
| 			result = this._conversations[conversation].participants; | ||||
| 		} | ||||
| 		return result; | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user