Ind.ie is now Small Technology Foundation.
Commit 85e70b8c authored by Aral Balkan's avatar Aral Balkan

Added generic means of getting timeline message deltas. Not functional until...

Added generic means of getting timeline message deltas. Not functional until message ID migration removes depracated timeline clocks.
parent 2f284e5b
......@@ -76,6 +76,7 @@ class PrivateWebServer
app.get '/private-timeline', require('./private/routes/private.coffee')(app)
app.get '/public-timeline', require('./private/routes/public.coffee')(app)
app.get '/conversation-with/:person', require('./private/routes/conversation.coffee')(app)
app.get '/posts-after/:timeline/:key', require('./private/routes/posts-after.coffee')(app)
#
# Catchall error handler.
......
......@@ -172,20 +172,38 @@ class StreamWeaver
key = "#{friendsName}_#{friendsAccountHandle}"
@friends.put key, " "
#
# Ajax methods for delta updates.
#
getPostsAfter: (timeline, key, limit = 20) =>
# console.log "Getting posts after key: #{key}…"
@getTimeline timeline, key, '\uffff', limit
getPostsBefore: (timeline, key, limit = 20) =>
@getTimeline timeline, '\x00', key, limit
#
# Get timeline
#
# Returns a promise to return the requested timeline.
# (We need to stream the timelines contents from the database.)
#
getTimeline: (timeline) =>
# TODO: Refactor to remove redundancy between this and the PublicTimelineWeaver in Waystone.
#
getTimeline: (timeline, from='\x00', to='\uffff', limit=50) =>
console.log "Streamweaver::getTimeline: #{timeline}"
return new Promise ((fulfill, reject) =>
# Create a new stream for the requested timeline
options = { gt: '\x00', lt: '\uffff', limit: 100}
options =
gt: from
lt: to
limit: limit
# The private and public timelines are displayed in reverse order
# (latest post first). However, since we implement that when displaying
......
......@@ -8,6 +8,8 @@ module.exports = (app) ->
route = (request, response) ->
person = request.param 'person'
#
# TODO: Refactor these formatter to remove redundancy.
#
......@@ -128,6 +130,7 @@ module.exports = (app) ->
console.log "Getting conversation timeline for person #{conversationTimelineForPerson}."
#
# Massage the messages.
#
......@@ -159,5 +162,4 @@ module.exports = (app) ->
# TODO: Add the formatters to the messages themselves so we don’t have to duplicate them on the client.
# Reverse the message order to match that of the Cocoa client.
response.render 'conversation', {personsName: personsName, messages: messages, __set: { formatters: {messageBodyIDFormatter: messageBodyIDFormatter, messageStatusIDFormatter: messageStatusIDFormatter, profileImagePathFormatter: profileImagePathFormatter, personFormatter:personFormatter, addFriendLinkFormatter: addFriendLinkFormatter, addFriendTextFormatter:addFriendTextFormatter, postDateFormatter:postDateFormatter}}}
response.render 'conversation', {personsAccountHandle: person, personsName: personsName, messages: messages, __set: { formatters: {messageBodyIDFormatter: messageBodyIDFormatter, messageStatusIDFormatter: messageStatusIDFormatter, profileImagePathFormatter: profileImagePathFormatter, personFormatter:personFormatter, addFriendLinkFormatter: addFriendLinkFormatter, addFriendTextFormatter:addFriendTextFormatter, postDateFormatter:postDateFormatter}}}
#
# Ajax updates for all private timelines.
# TODO: Refactor w. Waystone to remove redundancy.
#
module.exports = (app) ->
route = (request, response) ->
# Read the details
key = request.param 'key'
timeline = request.param 'timeline'
streamWeaver = app.get('config').streamWeaver
console.log "Looking up posts since key #{key} on timeline #{timeline}."
steamWeaver.getPostsAfter(timeline, key).then (messages) ->
# console.log 'Found new posts: '
# console.log messages
# Reverse the message order to match that of the Cocoa client.
# messages.reverse()
response.end JSON.stringify messages
......@@ -7,12 +7,12 @@
<link rel='stylesheet' href='/css/styles.css'>
<script type='text/javascript' src='/js/superagent.js'></script>
<script src="/js/set.js"></script>
<script src="/js/all-friends.js"></script>
<script src="/js/conversation.js"></script>
<script data-set-text='meta'></script>
</head>
<body>
<section id='public-timeline'>
<h1 data-set-text='personsName'></h1>
<h1 id='person' data-set-text='personsName' data-set-attribute='data-name personsAccountHandle'></h1>
<!-- Notice to display if there are no messages yet. -->
<div data-set-if='not:messages' id='notice'>
......
window.addEventListener('load', function(){
// Set: don’t run in Node.
if (typeof this.data !== 'undefined')
{
// console.log("In Node: Not running in-browser code.");
return;
}
setInterval(function(){
// console.log("Polling server for new public posts…")
var messages = document.getElementById('messages');
var newestPostID = messages.firstElementChild.getAttribute('id')
// console.log('Getting post after ' + newestPostID)
var person = document.getElementById('person').getAttribute('data-name')
console.log(person);
// TODO: Do not hard code this URL.
// TODO: Fix Set injectData so we don’t have to use this metadata injection workaround.
superagent
.get('http://127.0.0.1/posts-after/'+newestPostID+'/'+person)
.end(function(error, posts) {
//
// Optimisation: clone the repeater seed node and only apply the set
// template on that so we don’t end up rendering the whole list of messages.
// (I should pave this cowpath: https://source.ind.ie/project/set/issues/4)
//
posts = JSON.parse(posts.text);
// console.log(posts);
if (posts.length == 0){
console.log('No new posts.');
return;
}
var repeaterNodeHTML =
" <div style='background-color: rgb(200, 50, 50, 0.5);' class='message' data-set-repeat='message messages' data-set-attribute='id message.key' >"
+ " <div class='messageBody' data-set-attribute='id message.key messageBodyIDFormatter'>"
+ " <div class='image-and-body'>"
+ " <img class='profileImage' data-set-attribute='src message.key profileImagePathFormatter'>"
+ " <div class='bodyText' data-set-text='html message.value'>Message body HTML</div>"
+ " </div>"
+ " </div>"
+ " </div>";
var messages = document.getElementById('messages');
var div = document.createElement('div')
div.setAttribute('id', posts[0]['key']+'-0')
div.innerHTML = repeaterNodeHTML
messages.insertBefore(div, messages.firstElementChild)
// messages.innerHTML = repeaterNodeHTML + messages.innerHTML;
repeaterNode = messages.firstElementChild
// Bug: Formatters are not being passed from the server correctly
// when injectData is true. As a workaround: I’m duplicating them on the
// client also.
set.format['messageBodyIDFormatter'] = function (messageID) {
return messageID + "-body";
}
set.format['messageStatusIDFormatter'] = function (messageID) {
return messageID + "-status";
}
set.format['profileImagePathFormatter'] = function (messageID) {
var personHandle = messageID.substr(messageID.lastIndexOf('Z-')+2);
var profileImagePath = "/public/"+personHandle+"/about/me.jpg";
return profileImagePath;
}
// Update the repeater node
set(repeaterNode, {messages: posts})
});
}, 5000);
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment