Skip to content

Commit

Permalink
Merge pull request #2243 from daostack/feature/CW-2234-breadcrumbs
Browse files Browse the repository at this point in the history
make breadcrumb appear faster #2234
  • Loading branch information
MeyerPV authored Oct 25, 2023
2 parents 5e7efdc + 6e1ba0d commit 3de41c9
Show file tree
Hide file tree
Showing 32 changed files with 633 additions and 238 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ export default function CreateCommonModal(props: CreateCommonModalProps) {
image: createdCommonData.common.image,
name: createdCommonData.common.name,
directParent: createdCommonData.common.directParent,
rootCommonId: createdCommonData.common.rootCommonId,
hasMembership: true,
hasPermissionToAddProject,
notificationsAmount: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const CommonCreation: FC = () => {
image: common.image,
name: common.name,
directParent: common.directParent,
rootCommonId: common.rootCommonId,
hasMembership: true,
hasPermissionToAddProject,
notificationsAmount: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const ProjectCreation: FC<ProjectCreationProps> = (props) => {
image: createdProject.image,
name: createdProject.name,
directParent: createdProject.directParent,
rootCommonId: createdProject.rootCommonId,
hasMembership: true,
hasPermissionToAddProject: Object.values(governance.circles).some(
(circle) => circle.allowedActions[GovernanceActions.CREATE_PROJECT],
Expand Down
65 changes: 65 additions & 0 deletions src/services/Common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,38 @@ class CommonService {
.reduce((acc, items) => [...acc, ...items], []);
};

public subscribeToCommonsByDirectParentId = (
parentCommonId: string,
callback: (
data: {
common: Common;
statuses: {
isAdded: boolean;
isRemoved: boolean;
};
}[],
) => void,
): UnsubscribeFunction => {
const query = firebase
.firestore()
.collection(Collection.Daos)
.where("state", "==", CommonState.ACTIVE)
.where("directParent.commonId", "==", parentCommonId)
.withConverter(converter);

return query.onSnapshot((snapshot) => {
callback(
snapshot.docChanges().map((docChange) => ({
common: docChange.doc.data(),
statuses: {
isAdded: docChange.type === DocChange.Added,
isRemoved: docChange.type === DocChange.Removed,
},
})),
);
});
};

public getUserCommonIds = async (userId: string): Promise<string[]> =>
(
await firebase
Expand All @@ -144,6 +176,39 @@ class CommonService {
}));
};

public subscribeToAllUserCommonMemberInfo = (
userId: string,
callback: (
data: {
commonId: string;
commonMember: CommonMember;
statuses: {
isAdded: boolean;
isRemoved: boolean;
};
}[],
) => void,
): UnsubscribeFunction => {
const query = firebase
.firestore()
.collectionGroup(SubCollections.Members)
.where("userId", "==", userId)
.withConverter(commonMemberConverter);

return query.onSnapshot((snapshot) => {
callback(
snapshot.docChanges().map((docChange) => ({
commonId: docChange.doc.ref.path.split("/")[1],
commonMember: docChange.doc.data(),
statuses: {
isAdded: docChange.type === DocChange.Added,
isRemoved: docChange.type === DocChange.Removed,
},
})),
);
});
};

public getCommonsWithSubCommons = async (
commonIds: string[],
): Promise<Common[]> => {
Expand Down
32 changes: 32 additions & 0 deletions src/services/Governance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { governanceCollection } from "@/pages/OldCommon/store/api";
import { DocChange } from "@/shared/constants";
import { UnsubscribeFunction } from "@/shared/interfaces";
import { Collection, Governance } from "@/shared/models";
import {
Expand Down Expand Up @@ -64,6 +65,37 @@ class GovernanceService {
}
});
};

public subscribeToGovernanceListByCommonIds = (
commonIds: string[],
callback: (
data: {
governance: Governance;
statuses: {
isAdded: boolean;
isRemoved: boolean;
};
}[],
) => void,
): UnsubscribeFunction => {
const query = firebase
.firestore()
.collection(Collection.Governance)
.where("commonId", "in", commonIds)
.withConverter(converter);

return query.onSnapshot((snapshot) => {
callback(
snapshot.docChanges().map((docChange) => ({
governance: docChange.doc.data(),
statuses: {
isAdded: docChange.type === DocChange.Added,
isRemoved: docChange.type === DocChange.Removed,
},
})),
);
});
};
}

export default new GovernanceService();
3 changes: 3 additions & 0 deletions src/shared/hooks/useCases/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
export { useAllUserCommonMemberInfo } from "./useAllUserCommonMemberInfo";
export { useChatChannelUserStatus } from "./useChatChannelUserStatus";
export { useChatMessages } from "./useChatMessages";
export { useCommon } from "./useCommon";
export { useCommonFeedItems } from "./useCommonFeedItems";
export { useCommonMembersWithCircleIdsAmount } from "./useCommonMembersWithCircleIdsAmount";
export { useCommonRulesAcceptance } from "./useCommonRulesAcceptance";
export { useCommonsByDirectParentId } from "./useCommonsByDirectParentId";
export { useDiscussionById } from "./useDiscussionById";
export { useDMUserChatChannel } from "./useDMUserChatChannel";
export { useFeedItemUserMetadata } from "./useFeedItemUserMetadata";
Expand All @@ -28,6 +30,7 @@ export { useUserFeedItemFollowData } from "./useUserFeedItemFollowData";
export { useFeedItemFollow } from "./useFeedItemFollow";
export type { FeedItemFollowState } from "./useFeedItemFollow";
export { useGovernance } from "./useGovernance";
export { useGovernanceListByCommonIds } from "./useGovernanceListByCommonIds";
export { useGovernanceByCommonId } from "./useGovernanceByCommonId";
export { useUserInfoAboutMemberships } from "./useUserInfoAboutMemberships";
export { useBankAccountDetails } from "./useBankAccountDetails";
Expand Down
87 changes: 87 additions & 0 deletions src/shared/hooks/useCases/useAllUserCommonMemberInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { selectUser } from "@/pages/Auth/store/selectors";
import { CommonService } from "@/services";
import { Awaited, LoadingState } from "@/shared/interfaces";

type State = LoadingState<Awaited<
ReturnType<typeof CommonService.getAllUserCommonMemberInfo>
> | null>;

type Return = State;

export const useAllUserCommonMemberInfo = (): Return => {
const user = useSelector(selectUser());
const userId = user?.uid;
const [state, setState] = useState<State>({
loading: true,
fetched: false,
data: null,
});

useEffect(() => {
if (!userId) {
return;
}

const unsubscribe = CommonService.subscribeToAllUserCommonMemberInfo(
userId,
(data) => {
setState((currentState) => {
if (!currentState.data || currentState.data.length === 0) {
return {
loading: false,
fetched: true,
data: data.map((item) => ({
...item.commonMember,
commonId: item.commonId,
})),
};
}

const nextData = [...currentState.data];

data.forEach((item) => {
const itemIndex = nextData.findIndex(
({ commonId }) => commonId === item.commonId,
);

if (itemIndex === -1) {
nextData.push({
...item.commonMember,
commonId: item.commonId,
});
return;
}

if (item.statuses.isRemoved) {
nextData.splice(itemIndex, 1);
} else {
nextData[itemIndex] = {
...item.commonMember,
commonId: item.commonId,
};
}
});

return {
loading: false,
fetched: true,
data: nextData,
};
});
},
);

return () => {
unsubscribe();
setState({
loading: true,
fetched: false,
data: null,
});
};
}, [userId]);

return state;
};
73 changes: 73 additions & 0 deletions src/shared/hooks/useCases/useCommonsByDirectParentId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { useEffect, useState } from "react";
import { CommonService } from "@/services";
import { LoadingState } from "@/shared/interfaces";
import { Common } from "@/shared/models";

type State = LoadingState<Common[] | null>;

type Return = State;

export const useCommonsByDirectParentId = (parentCommonId?: string): Return => {
const [state, setState] = useState<State>({
loading: true,
fetched: false,
data: null,
});

useEffect(() => {
if (!parentCommonId) {
return;
}

const unsubscribe = CommonService.subscribeToCommonsByDirectParentId(
parentCommonId,
(data) => {
setState((currentState) => {
if (!currentState.data || currentState.data.length === 0) {
return {
loading: false,
fetched: true,
data: data.map((item) => item.common),
};
}

const nextData = [...currentState.data];

data.forEach((item) => {
const itemIndex = nextData.findIndex(
({ id }) => id === item.common.id,
);

if (itemIndex === -1) {
nextData.push(item.common);
return;
}

if (item.statuses.isRemoved) {
nextData.splice(itemIndex, 1);
} else {
nextData[itemIndex] = item.common;
}
});

return {
loading: false,
fetched: true,
data: nextData,
};
});
},
);

return () => {
unsubscribe();
setState({
loading: true,
fetched: false,
data: null,
});
};
}, [parentCommonId]);

return state;
};
66 changes: 66 additions & 0 deletions src/shared/hooks/useCases/useGovernanceListByCommonIds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { useEffect, useState } from "react";
import { GovernanceService } from "@/services";
import { LoadingState } from "@/shared/interfaces";
import { Governance } from "@/shared/models";

type State = LoadingState<Governance[] | null>;

type Return = State;

export const useGovernanceListByCommonIds = (commonIds: string[]): Return => {
const [state, setState] = useState<State>({
loading: true,
fetched: false,
data: null,
});

useEffect(() => {
if (commonIds.length === 0) {
return;
}

const unsubscribe = GovernanceService.subscribeToGovernanceListByCommonIds(
commonIds,
(data) => {
setState((currentState) => {
if (!currentState.data || currentState.data.length === 0) {
return {
loading: false,
fetched: true,
data: data.map((item) => item.governance),
};
}

const nextData = [...currentState.data];

data.forEach((item) => {
const itemIndex = nextData.findIndex(
({ id }) => id === item.governance.id,
);

if (itemIndex === -1) {
nextData.push(item.governance);
return;
}

if (item.statuses.isRemoved) {
nextData.splice(itemIndex, 1);
} else {
nextData[itemIndex] = item.governance;
}
});

return {
loading: false,
fetched: true,
data: nextData,
};
});
},
);

return unsubscribe;
}, [commonIds]);

return state;
};
Loading

0 comments on commit 3de41c9

Please sign in to comment.