Unverified Commit b485628f authored by Hannah Stepanek's avatar Hannah Stepanek Committed by GitHub

Merge pull request #1124 from hypothesis/simplify-groups-load-part-2

Simplify groups service `load` method using async/await
parents b22b7a3e ee9e092c
...@@ -138,7 +138,7 @@ function groups( ...@@ -138,7 +138,7 @@ function groups(
// to include groups associated with this page. This is retained to determine // to include groups associated with this page. This is retained to determine
// whether we need to re-fetch groups if the URLs of frames connected to the // whether we need to re-fetch groups if the URLs of frames connected to the
// sidebar app changes. // sidebar app changes.
let documentUri; let documentUri = null;
/* /*
* Fetch an individual group. * Fetch an individual group.
...@@ -158,169 +158,145 @@ function groups( ...@@ -158,169 +158,145 @@ function groups(
* group. * group.
* *
* The groups that are fetched depend on the current user, the URI of * The groups that are fetched depend on the current user, the URI of
* the current document, and whether any direct-links were followed (either * the current document, and the direct-linked group and/or annotation.
* to an annotation or group).
* *
* @return {Promise<Group[]>} * @return {Promise<Group[]>}
*/ */
function load() { async function load() {
let uri = Promise.resolve(null); // Step 1: Get the URI of the active document, so we can fetch groups
// associated with that document.
if (isSidebar) { if (isSidebar) {
uri = getDocumentUriForGroupSearch(); documentUri = await getDocumentUriForGroupSearch();
} }
const directLinkedGroupId = store.getState().directLinkedGroupId;
const directLinkedAnnId = store.getState().directLinkedAnnotationId; // Step 2: Concurrently fetch the groups the user is a member of,
// the groups associated with the current document and the annotation
// and/or group that was direct-linked (if any).
const params = { const params = {
expand: ['organization', 'scopes'], expand: ['organization', 'scopes'],
}; };
if (authority) {
params.authority = authority;
}
if (documentUri) {
params.document_uri = documentUri;
}
let directLinkedAnnotationGroupId = null; // If there is a direct-linked annotation, fetch the annotation in case
// the associated group has not already been fetched and we need to make
// an additional request for it.
const directLinkedAnnId = store.getState().directLinkedAnnotationId;
let directLinkedAnnApi = null;
if (directLinkedAnnId) {
directLinkedAnnApi = api.annotation
.get({ id: directLinkedAnnId })
.catch(() => {
// If the annotation does not exist or the user doesn't have permission.
return null;
});
}
// Step 1: Get the URI of the active document, so we can fetch groups // If there is a direct-linked group, add an API request to get that
// associated with that document. // particular group since it may not be in the set of groups that are
return uri // fetched by other requests.
.then(uri => { const directLinkedGroupId = store.getState().directLinkedGroupId;
// Step 2: Concurrently fetch the groups the user is a member of, let directLinkedGroupApi = null;
// the groups associated with the current document and the annotation if (directLinkedGroupId) {
// or group that was direct-linked (if any). directLinkedGroupApi = fetchGroup({
if (authority) { id: directLinkedGroupId,
params.authority = authority; expand: params.expand,
} }).then(group => {
if (uri) { // If the group does not exist or the user doesn't have permission.
params.document_uri = uri; if (group === null) {
store.setDirectLinkedGroupFetchFailed();
} else {
store.clearDirectLinkedGroupFetchFailed();
} }
documentUri = uri; return group;
});
}
const profileGroupsApi = api.profile.groups.read({ const [
myGroups,
featuredGroups,
token,
directLinkedAnn,
directLinkedGroup,
] = await Promise.all([
api.profile.groups.read({ expand: params.expand }),
api.groups.list(params),
auth.tokenGetter(),
directLinkedAnnApi,
directLinkedGroupApi,
]);
// Step 3. Add the direct-linked group to the list of featured groups,
// and if there was a direct-linked annotation, fetch its group if we
// don't already have it.
// If there is a direct-linked group, add it to the featured groups list.
if (
directLinkedGroup &&
!featuredGroups.some(g => g.id === directLinkedGroup.id)
) {
featuredGroups.push(directLinkedGroup);
}
// If there's a direct-linked annotation it may require an extra API call
// to fetch its group.
let directLinkedAnnotationGroupId = null;
if (directLinkedAnn) {
// Set the directLinkedAnnotationGroupId to be used later in
// the filterGroups method.
directLinkedAnnotationGroupId = directLinkedAnn.group;
// If the direct-linked annotation's group has not already been fetched,
// fetch it.
const directLinkedAnnGroup = myGroups
.concat(featuredGroups)
.find(g => g.id === directLinkedAnn.group);
if (!directLinkedAnnGroup) {
const directLinkedAnnGroup = await fetchGroup({
id: directLinkedAnn.group,
expand: params.expand, expand: params.expand,
}); });
const listGroupsApi = api.groups.list(params); if (directLinkedAnnGroup) {
let groupApiRequests = [ featuredGroups.push(directLinkedAnnGroup);
profileGroupsApi,
listGroupsApi,
auth.tokenGetter(),
];
// If there is a direct-linked annotation, fetch the annotation to see
// if there needs to be a second API request to fetch its group since
// the group may not be in the results returned by group.list,
// profile.groups, or the direct-linked group.
let directLinkedAnnApi = Promise.resolve(null);
if (directLinkedAnnId) {
directLinkedAnnApi = api.annotation
.get({ id: directLinkedAnnId })
.catch(() => {
// If the annotation does not exist or the user doesn't have permission.
return null;
});
}
groupApiRequests = groupApiRequests.concat(directLinkedAnnApi);
// If there is a direct-linked group, add an API request to get that
// particular group since it may not be in the results returned by
// group.list or profile.groups.
let directLinkedGroupApi = Promise.resolve(null);
if (directLinkedGroupId) {
directLinkedGroupApi = fetchGroup({
id: directLinkedGroupId,
expand: params.expand,
}).then(group => {
// If the group does not exist or the user doesn't have permission.
if (group === null) {
store.setDirectLinkedGroupFetchFailed();
} else {
store.clearDirectLinkedGroupFetchFailed();
}
return group;
});
}
groupApiRequests = groupApiRequests.concat(directLinkedGroupApi);
return Promise.all(groupApiRequests);
})
.then(
([
myGroups,
featuredGroups,
token,
directLinkedAnn,
directLinkedGroup,
]) => {
// Step 3. Add the direct-linked group to the list of featured groups,
// and if there was a direct-linked annotation, fetch its group if we
// don't already have it.
// If there is a direct-linked group, add it to the featured groups list.
let allFeaturedGroups =
directLinkedGroup !== null &&
!featuredGroups.some(g => g.id === directLinkedGroup.id)
? featuredGroups.concat([directLinkedGroup])
: featuredGroups;
// If there's a direct-linked annotation it may require an extra API call
// to fetch its group.
if (directLinkedAnn) {
// Set the directLinkedAnnotationGroupId to be used later in
// the filterGroups method.
directLinkedAnnotationGroupId = directLinkedAnn.group;
const directLinkedAnnGroup = myGroups
.concat(allFeaturedGroups)
.some(g => g.id === directLinkedAnn.group);
// If the direct-linked annotation's group has not already been fetched,
// fetch it.
if (!directLinkedAnnGroup) {
const initialFeaturedGroups = allFeaturedGroups;
allFeaturedGroups = fetchGroup({
id: directLinkedAnn.group,
expand: params.expand,
}).then(directLinkedAnnGroup => {
if (!directLinkedAnnGroup) {
return initialFeaturedGroups;
}
return initialFeaturedGroups.concat(directLinkedAnnGroup);
});
}
}
return Promise.all([myGroups, allFeaturedGroups, documentUri, token]);
}
)
.then(([myGroups, featuredGroups, documentUri, token]) => {
// Step 4. Combine all the groups into a single list and set additional
// metadata on them that will be used elsewhere in the app.
const isLoggedIn = token !== null;
const groups = filterGroups(
combineGroups(myGroups, featuredGroups, documentUri),
isLoggedIn,
directLinkedAnnotationGroupId,
directLinkedGroupId
);
injectOrganizations(groups);
// Step 5. Load the groups into the store and focus the appropriate
// group.
const isFirstLoad = store.allGroups().length === 0;
const prevFocusedGroup = localStorage.getItem(STORAGE_KEY);
store.loadGroups(groups);
if (
isFirstLoad &&
groups.some(g => g.id === directLinkedAnnotationGroupId)
) {
store.focusGroup(directLinkedAnnotationGroupId);
} else if (
isFirstLoad &&
groups.some(g => g.id === directLinkedGroupId)
) {
store.focusGroup(directLinkedGroupId);
} else if (isFirstLoad && groups.some(g => g.id === prevFocusedGroup)) {
store.focusGroup(prevFocusedGroup);
} }
}
}
return groups; // Step 4. Combine all the groups into a single list and set additional
}); // metadata on them that will be used elsewhere in the app.
const isLoggedIn = token !== null;
const groups = filterGroups(
combineGroups(myGroups, featuredGroups, documentUri),
isLoggedIn,
directLinkedAnnotationGroupId,
directLinkedGroupId
);
injectOrganizations(groups);
// Step 5. Load the groups into the store and focus the appropriate
// group.
const isFirstLoad = store.allGroups().length === 0;
const prevFocusedGroup = localStorage.getItem(STORAGE_KEY);
store.loadGroups(groups);
if (isFirstLoad) {
if (groups.some(g => g.id === directLinkedAnnotationGroupId)) {
store.focusGroup(directLinkedAnnotationGroupId);
} else if (groups.some(g => g.id === directLinkedGroupId)) {
store.focusGroup(directLinkedGroupId);
} else if (groups.some(g => g.id === prevFocusedGroup)) {
store.focusGroup(prevFocusedGroup);
}
}
return groups;
} }
const sortGroups = memoize(groups => { const sortGroups = memoize(groups => {
......
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