Skip to content

Commit

Permalink
Merge pull request #2326 from daostack/bugfix/CW-2317-unread-inbox-cache
Browse files Browse the repository at this point in the history
Inbox unread filter fixes #2317
  • Loading branch information
andreymikhadyuk authored Nov 21, 2023
2 parents 76f501f + 655a8e4 commit 82ebb55
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 32 deletions.
6 changes: 5 additions & 1 deletion src/services/Chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,16 @@ class ChatService {
participantId: string;
startAt?: Timestamp;
endAt?: Timestamp;
onlyWithMessages?: boolean;
}): Promise<ChatChannel[]> => {
const { participantId, startAt, endAt } = options;
const { participantId, startAt, endAt, onlyWithMessages = false } = options;
let query = this.getChatChannelCollection()
.where("participants", "array-contains", participantId)
.orderBy("updatedAt", "desc");

if (onlyWithMessages) {
query = query.where("messageCount", ">", 0);
}
if (startAt) {
query = query.startAt(startAt);
}
Expand Down
22 changes: 17 additions & 5 deletions src/shared/hooks/useCases/useInboxItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,14 @@ export const useInboxItems = (
const inboxItems = useSelector(selectInboxItems);
const user = useSelector(selectUser());
const userId = user?.uid;
const unread = options?.unread;
const lastBatch = newItemsBatches[0];

const fetch = () => {
dispatch(
inboxActions.getInboxItems.request({
limit: 15,
unread: options?.unread,
unread,
}),
);
};
Expand Down Expand Up @@ -213,6 +214,7 @@ export const useInboxItems = (
participantId: userId,
startAt,
endAt,
onlyWithMessages: true,
}),
FeedItemFollowsService.getFollowFeedItems({
userId,
Expand Down Expand Up @@ -250,7 +252,7 @@ export const useInboxItems = (
}, []);

useEffect(() => {
if (!inboxItems.firstDocTimestamp || !userId) {
if (!inboxItems.firstDocTimestamp || !userId || unread) {
return;
}

Expand All @@ -263,10 +265,15 @@ export const useInboxItems = (
);

return unsubscribe;
}, [inboxItems.firstDocTimestamp, userId, feedItemIdsForNotListening]);
}, [
inboxItems.firstDocTimestamp,
userId,
feedItemIdsForNotListening,
unread,
]);

useEffect(() => {
if (!inboxItems.firstDocTimestamp || !userId) {
if (!inboxItems.firstDocTimestamp || !userId || unread) {
return;
}

Expand All @@ -280,7 +287,12 @@ export const useInboxItems = (
);

return unsubscribe;
}, [inboxItems.firstDocTimestamp, userId, feedItemIdsForNotListening]);
}, [
inboxItems.firstDocTimestamp,
userId,
feedItemIdsForNotListening,
unread,
]);

useEffect(() => {
if (!lastBatch) {
Expand Down
6 changes: 6 additions & 0 deletions src/shared/utils/queryParams.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import queryString from "query-string";
import { history } from "@/shared/appConfig";

export const getQueryParam = (key: string): string | null => {
const urlParams = new URLSearchParams(window.location.search);

return urlParams.get(key);
};

export const addQueryParam = (key: string, value: string) => {
const params = queryString.parse(window.location.search);
const search = queryString.stringify({
Expand Down
6 changes: 5 additions & 1 deletion src/store/states/inbox/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
export * as inboxActions from "./actions";
export { reducer as inboxReducer } from "./reducer";
export {
reducer as inboxReducer,
INITIAL_INBOX_ITEMS,
INITIAL_INBOX_STATE,
} from "./reducer";
export { mainSaga as inboxSaga } from "./saga";
export * from "./selectors";
export * from "./types";
16 changes: 9 additions & 7 deletions src/store/states/inbox/reducer.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
import produce from "immer";
import { WritableDraft } from "immer/dist/types/types-external";
import { ActionType, createReducer } from "typesafe-actions";
import { InboxItemType } from "@/shared/constants";
import { InboxItemType, QueryParamKey } from "@/shared/constants";
import {
checkIsChatChannelLayoutItem,
checkIsFeedItemFollowLayoutItem,
FeedLayoutItemWithFollowData,
} from "@/shared/interfaces";
import { ChatChannel, CommonFeed, Timestamp } from "@/shared/models";
import { getQueryParam } from "@/shared/utils/queryParams";
import * as actions from "./actions";
import { InboxItems, InboxState } from "./types";
import { getFeedLayoutItemDateForSorting } from "./utils";

type Action = ActionType<typeof actions>;

const initialInboxItems: InboxItems = {
export const INITIAL_INBOX_ITEMS: InboxItems = {
data: null,
loading: false,
hasMore: false,
firstDocTimestamp: null,
lastDocTimestamp: null,
batchNumber: 0,
unread: getQueryParam(QueryParamKey.Unread) === "true",
};

const initialState: InboxState = {
items: { ...initialInboxItems },
export const INITIAL_INBOX_STATE: InboxState = {
items: { ...INITIAL_INBOX_ITEMS },
sharedFeedItemId: null,
sharedItem: null,
chatChannelItems: [],
Expand Down Expand Up @@ -410,8 +412,8 @@ const updateChatChannelItem = (
updateChatChannelItemInSharedInboxItem(state, payload);
};

export const reducer = createReducer<InboxState, Action>(initialState)
.handleAction(actions.resetInbox, () => ({ ...initialState }))
export const reducer = createReducer<InboxState, Action>(INITIAL_INBOX_STATE)
.handleAction(actions.resetInbox, () => ({ ...INITIAL_INBOX_STATE }))
.handleAction(actions.getInboxItems.request, (state) =>
produce(state, (nextState) => {
nextState.items = {
Expand Down Expand Up @@ -542,7 +544,7 @@ export const reducer = createReducer<InboxState, Action>(initialState)
)
.handleAction(actions.resetInboxItems, (state) =>
produce(state, (nextState) => {
nextState.items = { ...initialInboxItems };
nextState.items = { ...INITIAL_INBOX_ITEMS };
nextState.sharedFeedItemId = null;
nextState.sharedItem = null;
nextState.chatChannelItems = [];
Expand Down
3 changes: 2 additions & 1 deletion src/store/states/inbox/saga/getInboxItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function* getInboxItems(
action: ReturnType<typeof actions.getInboxItems.request>,
) {
const {
payload: { limit, unread },
payload: { limit, unread = false },
} = action;

try {
Expand Down Expand Up @@ -72,6 +72,7 @@ export function* getInboxItems(
firstDocTimestamp: isFirstRequest
? firstDocTimestamp
: currentItems.firstDocTimestamp,
unread,
}),
);
} catch (error) {
Expand Down
1 change: 1 addition & 0 deletions src/store/states/inbox/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface InboxItems {
firstDocTimestamp: Timestamp | null;
lastDocTimestamp: Timestamp | null;
batchNumber: number;
unread: boolean;
}

export interface InboxState {
Expand Down
52 changes: 35 additions & 17 deletions src/store/transforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,22 @@ import { deserializeFeedLayoutItemWithFollowData } from "@/shared/interfaces";
import { convertObjectDatesToFirestoreTimestamps } from "@/shared/utils";
import { getFeedLayoutItemDateForSorting } from "@/store/states/inbox/utils";
import { CommonLayoutState } from "./states/commonLayout";
import { InboxItems, InboxState } from "./states/inbox";
import {
InboxItems,
InboxState,
INITIAL_INBOX_ITEMS,
INITIAL_INBOX_STATE,
} from "./states/inbox";

export const inboxTransform = createTransform(
(inboundState: InboxState) => {
if (inboundState.items.unread) {
return {
...inboundState,
items: { ...INITIAL_INBOX_ITEMS },
};
}

const data =
inboundState.items.data && inboundState.items.data.slice(0, 30);

Expand All @@ -26,22 +38,28 @@ export const inboxTransform = createTransform(
},
};
},
(outboundState: InboxState) => ({
...outboundState,
sharedItem:
outboundState.sharedItem &&
deserializeFeedLayoutItemWithFollowData(outboundState.sharedItem),
chatChannelItems: [],
items: {
...convertObjectDatesToFirestoreTimestamps<InboxItems>(
outboundState.items,
["firstDocTimestamp", "lastDocTimestamp"],
),
data:
outboundState.items.data &&
outboundState.items.data.map(deserializeFeedLayoutItemWithFollowData),
},
}),
(outboundState: InboxState) => {
if (outboundState.items.unread !== INITIAL_INBOX_ITEMS.unread) {
return { ...INITIAL_INBOX_STATE };
}

return {
...outboundState,
sharedItem:
outboundState.sharedItem &&
deserializeFeedLayoutItemWithFollowData(outboundState.sharedItem),
chatChannelItems: [],
items: {
...convertObjectDatesToFirestoreTimestamps<InboxItems>(
outboundState.items,
["firstDocTimestamp", "lastDocTimestamp"],
),
data:
outboundState.items.data &&
outboundState.items.data.map(deserializeFeedLayoutItemWithFollowData),
},
};
},
{ whitelist: ["inbox"] },
);

Expand Down

0 comments on commit 82ebb55

Please sign in to comment.