From b07def69015d4d464dcb83d5148d27b42ddb57e5 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 27 Jun 2014 15:45:14 +0100 Subject: [PATCH] Get infinite scroll auto-loading of track changes workikng --- .../views/project/editor/track-changes.jade | 102 ++++++++++-------- .../TrackChangesListController.coffee | 8 +- .../track-changes/TrackChangesManager.coffee | 18 ++-- .../directives/infiniteScroll.coffee | 45 ++++++++ .../stylesheets/app/editor/track-changes.less | 5 + 5 files changed, 124 insertions(+), 54 deletions(-) create mode 100644 services/web/public/coffee/app/ide/track-changes/directives/infiniteScroll.coffee diff --git a/services/web/app/views/project/editor/track-changes.jade b/services/web/app/views/project/editor/track-changes.jade index 8f76f92574..56fc7d2974 100644 --- a/services/web/app/views/project/editor/track-changes.jade +++ b/services/web/app/views/project/editor/track-changes.jade @@ -1,60 +1,68 @@ div#trackChanges(ng-show="ui.view == 'track-changes'") aside.change-list( ng-controller="TrackChangesListController" + infinite-scroll="loadMore()" + infinite-scroll-disabled="trackChanges.loading || trackChanges.atEnd" + infinite-scroll-initialize="ui.view == 'track-changes'" ) - ul.list-unstyled( - ng-class="{\ - 'hover-state': trackChanges.hoveringOverListSelectors\ - }" - ) - li.change( - ng-repeat="update in trackChanges.updates" + .infinite-scroll-inner + ul.list-unstyled( ng-class="{\ - 'first-in-day': update.meta.first_in_day,\ - 'selected': update.inSelection,\ - 'selected-to': update.selectedTo,\ - 'selected-from': update.selectedFrom,\ - 'hover-selected': update.inHoverSelection,\ - 'hover-selected-to': update.hoverSelectedTo,\ - 'hover-selected-from': update.hoverSelectedFrom,\ + 'hover-state': trackChanges.hoveringOverListSelectors\ }" - ng-controller="TrackChangesListItemController" ) + li.change( + ng-repeat="update in trackChanges.updates" + ng-class="{\ + 'first-in-day': update.meta.first_in_day,\ + 'selected': update.inSelection,\ + 'selected-to': update.selectedTo,\ + 'selected-from': update.selectedFrom,\ + 'hover-selected': update.inHoverSelection,\ + 'hover-selected-to': update.hoverSelectedTo,\ + 'hover-selected-from': update.hoverSelectedFrom,\ + }" + ng-controller="TrackChangesListItemController" + ) - div.day(ng-show="update.meta.first_in_day") {{ update.meta.end_ts | relativeDate }} + div.day(ng-show="update.meta.first_in_day") {{ update.meta.end_ts | relativeDate }} - div.selectors - div.range - form - input.selector-from( - type="radio" - name="fromVersion" - ng-model="update.selectedFrom" - ng-value="true" - ng-mouseover="mouseOverSelectedFrom()" - ng-mouseout="mouseOutSelectedFrom()" - ng-show="update.afterSelection || update.inSelection" - ) - form - input.selector-to( - type="radio" - name="toVersion" - ng-model="update.selectedTo" - ng-value="true" - ng-mouseover="mouseOverSelectedTo()" - ng-mouseout="mouseOutSelectedTo()" - ng-show="update.beforeSelection || update.inSelection" - ) + div.selectors + div.range + form + input.selector-from( + type="radio" + name="fromVersion" + ng-model="update.selectedFrom" + ng-value="true" + ng-mouseover="mouseOverSelectedFrom()" + ng-mouseout="mouseOutSelectedFrom()" + ng-show="update.afterSelection || update.inSelection" + ) + form + input.selector-to( + type="radio" + name="toVersion" + ng-model="update.selectedTo" + ng-value="true" + ng-mouseover="mouseOverSelectedTo()" + ng-mouseout="mouseOutSelectedTo()" + ng-show="update.beforeSelection || update.inSelection" + ) - div.description(ng-click="select()") - div.time {{ update.meta.end_ts | formatDate:'h:mm a' }} - div.docs(ng-repeat="(doc_id, doc) in update.docs") - span.doc {{ doc.entity.name }} - div.users - div.user(ng-repeat="update_user in update.meta.users") - .color-square(ng-style="{'background-color': 'hsl({{ update_user.hue }}, 100%, 50%)'}") - span(ng-if="update_user.id != user.id") {{user.first_name}} {{user.last_name}} - span(ng-if="update_user.id == user.id") You + div.description(ng-click="select()") + div.time {{ update.meta.end_ts | formatDate:'h:mm a' }} + div.docs(ng-repeat="(doc_id, doc) in update.docs") + span.doc {{ doc.entity.name }} + div.users + div.user(ng-repeat="update_user in update.meta.users") + .color-square(ng-style="{'background-color': 'hsl({{ update_user.hue }}, 100%, 50%)'}") + span(ng-if="update_user.id != user.id") {{user.first_name}} {{user.last_name}} + span(ng-if="update_user.id == user.id") You + + .loading(ng-show="trackChanges.loading") + i.fa.fa-spin.fa-refresh + |   Loading... .diff.full-size .diff-editor.hide-ace-cursor( diff --git a/services/web/public/coffee/app/ide/track-changes/TrackChangesListController.coffee b/services/web/public/coffee/app/ide/track-changes/TrackChangesListController.coffee index f1e87713f7..71b8497824 100644 --- a/services/web/public/coffee/app/ide/track-changes/TrackChangesListController.coffee +++ b/services/web/public/coffee/app/ide/track-changes/TrackChangesListController.coffee @@ -1,9 +1,12 @@ define [ "base" ], (App) -> - App.controller "TrackChangesListController", ["$scope", ($scope) -> + App.controller "TrackChangesListController", ["$scope", "ide", ($scope, ide) -> $scope.hoveringOverListSelectors = false + $scope.loadMore = () => + ide.trackChangesManager.fetchNextBatchOfUpdates() + $scope.recalculateSelectedUpdates = () -> console.log "RECALCULATING UPDATES" beforeSelection = true @@ -61,6 +64,9 @@ define [ delete update.hoverSelectedFrom delete update.hoverSelectedTo delete update.inHoverSelection + + $scope.$watch "trackChanges.updates.length", () -> + $scope.recalculateSelectedUpdates() ] App.controller "TrackChangesListItemController", ["$scope", ($scope) -> diff --git a/services/web/public/coffee/app/ide/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/app/ide/track-changes/TrackChangesManager.coffee index cfd6a0c7c3..2883a2514b 100644 --- a/services/web/public/coffee/app/ide/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/app/ide/track-changes/TrackChangesManager.coffee @@ -1,5 +1,6 @@ define [ "ide/track-changes/TrackChangesListController" + "ide/track-changes/directives/infiniteScroll" ], () -> class TrackChangesManager constructor: (@ide, @$scope) -> @@ -24,9 +25,9 @@ define [ onShow: () -> @reset() - @fetchNextBatchOfChanges() - .success () => - @autoSelectRecentUpdates() + # @fetchNextBatchOfChanges() + # .success () => + # @autoSelectRecentUpdates() reset: () -> @$scope.trackChanges = { @@ -61,10 +62,11 @@ define [ @$scope.trackChanges.updates[indexOfLastUpdateNotByMe].selectedFrom = true BATCH_SIZE: 4 - fetchNextBatchOfChanges: () -> + fetchNextBatchOfUpdates: () -> url = "/project/#{@ide.project_id}/updates?min_count=#{@BATCH_SIZE}" - if @nextBeforeTimestamp? + if @$scope.trackChanges.nextBeforeTimestamp? url += "&before=#{@$scope.trackChanges.nextBeforeTimestamp}" + @$scope.trackChanges.loading = true @ide.$http .get(url) .success (data) => @@ -72,9 +74,9 @@ define [ @$scope.trackChanges.nextBeforeTimestamp = data.nextBeforeTimestamp if !data.nextBeforeTimestamp? @$scope.trackChanges.atEnd = true + @$scope.trackChanges.loading = false reloadDiff: () -> - diff = @$scope.trackChanges.diff {updates, doc} = @$scope.trackChanges.selection {fromV, toV} = @_calculateRangeFromSelection() @@ -182,9 +184,13 @@ define [ previousUpdate = update + firstLoad = @$scope.trackChanges.updates.length == 0 + @$scope.trackChanges.updates = @$scope.trackChanges.updates.concat(updates) + @autoSelectRecentUpdates() if firstLoad + _calculateRangeFromSelection: () -> fromV = toV = start_ts = end_ts = null diff --git a/services/web/public/coffee/app/ide/track-changes/directives/infiniteScroll.coffee b/services/web/public/coffee/app/ide/track-changes/directives/infiniteScroll.coffee new file mode 100644 index 0000000000..550373e77c --- /dev/null +++ b/services/web/public/coffee/app/ide/track-changes/directives/infiniteScroll.coffee @@ -0,0 +1,45 @@ +define [ + "base" +], (App) -> + App.directive "infiniteScroll", () -> + return { + link: (scope, element, attrs, ctrl) -> + innerElement = element.find(".infinite-scroll-inner") + element.css 'overflow-y': 'auto' + + atEndOfListView = () -> + element.scrollTop() + element.height() >= innerElement.height() - 30 + + listShorterThanContainer = () -> + element.innerHeight() > @$(".change-list").outerHeight() + + loadUntilFull = () -> + if (listShorterThanContainer() or atEndOfListView()) and not scope.$eval(attrs.infiniteScrollDisabled) + console.log "Loading more" + promise = scope.$eval(attrs.infiniteScroll) + console.log promise + promise.then () -> + loadUntilFull() + # @collection.fetchNextBatch + # error: (error) => + # @hideLoading() + # @showEmptyMessageIfCollectionEmpty() + # callback(error) + # success: (collection, response) => + # @hideLoading() + # if @collection.isAtEnd() + # @atEndOfCollection = true + # @showEmptyMessageIfCollectionEmpty() + # callback() + # else + # @loadUntilFull(callback) + + element.on "scroll", (event) -> + loadUntilFull() + + scope.$watch attrs.infiniteScrollInitialize, (value) -> + console.log "INITIALIZE", value + if value + loadUntilFull() + + } \ No newline at end of file diff --git a/services/web/public/stylesheets/app/editor/track-changes.less b/services/web/public/stylesheets/app/editor/track-changes.less index ef3905a070..ca7f168006 100644 --- a/services/web/public/stylesheets/app/editor/track-changes.less +++ b/services/web/public/stylesheets/app/editor/track-changes.less @@ -138,6 +138,11 @@ right: 0; background-color: white; + .loading { + text-align: center; + font-family: @font-family-serif; + } + ul { li.change { position: relative;