Skip to content

Instantly share code, notes, and snippets.

@FirstVertex
Created September 30, 2012 23:47
Show Gist options
  • Save FirstVertex/3808759 to your computer and use it in GitHub Desktop.
Save FirstVertex/3808759 to your computer and use it in GitHub Desktop.
Virtual Pubsub in SmartJs
<!-- the Knockout binding from the text input to the chatRoomViewModel's
currentChatInput property. notice the valueUpdate is set to afterkeydown,
so the viewModel will be updated with each keystroke -->
<input type="text" data-mini="true" placeholder="chat"
data-bind="value: currentChatInput, valueUpdate: 'afterkeydown'" />
// the Knockout computed bound to the text input updates the
// isTyping property of the localMemberViewModel
// localMemberViewModel() returns an instance of chatMemberViewModel
_currentChatInput = Ko.observable(''),
currentChatInput = Ko.computed({
read: function () {
return _currentChatInput();
},
write: function (value) {
var oldValue = _currentChatInput();
value = value || '';
if (value === oldValue) return;
_currentChatInput(value);
var isTyping = value.length ? true : false;
// only the localMember can touch the chatInput
localMemberViewModel().isTyping(isTyping);
}
});
// the chatMemberViewModel's isTyping property is also a computed.
// when the isTyping value changes, this ViewModel calls Server.publishGroupEvent
var _isTyping = Ko.observable(false);
self.isTyping = Ko.computed({
read: function () {
return _isTyping();
},
write: function (value) {
var oldValue = _isTyping();
if (value === oldValue) return;
_isTyping(value);
if (self.isLocalMember) {
var dto = {
isTyping: value
};
GroupContext.publishGroupEvent('chat.typing', dto);
}
}
});
// GroupContext.publishGroupEvent is an abstraction that calls the server to
// route the event to only clients in the same nowjs group
// the event will end up being published on all clients in the group
// the chatRoomViewModel subscribes to the event with the onMemberTyping method
// each client:
// 1) receives the message
// 2) finds the member who initiated the event
// 3) and updates their isTyping property
Pubsub.subscribe('chat.typing', onMemberTyping);
function onMemberTyping(typingDto, isRemoteEvent, senderClientId) {
if (isRemoteEvent) {
var sender = findMemberViewModel(senderClientId);
if (sender) {
sender.isTyping(typingDto.isTyping);
}
}
}
<!-- Knockout binds each chatMemberViewModel to a listView item -->
<!-- the CSS style named "memberIsTyping" is conditionally applied,
based on the viewModel's isTyping property -->
<!-- ko foreach: members, refreshListview: true
--><li style="padding:.3em">
<span data-bind="text: memberName, css: { memberIsTyping: isTyping }"></span>
</li><!-- /ko -->
/* a css style gives a visual indicator of a
green italic font when the member starts typing */
.memberIsTyping { color: #07d945; font-style:italic }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment