Commit 3c9115cd authored by Hannah Stepanek's avatar Hannah Stepanek

Load annotations using the annotations service

- Load annotations using the new annotations service.
- Use the new store isFetchingAnnotations rather than the previous
isLoading method to determine whether an annotation fetch is currently
in progress.
parent 169f4689
'use strict';
const SearchClient = require('../search-client');
const events = require('../events');
const isThirdPartyService = require('../util/is-third-party-service');
const tabs = require('../tabs');
/**
* Returns the group ID of the first annotation in `results` whose
* ID is `annId`.
*/
function getGroupID(annId, results) {
const annot = results.find(function(annot) {
return annot.id === annId;
});
if (!annot) {
return null;
}
return annot.group;
}
// @ngInject
function SidebarContentController(
$scope,
analytics,
annotations,
store,
annotationMapper,
api,
features,
frameSync,
groups,
rootThread,
settings,
streamer,
streamFilter
streamer
) {
const self = this;
......@@ -90,61 +71,7 @@ function SidebarContentController(
}
}
const searchClients = [];
function _resetAnnotations() {
annotationMapper.unloadAnnotations(store.savedAnnotations());
}
function _loadAnnotationsFor(uris, group) {
const searchClient = new SearchClient(api.search, {
// If no group is specified, we are fetching annotations from
// all groups in order to find out which group contains the selected
// annotation, therefore we need to load all chunks before processing
// the results
incremental: !!group,
});
searchClients.push(searchClient);
searchClient.on('results', function(results) {
if (store.hasSelectedAnnotations()) {
// Focus the group containing the selected annotation and filter
// annotations to those from this group
let groupID = getGroupID(store.getFirstSelectedAnnotationId(), results);
if (!groupID) {
// If the selected annotation is not available, fall back to
// loading annotations for the currently focused group
groupID = groups.focused().id;
}
results = results.filter(function(result) {
return result.group === groupID;
});
groups.focus(groupID);
}
if (results.length) {
annotationMapper.loadAnnotations(results);
}
});
searchClient.on('end', function() {
// Remove client from list of active search clients.
//
// $evalAsync is required here because search results are emitted
// asynchronously. A better solution would be that the loading state is
// tracked as part of the app state.
$scope.$evalAsync(function() {
searchClients.splice(searchClients.indexOf(searchClient), 1);
});
store.frames().forEach(function(frame) {
if (0 <= uris.indexOf(frame.uri)) {
store.updateFrameAnnotationFetchStatus(frame.uri, true);
}
});
});
searchClient.get({ uri: uris, group: group });
}
this.isLoading = function() {
this.isLoading = () => {
if (
!store.frames().some(function(frame) {
return frame.uri;
......@@ -153,47 +80,9 @@ function SidebarContentController(
// The document's URL isn't known so the document must still be loading.
return true;
}
if (searchClients.length > 0) {
// We're still waiting for annotation search results from the API.
return true;
}
return false;
return store.isFetchingAnnotations();
};
/**
* Load annotations for all URLs associated with `frames`.
*/
function loadAnnotations() {
_resetAnnotations();
searchClients.forEach(function(client) {
client.cancel();
});
// If there is no selection, load annotations only for the focused group.
//
// If there is a selection, we load annotations for all groups, find out
// which group the first selected annotation is in and then filter the
// results on the client by that group.
//
// In the common case where the total number of annotations on
// a page that are visible to the user is not greater than
// the batch size, this saves an extra roundtrip to the server
// to fetch the selected annotation in order to determine which group
// it is in before fetching the remaining annotations.
const group = store.hasSelectedAnnotations() ? null : groups.focused().id;
const searchUris = store.searchUris();
if (searchUris.length > 0) {
_loadAnnotationsFor(searchUris, group);
streamFilter.resetFilter().addClause('/uri', 'one_of', searchUris);
streamer.setConfig('filter', { filter: streamFilter.getFilter() });
}
}
$scope.$on('sidebarOpened', function() {
analytics.track(analytics.events.SIDEBAR_OPENED);
......@@ -247,17 +136,11 @@ function SidebarContentController(
}
if (!prevGroupId || currentGroupId !== prevGroupId) {
// The focused group may be changed during loading annotations as a result
// of switching to the group containing a direct-linked annotation.
//
// In that case, we don't want to trigger reloading annotations again.
if (this.isLoading()) {
return;
}
store.clearSelectedAnnotations();
}
loadAnnotations();
const searchUris = store.searchUris();
annotations.load(searchUris, currentGroupId);
},
true
);
......@@ -281,7 +164,7 @@ function SidebarContentController(
this.scrollTo = scrollToAnnotation;
this.selectedGroupUnavailable = function() {
return !this.isLoading() && store.getState().directLinkedGroupFetchFailed;
return store.getState().directLinkedGroupFetchFailed;
};
this.selectedAnnotationUnavailable = function() {
......@@ -314,7 +197,9 @@ function SidebarContentController(
// selection is available to the user, show the CTA.
const selectedID = store.getFirstSelectedAnnotationId();
return (
!this.isLoading() && !!selectedID && store.annotationExists(selectedID)
!store.isFetchingAnnotations() &&
!!selectedID &&
store.annotationExists(selectedID)
);
};
}
......
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