Skip to content

Commit

Permalink
Merge pull request #238 from gabceb/180
Browse files Browse the repository at this point in the history
Implements infinite scrolling
  • Loading branch information
jrgifford committed Mar 21, 2013
2 parents d3d6cde + 189e765 commit 930039c
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 40 deletions.
20 changes: 10 additions & 10 deletions Gemfile.lock
Expand Up @@ -46,8 +46,8 @@ GEM
bourbon (3.1.1)
sass (>= 3.2.0)
thor
bourne (1.2.1)
mocha (= 0.12.7)
bourne (1.4.0)
mocha (~> 0.13.2)
builder (3.0.4)
cancan (1.6.9)
capybara (2.0.2)
Expand All @@ -70,11 +70,11 @@ GEM
coffee-script (2.2.0)
coffee-script-source
execjs
coffee-script-source (1.6.1)
coffee-script-source (1.6.2)
colorize (0.5.8)
columnize (0.3.6)
cookiejar (0.3.0)
coveralls (0.6.2)
coveralls (0.6.3)
colorize
multi_json (~> 1.3)
rest-client
Expand Down Expand Up @@ -130,7 +130,7 @@ GEM
yajl-ruby (>= 1.0.0)
faye-websocket (0.4.7)
eventmachine (>= 0.12.0)
ffi (1.4.0)
ffi (1.5.0)
gemoji (1.4.0)
guard (1.6.2)
listen (>= 0.6.0)
Expand Down Expand Up @@ -163,18 +163,18 @@ GEM
launchy (2.2.0)
addressable (~> 2.3)
listen (0.7.3)
lumberjack (1.0.2)
lumberjack (1.0.3)
mail (2.5.3)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
metaclass (0.0.1)
method_source (0.8.1)
mime-types (1.21)
mocha (0.12.7)
mocha (0.13.3)
metaclass (~> 0.0.1)
multi_json (1.7.1)
nokogiri (1.5.7)
nokogiri (1.5.8)
orm_adapter (0.4.0)
paperclip (3.4.1)
activemodel (>= 3.0.0)
Expand Down Expand Up @@ -250,9 +250,9 @@ GEM
multi_json (~> 1.0)
rubyzip
websocket (~> 1.0.4)
shoulda-matchers (1.5.0)
shoulda-matchers (1.5.2)
activesupport (>= 3.0.0)
bourne (~> 1.2.0)
bourne (~> 1.3)
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
Expand Down
17 changes: 13 additions & 4 deletions app/assets/javascripts/backbone/helpers/channels.js.coffee
Expand Up @@ -20,14 +20,17 @@ class Kandan.Helpers.Channels

@scrollToLatestMessage: (channelId)->
if channelId
theScrollArea = $('#channels-'+channelId)
theScrollArea = @channelPane(channelId)
theScrollArea.scrollTop(theScrollArea.prop('scrollHeight'))
else
$('.channels-pane').scrollTop($('.channels-pane').prop('scrollHeight'))

@currentScrollPosition: (channelId)->
$('channels-pane').scrollTop()

@channelPane: (channelId)->
$("#channels-#{channelId}")

@channelActivitiesEl: (channelId)->
$("#channel-activities-#{channelId}")

Expand Down Expand Up @@ -92,12 +95,12 @@ class Kandan.Helpers.Channels


@channelExists: (channelId)->
return true if $("#channels-#{channelId}").length > 0
return true if @channelPane(channelId).length > 0
false


@createChannelArea: (channel)->
channelArea = "#channels-#{channel.get('id')}"
channelArea = @channelPane(channel.get('id'))
totalTabs = $("#kandan").tabs("length")
$createTab = $("#create_channel").parents("li").detach()
$("#kandan").tabs("add", channelArea, "#{channel.get("name")}", totalTabs)
Expand Down Expand Up @@ -161,12 +164,18 @@ class Kandan.Helpers.Channels


@setPaginationState: (channelId, moreActivities, oldest)->
@channelPaginationEl(channelId).data("oldest", oldest)
console.log "pagination element", moreActivities, @channelPaginationEl(channelId)
if moreActivities == true
# Only set pagination data if there are more activities. Otherwise is useless
@channelPaginationEl(channelId).data("oldest", oldest.get("id"))

@channelPaginationEl(channelId).show()
else
@channelPaginationEl(channelId).hide()

# If there are no more messages we will unbind the scroll event
@channelPane(channelId).unbind("scroll")



@setPaginationData: (channelId)->
Expand Down
40 changes: 40 additions & 0 deletions app/assets/javascripts/backbone/views/channel_pane.js.coffee
Expand Up @@ -4,6 +4,16 @@ class Kandan.Views.ChannelPane extends Backbone.View
render: (container)->
$container = $(container || @el)
$container.html @paginatedActivitiesView()

# Flag to avoid pulling new messages when we already requested new messages from the server
@loading_new_messages = false

$container.bind 'scroll', ()=>
if $container.scrollTop() <= 100 && !@loading_new_messages
@loading_new_messages = true
@loadMoreActivities($container)
return

$container.append @chatboxView()
@setIdAndData($container)
$li = $("a[href=#channels-#{@options.channel.get('id')}]").parent()
Expand All @@ -27,3 +37,33 @@ class Kandan.Views.ChannelPane extends Backbone.View
chatboxView: ()->
view = new Kandan.Views.Chatbox({channel: @options.channel})
view.render().el

loadMoreActivities: ($container)->
$channel_activities = $container.find(".channel-activities")

# Keeping a reference of the first child to find the offset after the elements are added
$current_top_element = $channel_activities.children().first()

$pagination = $container.find(".pagination")
oldest = $pagination.data("oldest")

activities = new Kandan.Collections.Activities([], {channel_id: @options.channel.get("id")})
activities.fetch({
data: { oldest: oldest },
success: (collection)=>
for activity in collection.models.reverse()
activityView = new Kandan.Views.ShowActivity({activity: activity, silence_mentions: true})
$container.find(".channel-activities").prepend(activityView.render().el)

if $current_top_element.length != 0
$container.scrollTop($current_top_element.offset().top)

Kandan.Helpers.Channels.setPaginationState(
collection.channelId,
collection.moreActivities,
_.last(collection.models),
$container
)

@loading_new_messages = false
})
Expand Up @@ -4,17 +4,13 @@ class Kandan.Views.PaginatedActivities extends Backbone.View
className: 'paginated-activities'
template: JST['paginated_activities']

events:
"click .pagination": "loadMoreActivities"

setPagination: ()->
oldestActivityId = 0
if @channel.activities and @channel.activities.models.length > 0
oldestActivityId = _.first(@channel.activities.models).get("id")

$(@el).find(".pagination").data("oldest", oldestActivityId)


render: ()->
@channel = @options.channel
$(@el).html @template()
Expand All @@ -24,21 +20,3 @@ class Kandan.Views.PaginatedActivities extends Backbone.View
listActivitiesView = new Kandan.Views.ListActivities({channel: @channel})
$(@el).append listActivitiesView.render().el
@


loadMoreActivities: ()->
oldest = $(@el).find(".pagination").data("oldest")
activities = new Kandan.Collections.Activities([], {channel_id: @channel.get("id")})
activities.fetch({
data: { oldest: oldest },
success: (collection)=>
for activity in collection.models.reverse()
activityView = new Kandan.Views.ShowActivity({activity: activity})
$(@el).find(".channel-activities").prepend(activityView.render().el)

Kandan.Helpers.Channels.setPaginationState(
collection.channelId,
collection.moreActivities,
_.last(collection.models).get("id")
)
})
Expand Up @@ -23,7 +23,8 @@ class Kandan.Views.ShowActivity extends Backbone.View
if activity.user.id == Kandan.Helpers.Users.currentUser().id
$(@el).addClass("current_user")

if user_mention_regex.test(@compiledTemplate) || all_mention_regex.test(@compiledTemplate)
# Only fire mentions if we are not loading old messages
if !@options.silence_mentions && (user_mention_regex.test(@compiledTemplate) || all_mention_regex.test(@compiledTemplate))
$(@el).addClass("mentioned_user")
Kandan.Plugins.Notifications?.playAudioNotification('attention')

Expand Down
8 changes: 6 additions & 2 deletions app/assets/stylesheets/_chat_area.sass
Expand Up @@ -114,8 +114,12 @@ html body .ui-tabs .ui-tabs-nav li
min-height: 110%
padding-bottom: 0px
.pagination
text-decoration: underline
cursor: pointer
text-align: center
font-size: 14px
span
position: relative
top: -6px
left: 10px
.channel-activities
width: 100%

Expand Down
2 changes: 1 addition & 1 deletion app/assets/templates/paginated_activities.jst.eco
@@ -1 +1 @@
<div class="pagination">previous messages</div>
<div class="pagination"><i class="icon-spinner icon-spin icon-2x"></i><span>Loading previous messages</span></div>

0 comments on commit 930039c

Please sign in to comment.