Created
August 21, 2017 10:13
-
-
Save alexlcdee/c1d497f125f17a08173219d161bbf049 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var GalaMessaging; | |
(function (GalaMessaging) { | |
var messagingPrivate = { | |
userId: 0, | |
apiHost: '', | |
userRole: '' | |
}; | |
var Messaging = (function () { | |
function Messaging(config) { | |
var _this = this; | |
this.connection = new Connection(this); | |
this.notificationArea = new NotificationArea(this); | |
this.isInitialized = false; | |
if (config.userId) { | |
messagingPrivate.userId = config.userId; | |
} | |
messagingPrivate.apiHost = config.apiHost; | |
messagingPrivate.userRole = config.userRole; | |
if (config.port === undefined) { | |
config.port = '80'; | |
} | |
this._conversations = new Conversations(this, config.conversations); | |
this.connection.open({ hostName: config.host, port: config.port, query: { id: messagingPrivate.userId } }); | |
this.connection.on('reconnect', function () { return _this.connection.emit('userConnect', { id: messagingPrivate.userId }); }); | |
this.connection.on('chat-start-conversation', this.conversations.startConversation.bind(this.conversations)); | |
this.connection.on('chat-accept-conversation', this.conversations.acceptConversation.bind(this.conversations)); | |
this.connection.on('chat-message', this.conversations.newMessage.bind(this)); | |
this.connection.on('chat-error', function (error) { | |
console.log(error); | |
}); | |
this.connection.on('chat-sync-timer', function (data) { | |
_this.conversations.getConversation(data.conversationId).syncTimer(data.duration); | |
}); | |
this.connection.on('chat-conversation-stop', function (data) { return _this.conversations.getConversation(data.id).stop(); }); | |
this.isInitialized = true; | |
this.conversations.restoreConversations(); | |
} | |
Object.defineProperty(Messaging.prototype, "userId", { | |
get: function () { | |
return messagingPrivate.userId; | |
}, | |
set: function (value) { | |
throw new Error("You cannot change user ID given by server. Your actual ID is " + this.userId); | |
}, | |
enumerable: true, | |
configurable: true | |
}); | |
Object.defineProperty(Messaging.prototype, "apiHost", { | |
get: function () { | |
return messagingPrivate.apiHost; | |
}, | |
set: function (value) { | |
throw new Error("You cannot change API host. Actual API host is '" + this.apiHost + "'"); | |
}, | |
enumerable: true, | |
configurable: true | |
}); | |
Object.defineProperty(Messaging.prototype, "userRole", { | |
get: function () { | |
return messagingPrivate.userRole; | |
}, | |
set: function (value) { | |
throw new Error("You cannot change yor user role. Your actual role is '" + this.userRole + "'"); | |
}, | |
enumerable: true, | |
configurable: true | |
}); | |
Object.defineProperty(Messaging.prototype, "conversations", { | |
get: function () { | |
return this._conversations; | |
}, | |
enumerable: true, | |
configurable: true | |
}); | |
Messaging.prototype.notify = function (data) { | |
this.notificationArea.showNotification(data); | |
}; | |
Messaging.prototype.startConversation = function (peerId) { | |
if (this.conversations.getConversationWithPeer(peerId) !== undefined) { | |
} | |
else { | |
this.connection.emit('chat-start-conversation', { withPeer: peerId }); | |
} | |
}; | |
Messaging.prototype.acceptConversation = function (id) { | |
this.connection.emit('chat-accept-conversation', { id: id }); | |
}; | |
Messaging.prototype.sendMessage = function (conversationId, message) { | |
this.connection.emit('chat-send-message', { conversation: conversationId, message: message }); | |
}; | |
Messaging.prototype.runConversation = function (id) { | |
this.connection.emit('chat-run-conversation', { id: id }); | |
}; | |
Messaging.prototype.stopConversation = function (id) { | |
this.connection.emit('chat-stop-conversation', { id: id }); | |
}; | |
return Messaging; | |
}()); | |
Messaging.ROLE_PSY = 'psy'; | |
Messaging.ROLE_CLIENT = 'client'; | |
var messagingInstance; | |
function init(config) { | |
if (messagingInstance === undefined) { | |
messagingInstance = new Messaging(config); | |
$(window).trigger('galaMessaging.afterInit'); | |
} | |
else { | |
throw new Error("Messaging can be initialized only once."); | |
} | |
} | |
GalaMessaging.init = init; | |
function getInstance() { | |
return messagingInstance; | |
} | |
GalaMessaging.getInstance = getInstance; | |
var Connection = (function () { | |
function Connection(app) { | |
this.app = app; | |
} | |
Connection.prototype.open = function (options) { | |
var connectionString = options.hostName + ':' + options.port; | |
this.socket = io(connectionString, { | |
'reconnection': true, | |
'reconnectionDelay': 1000, | |
'reconnectionDelayMax': 5000, | |
}); | |
this.socket.emit('userConnect', options.query); | |
}; | |
Connection.prototype.on = function (event, callable) { | |
this.socket.on(event, callable); | |
}; | |
Connection.prototype.emit = function (event, data) { | |
this.socket.emit(event, data); | |
}; | |
return Connection; | |
}()); | |
var NotificationArea = (function () { | |
function NotificationArea(app) { | |
this.notificationsCount = 0; | |
this.app = app; | |
var area = $('<div class="notification-area"></div>'); | |
this.showNotification = function (data) { | |
if ($('body .notification-area').length === 0) { | |
$('body').append(area); | |
} | |
if (this.notificationsCount < NotificationArea.MAX_NOTIFICATIONS) { | |
area.append(this.render(data)); | |
} | |
else { | |
this.remove(area.find('.incomming-message:first'), area.append.bind(area, [this.render(data)])); | |
} | |
}; | |
} | |
NotificationArea.prototype.remove = function ($notification, complete) { | |
if (complete === undefined) { | |
complete = function () { | |
}; | |
} | |
clearTimeout($notification.data('timeout')); | |
$notification.fadeOut(200, (function () { | |
$notification.remove(); | |
this.notificationsCount--; | |
complete(); | |
}).bind(this)); | |
}; | |
NotificationArea.prototype.render = function (data) { | |
var $notification = $('<div class="incomming-message " data-id="' + data.id + '"></div>'); | |
$notification.append('<div class="img"><img src="' + data.photo + '?width=64&cropratio=1:1"/></div>'); | |
$notification.append('<div class="data"><div class="title">' + data.title + '</div><div class="text">' + data.text + '</div></div>'); | |
/*$notification.data('timeout', setTimeout((function () { | |
this.remove($notification); | |
}).bind(this), 15000));*/ | |
this.notificationsCount++; | |
if ('function' === typeof data.onClick) { | |
$notification.on('click', data.onClick); | |
} | |
$notification.delay(100).fadeIn(200); | |
return $notification; | |
}; | |
return NotificationArea; | |
}()); | |
NotificationArea.MAX_NOTIFICATIONS = 5; | |
var Conversations = (function () { | |
function Conversations(app, collection) { | |
var _this = this; | |
this.app = app; | |
var storage = collection; | |
this.getConversation = function (id) { | |
if (storage[id] === undefined) { | |
throw new Error("Conversation with id " + id + " not found"); | |
} | |
return storage[id]; | |
}; | |
this.setConversation = function (id, data) { | |
storage[id] = data; | |
//localStorage.setItem('conversations', storage.toString()); | |
}; | |
this.dumpStorage = function () { | |
console.dir(storage); | |
}; | |
this.clearStorage = function () { | |
for (var i in storage) { | |
if (storage.hasOwnProperty(i)) { | |
storage[i].stop(); | |
} | |
} | |
storage = []; | |
//localStorage.setItem('conversations', storage.toString()); | |
}; | |
this.getConversationWithPeer = function (peerId) { | |
for (var i in storage) { | |
if (storage.hasOwnProperty(i) && storage[i].peerId === peerId) { | |
return storage[i]; | |
} | |
} | |
}; | |
this.startConversation = function () { | |
var args = []; | |
for (var _i = 0; _i < arguments.length; _i++) { | |
args[_i] = arguments[_i]; | |
} | |
var data = args[0]; | |
var conversation = new Conversation(_this.app, parseInt(data.conversationId), parseInt(data.userId)); | |
_this.setConversation(data.conversationId, conversation); | |
if (parseInt(data.senderId) !== messagingPrivate.userId) { | |
_this.app.notify({ | |
id: data.userId, | |
photo: data.photo, | |
title: data.title, | |
text: data.text, | |
onClick: function (e) { | |
_this.app.acceptConversation(data.conversationId); | |
console.dir(e.delegateTarget); | |
e.delegateTarget.remove(); | |
//window.location.href = '/chat'; | |
} | |
}); | |
} | |
}; | |
this.acceptConversation = function () { | |
var args = []; | |
for (var _i = 0; _i < arguments.length; _i++) { | |
args[_i] = arguments[_i]; | |
} | |
var data = args[0]; | |
var conversation; | |
conversation = _this.getConversation(data.id); | |
conversation.start(); | |
}; | |
this.restoreConversations = function () { | |
//if (localStorage.getItem('conversations') !== null) { | |
//let conversations = JSON.parse(localStorage.getItem('conversations')); | |
var conversations = storage; | |
for (var i in conversations) { | |
if (conversations.hasOwnProperty(i)) { | |
var data = conversations[i]; | |
var currentState = data.state; | |
data.state = 0; | |
storage[i] = Conversation.fromStorage(_this.app, data); | |
if (currentState === Conversation.STATE_RUNNING) { | |
var started = storage[i].start(); | |
if (started !== false) { | |
started.then(function () { | |
_this.app.runConversation(storage[i].id); | |
}); | |
} | |
} | |
} | |
} | |
//} | |
}; | |
this.newMessage = function () { | |
var args = []; | |
for (var _i = 0; _i < arguments.length; _i++) { | |
args[_i] = arguments[_i]; | |
} | |
var data = args[0]; | |
_this.getConversation(data.conversationId).newMessage(data); | |
}; | |
} | |
return Conversations; | |
}()); | |
var Conversation = (function () { | |
function Conversation(app, id, peerId) { | |
this._duration = 0; | |
this._state = Conversation.STATE_INIT; | |
this.id = id; | |
this.app = app; | |
this.storage = app.conversations; | |
this.peerId = peerId; | |
} | |
Object.defineProperty(Conversation.prototype, "state", { | |
get: function () { | |
return this._state; | |
}, | |
set: function (value) { | |
this._state = value; | |
this.storage.setConversation(this.id, this); | |
}, | |
enumerable: true, | |
configurable: true | |
}); | |
Object.defineProperty(Conversation.prototype, "duration", { | |
set: function (value) { | |
this._duration = value; | |
this.storage.setConversation(this.id, this); | |
}, | |
enumerable: true, | |
configurable: true | |
}); | |
Conversation.prototype.toString = function () { | |
return JSON.stringify({ | |
id: this.id, | |
duration: this._duration, | |
state: this._state, | |
peerId: this.peerId | |
}); | |
}; | |
Conversation.fromStorage = function (app, data) { | |
var conversation = new Conversation(app, data.id, data.peerId); | |
conversation._duration = data.duration; | |
conversation._state = data.state; | |
return conversation; | |
}; | |
Conversation.prototype.retrieveConversationWindow = function (success) { | |
var _this = this; | |
$.get('/chat/getDialog', { userId: this.peerId, conversationId: this.id }, function (data) { | |
_this.$window = $(data); | |
_this.$exp = _this.$window.find('.exp-time-now'); | |
_this.$textArea = _this.$window.find('.text-recall'); | |
_this.$messageBox = _this.$window.find('.chat-msgs'); | |
success(); | |
}); | |
}; | |
Conversation.prototype.printWindow = function () { | |
var _this = this; | |
return new Promise(function (resolve, reject) { | |
if (_this.$window === undefined) { | |
_this.retrieveConversationWindow(resolve); | |
} | |
else { | |
resolve(); | |
} | |
}).then(function () { | |
if ($("body [data-conversation-id=" + _this.id + "]").length === 0) { | |
$('.dialogs').append(_this.$window); | |
$('.chat-wrapper').removeClass('active'); | |
_this.$window.addClass('active'); | |
_this.$messageBox.animate({ 'scrollTop': _this.$messageBox.prop('scrollHeight') }, 1); | |
_this.$window.on('click', '.text-send', function () { | |
_this.app.sendMessage(_this.id, _this.$textArea.val()); | |
_this.$textArea.val(''); | |
}); | |
_this.$window.on('click', '.end-chat', function () { | |
_this.app.stopConversation(_this.id); | |
_this.$textArea.val(''); | |
}); | |
} | |
}); | |
}; | |
Conversation.prototype.stop = function () { | |
if (this.state === Conversation.STATE_STOPPED) { | |
return false; | |
} | |
this.pause(); | |
this.state = Conversation.STATE_STOPPED; | |
}; | |
Conversation.prototype.start = function () { | |
var _this = this; | |
if (this.state === Conversation.STATE_RUNNING) { | |
return false; | |
} | |
return this.printWindow().then(function () { | |
var lastIntervalTick = Date.now(); | |
_this.interval = setInterval(function () { | |
var now = Date.now(); | |
_this.duration = _this._duration + ((now - lastIntervalTick) / 1000); | |
lastIntervalTick = now; | |
_this.intervalTick(); | |
}, 500); | |
_this.state = Conversation.STATE_RUNNING; | |
}); | |
}; | |
Conversation.prototype.pause = function () { | |
if (this.state !== Conversation.STATE_RUNNING) { | |
return false; | |
} | |
clearInterval(this.interval); | |
this.state = Conversation.STATE_PAUSED; | |
}; | |
Conversation.prototype.syncTimer = function (duration) { | |
this.duration = parseInt(duration); | |
}; | |
Conversation.prototype.newMessage = function (data) { | |
var message = $("\n<div class=\"chat-message\">\n <div class=\"chat-avatar left\">\n <img src=\"" + data.sender.photo + "?width=50&height=50&cropratio=1%3A1\">\n </div>\n <div class=\"chat-message-wrap\">\n <div class=\"chat-name\">" + data.sender.name + "</div>\n <div class=\"chat-message-text ns15\">" + data.message + "</div>\n </div>\n</div>"); | |
var msgs = this.$window.find('.chat-msgs'); | |
msgs.append(message); | |
this.$messageBox.animate({ 'scrollTop': this.$messageBox.prop('scrollHeight') }, 100); | |
}; | |
Conversation.prototype.intervalTick = function () { | |
var duration = '{h}:{m}:{s}'; | |
var times = { hours: 0, minutes: 0, seconds: 0 }; | |
var dataDuration = this._duration; | |
times.seconds = (dataDuration % 60) | 0; | |
times.minutes = (dataDuration / 60 % 60) | 0; | |
times.hours = (dataDuration / 60 / 60 % 60) | 0; | |
for (var key in times) { | |
times[key] = times[key].toString(); | |
if (times[key].length < 2) | |
times[key] = '0' + times[key]; | |
} | |
duration = duration | |
.replace('{h}', times.hours.toString()) | |
.replace('{m}', times.minutes.toString()) | |
.replace('{s}', times.seconds.toString()); | |
this.$exp.html(duration); | |
}; | |
return Conversation; | |
}()); | |
Conversation.STATE_INIT = 0; | |
Conversation.STATE_RUNNING = 1; | |
Conversation.STATE_STOPPED = 2; | |
Conversation.STATE_PAUSED = 3; | |
})(GalaMessaging || (GalaMessaging = {})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace GalaMessaging { | |
interface MessagingConfig { | |
host: string; | |
port?: string; | |
userId: number; | |
apiHost: string; | |
userRole: string; | |
conversations: Array<any>; | |
} | |
let messagingPrivate = { | |
userId: 0, | |
apiHost: '', | |
userRole: '' | |
}; | |
class Messaging { | |
private connection: Connection = new Connection(this); | |
private notificationArea: NotificationArea = new NotificationArea(this); | |
private _conversations: Conversations; | |
private isInitialized = false; | |
static readonly ROLE_PSY = 'psy'; | |
static readonly ROLE_CLIENT = 'client'; | |
getApiHost: () => string; | |
getUserId: () => number; | |
getUserRole: () => string; | |
get userId() { | |
return messagingPrivate.userId; | |
} | |
set userId(value) { | |
throw new Error(`You cannot change user ID given by server. Your actual ID is ${this.userId}`); | |
} | |
get apiHost() { | |
return messagingPrivate.apiHost; | |
} | |
set apiHost(value) { | |
throw new Error(`You cannot change API host. Actual API host is '${this.apiHost}'`); | |
} | |
get userRole() { | |
return messagingPrivate.userRole; | |
} | |
set userRole(value) { | |
throw new Error(`You cannot change yor user role. Your actual role is '${this.userRole}'`); | |
} | |
get conversations() { | |
return this._conversations; | |
} | |
public constructor(config: MessagingConfig) { | |
if (config.userId) { | |
messagingPrivate.userId = config.userId; | |
} | |
messagingPrivate.apiHost = config.apiHost; | |
messagingPrivate.userRole = config.userRole; | |
if (config.port === undefined) { | |
config.port = '80'; | |
} | |
this._conversations = new Conversations(this, config.conversations); | |
this.connection.open({hostName: config.host, port: config.port, query: {id: messagingPrivate.userId}}); | |
this.connection.on('reconnect', () => this.connection.emit('userConnect', {id: messagingPrivate.userId})); | |
this.connection.on('chat-start-conversation', this.conversations.startConversation.bind(this.conversations)); | |
this.connection.on('chat-accept-conversation', this.conversations.acceptConversation.bind(this.conversations)); | |
this.connection.on('chat-message', this.conversations.newMessage.bind(this)); | |
this.connection.on('chat-error', error => { | |
console.log(error); | |
}); | |
this.connection.on('chat-sync-timer', data => { | |
this.conversations.getConversation(data.conversationId).syncTimer(data.duration); | |
}); | |
this.connection.on('chat-conversation-stop', (data) => this.conversations.getConversation(data.id).stop()); | |
this.isInitialized = true; | |
this.conversations.restoreConversations(); | |
} | |
public notify(data: Notification) { | |
this.notificationArea.showNotification(data); | |
} | |
public startConversation(peerId: number) { | |
if (this.conversations.getConversationWithPeer(peerId) !== undefined) { | |
} else { | |
this.connection.emit('chat-start-conversation', {withPeer: peerId}); | |
} | |
} | |
public acceptConversation(id: string) { | |
this.connection.emit('chat-accept-conversation', {id: id}); | |
} | |
public sendMessage(conversationId: number, message: string) { | |
this.connection.emit('chat-send-message', {conversation: conversationId, message: message}); | |
} | |
public runConversation(id: number) { | |
this.connection.emit('chat-run-conversation', {id: id}); | |
} | |
public stopConversation(id: number) { | |
this.connection.emit('chat-stop-conversation', {id: id}); | |
} | |
} | |
let messagingInstance; | |
export function init(config: MessagingConfig) { | |
if (messagingInstance === undefined) { | |
messagingInstance = new Messaging(config); | |
$(window).trigger('galaMessaging.afterInit'); | |
} else { | |
throw new Error(`Messaging can be initialized only once.`); | |
} | |
} | |
export function getInstance(): Messaging { | |
return messagingInstance; | |
} | |
class Connection { | |
private socket: SocketIOClient.Socket; | |
private app: Messaging; | |
open(options: ConnectionOptions) { | |
let connectionString = options.hostName + ':' + options.port; | |
this.socket = io(connectionString, { | |
'reconnection': true, | |
'reconnectionDelay': 1000, | |
'reconnectionDelayMax': 5000, | |
}); | |
this.socket.emit('userConnect', options.query); | |
} | |
on(event, callable: (data?: any) => void) { | |
this.socket.on(event, callable); | |
} | |
emit(event: string, data) { | |
this.socket.emit(event, data); | |
} | |
constructor(app: Messaging) { | |
this.app = app; | |
} | |
} | |
interface ConnectionOptions { | |
hostName: string; | |
port: string; | |
query: {}; | |
} | |
interface Notification { | |
id: number; | |
photo: string; | |
title: string; | |
text: string; | |
onClick?: (...args) => void; | |
} | |
class NotificationArea { | |
private app; | |
public showNotification: (data: Notification) => void; | |
private notificationsCount = 0; | |
static readonly MAX_NOTIFICATIONS = 5; | |
constructor(app: Messaging) { | |
this.app = app; | |
let area = $('<div class="notification-area"></div>'); | |
this.showNotification = function (data: Notification) { | |
if ($('body .notification-area').length === 0) { | |
$('body').append(area); | |
} | |
if (this.notificationsCount < NotificationArea.MAX_NOTIFICATIONS) { | |
area.append(this.render(data)); | |
} else { | |
this.remove(area.find('.incomming-message:first'), area.append.bind(area, [this.render(data)])); | |
} | |
} | |
} | |
private remove($notification: JQuery, complete?: () => void) { | |
if (complete === undefined) { | |
complete = function () { | |
}; | |
} | |
clearTimeout($notification.data('timeout')); | |
$notification.fadeOut(200, (function () { | |
$notification.remove(); | |
this.notificationsCount--; | |
complete(); | |
}).bind(this)); | |
} | |
private render(data: Notification) { | |
let $notification = $('<div class="incomming-message " data-id="' + data.id + '"></div>'); | |
$notification.append('<div class="img"><img src="' + data.photo + '?width=64&cropratio=1:1"/></div>'); | |
$notification.append('<div class="data"><div class="title">' + data.title + '</div><div class="text">' + data.text + '</div></div>'); | |
/*$notification.data('timeout', setTimeout((function () { | |
this.remove($notification); | |
}).bind(this), 15000));*/ | |
this.notificationsCount++; | |
if ('function' === typeof data.onClick) { | |
$notification.on('click', data.onClick); | |
} | |
$notification.delay(100).fadeIn(200); | |
return $notification; | |
} | |
} | |
class Conversations { | |
private app: Messaging; | |
getConversation: (id: number) => Conversation; | |
setConversation: (id: number, data: Conversation) => void; | |
startConversation: (...args) => void; | |
getConversationWithPeer: (peerId: number) => Conversation; | |
acceptConversation: (...args) => void; | |
dumpStorage: () => void; | |
clearStorage: () => void; | |
restoreConversations: () => void; | |
newMessage: (...args) => void; | |
constructor(app: Messaging, collection: Array<any>) { | |
this.app = app; | |
let storage = collection; | |
this.getConversation = (id) => { | |
if (storage[id] === undefined) { | |
throw new Error(`Conversation with id ${id} not found`); | |
} | |
return storage[id]; | |
}; | |
this.setConversation = (id: number, data: Conversation) => { | |
storage[id] = data; | |
//localStorage.setItem('conversations', storage.toString()); | |
}; | |
this.dumpStorage = function () { | |
console.dir(storage); | |
}; | |
this.clearStorage = function () { | |
for (let i in storage) { | |
if (storage.hasOwnProperty(i)) { | |
storage[i].stop(); | |
} | |
} | |
storage = []; | |
//localStorage.setItem('conversations', storage.toString()); | |
}; | |
this.getConversationWithPeer = function (peerId: number) { | |
for (let i in storage) { | |
if (storage.hasOwnProperty(i) && storage[i].peerId === peerId) { | |
return storage[i]; | |
} | |
} | |
}; | |
this.startConversation = (...args) => { | |
let data = args[0]; | |
let conversation = new Conversation(this.app, parseInt(data.conversationId), parseInt(data.userId)); | |
this.setConversation(data.conversationId, conversation); | |
if (parseInt(data.senderId) !== messagingPrivate.userId) { | |
this.app.notify({ | |
id: data.userId, | |
photo: data.photo, | |
title: data.title, | |
text: data.text, | |
onClick: (e: JQueryEventObject) => { | |
this.app.acceptConversation(data.conversationId); | |
console.dir(e.delegateTarget); | |
e.delegateTarget.remove(); | |
//window.location.href = '/chat'; | |
} | |
}); | |
} | |
}; | |
this.acceptConversation = (...args) => { | |
let data = args[0]; | |
let conversation; | |
conversation = this.getConversation(data.id); | |
conversation.start(); | |
}; | |
this.restoreConversations = () => { | |
//if (localStorage.getItem('conversations') !== null) { | |
//let conversations = JSON.parse(localStorage.getItem('conversations')); | |
let conversations = storage; | |
for (let i in conversations) { | |
if (conversations.hasOwnProperty(i)) { | |
let data = conversations[i]; | |
let currentState = data.state; | |
data.state = 0; | |
storage[i] = Conversation.fromStorage(this.app, data); | |
if (currentState === Conversation.STATE_RUNNING) { | |
let started = storage[i].start(); | |
if (started !== false) { | |
started.then(() => { | |
this.app.runConversation(storage[i].id) | |
}); | |
} | |
} | |
} | |
} | |
//} | |
}; | |
this.newMessage = (...args) => { | |
let data = args[0]; | |
this.getConversation(data.conversationId).newMessage(data); | |
} | |
} | |
} | |
class Conversation { | |
$window: JQuery; | |
interval; | |
id: number; | |
peerId: number; | |
private _duration: number = 0; | |
private $exp: JQuery; | |
private $textArea: JQuery; | |
private $messageBox: JQuery; | |
private _state: number = Conversation.STATE_INIT; | |
private storage: Conversations; | |
private app: Messaging; | |
static readonly STATE_INIT = 0; | |
static readonly STATE_RUNNING = 1; | |
static readonly STATE_STOPPED = 2; | |
static readonly STATE_PAUSED = 3; | |
public get state() { | |
return this._state; | |
} | |
public set state(value: number) { | |
this._state = value; | |
this.storage.setConversation(this.id, this); | |
} | |
private set duration(value: number) { | |
this._duration = value; | |
this.storage.setConversation(this.id, this); | |
} | |
constructor(app: Messaging, id: number, peerId: number) { | |
this.id = id; | |
this.app = app; | |
this.storage = app.conversations; | |
this.peerId = peerId; | |
} | |
toString() { | |
return JSON.stringify({ | |
id: this.id, | |
duration: this._duration, | |
state: this._state, | |
peerId: this.peerId | |
}); | |
} | |
static fromStorage(app: Messaging, data: { id: number, duration: number, state: number, peerId: number }) { | |
let conversation = new Conversation(app, data.id, data.peerId); | |
conversation._duration = data.duration; | |
conversation._state = data.state; | |
return conversation; | |
} | |
private retrieveConversationWindow(success: () => void) { | |
$.get('/chat/getDialog', {userId: this.peerId, conversationId: this.id}, data => { | |
this.$window = $(data); | |
this.$exp = this.$window.find('.exp-time-now'); | |
this.$textArea = this.$window.find('.text-recall'); | |
this.$messageBox = this.$window.find('.chat-msgs'); | |
success(); | |
}); | |
} | |
public printWindow() { | |
return new Promise((resolve, reject) => { | |
if (this.$window === undefined) { | |
this.retrieveConversationWindow(resolve); | |
} else { | |
resolve(); | |
} | |
}).then(() => { | |
if ($(`body [data-conversation-id=${this.id}]`).length === 0) { | |
$('.dialogs').append(this.$window); | |
$('.chat-wrapper').removeClass('active'); | |
this.$window.addClass('active'); | |
this.$messageBox.animate({'scrollTop': this.$messageBox.prop('scrollHeight')}, 1); | |
this.$window.on('click', '.text-send', () => { | |
this.app.sendMessage(this.id, this.$textArea.val()); | |
this.$textArea.val(''); | |
}); | |
this.$window.on('click', '.end-chat', () => { | |
this.app.stopConversation(this.id); | |
this.$textArea.val(''); | |
}); | |
} | |
}); | |
} | |
stop() { | |
if (this.state === Conversation.STATE_STOPPED) { | |
return false; | |
} | |
this.pause(); | |
this.state = Conversation.STATE_STOPPED; | |
} | |
start() { | |
if (this.state === Conversation.STATE_RUNNING) { | |
return false; | |
} | |
return this.printWindow().then(() => { | |
let lastIntervalTick = Date.now(); | |
this.interval = setInterval(() => { | |
let now = Date.now(); | |
this.duration = this._duration + ((now - lastIntervalTick) / 1000); | |
lastIntervalTick = now; | |
this.intervalTick(); | |
}, 500); | |
this.state = Conversation.STATE_RUNNING; | |
}); | |
} | |
pause() { | |
if (this.state !== Conversation.STATE_RUNNING) { | |
return false; | |
} | |
clearInterval(this.interval); | |
this.state = Conversation.STATE_PAUSED; | |
} | |
syncTimer(duration) { | |
this.duration = parseInt(duration); | |
} | |
newMessage(data) { | |
let message = $(` | |
<div class="chat-message"> | |
<div class="chat-avatar left"> | |
<img src="${data.sender.photo}?width=50&height=50&cropratio=1%3A1"> | |
</div> | |
<div class="chat-message-wrap"> | |
<div class="chat-name">${data.sender.name}</div> | |
<div class="chat-message-text ns15">${data.message}</div> | |
</div> | |
</div>`); | |
let msgs = this.$window.find('.chat-msgs'); | |
msgs.append(message); | |
this.$messageBox.animate({'scrollTop': this.$messageBox.prop('scrollHeight')}, 100); | |
} | |
private intervalTick() { | |
let duration = '{h}:{m}:{s}'; | |
let times = {hours: 0, minutes: 0, seconds: 0}; | |
let dataDuration = this._duration; | |
times.seconds = (dataDuration % 60) | 0; | |
times.minutes = (dataDuration / 60 % 60) | 0; | |
times.hours = (dataDuration / 60 / 60 % 60) | 0; | |
for (let key in times) { | |
times[key] = times[key].toString(); | |
if (times[key].length < 2) | |
times[key] = '0' + times[key]; | |
} | |
duration = duration | |
.replace('{h}', times.hours.toString()) | |
.replace('{m}', times.minutes.toString()) | |
.replace('{s}', times.seconds.toString()); | |
this.$exp.html(duration); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment