Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions packages/shared/src/hooks/feed/useAdvancedSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import useTagAndSource from '../useTagAndSource';
import { Origin } from '../../lib/log';

interface UseAdvancedSettings {
selectedSettings: Record<string, boolean>;
selectedSettings: Record<number, boolean>;
onToggleSettings(id: number, state: boolean): void;
onToggleSource(source: Source): void;
onUpdateSettings(
Expand All @@ -30,11 +30,14 @@ export const useAdvancedSettings = (

const selectedSettings = useMemo(
() =>
feedSettings?.advancedSettings?.reduce((settingsMap, currentSettings) => {
const map = { ...settingsMap };
map[currentSettings.id] = currentSettings.enabled;
return map;
}, {}) || {},
feedSettings?.advancedSettings?.reduce<Record<number, boolean>>(
(settingsMap, currentSettings) => {
const map = { ...settingsMap };
map[currentSettings.id] = currentSettings.enabled;
return map;
},
{},
) || {},
[feedSettings?.advancedSettings],
);

Expand All @@ -61,7 +64,7 @@ export const useAdvancedSettings = (
const onToggleSettings = useCallback(
(id: number, defaultEnabledState: boolean) => {
if (alerts?.filter && user) {
updateAlerts({ filter: false });
updateAlerts?.({ filter: false });
}

const enabled = !(selectedSettings[id] ?? defaultEnabledState);
Expand Down
6 changes: 3 additions & 3 deletions packages/shared/src/hooks/feed/useAutoRotatingAds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const useAutoRotatingAds = (
const rotationTime = autorotateAds * 1_000;

const refs = useCallback(
(node: HTMLElement) => {
(node?: Element | null) => {
ref?.(node);
inViewRef(node);
},
Expand All @@ -49,14 +49,14 @@ export const useAutoRotatingAds = (

const { fetchAd } = useFetchAd();
const queryKey = useMemo(
() => [RequestKey.Ads, ...feedQueryKey],
() => [RequestKey.Ads, ...(feedQueryKey ?? [])],
[feedQueryKey],
);

const fetchNewAd = useCallback(async (): Promise<Ad> => {
const newAd = await fetchAd({ active: true });
if (!newAd) {
return null;
throw new Error('Unable to fetch replacement ad');
}

// End the impression event for the old ad
Expand Down
5 changes: 3 additions & 2 deletions packages/shared/src/hooks/feed/useCustomDefaultFeed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ const useCustomDefaultFeed = (): UseCustomDefaultFeed => {
const { user } = useAuthContext();

return {
isCustomDefaultFeed: user?.defaultFeedId && user.defaultFeedId !== user?.id,
defaultFeedId: user?.defaultFeedId ?? user?.id,
isCustomDefaultFeed:
!!user?.defaultFeedId && user.defaultFeedId !== user?.id,
defaultFeedId: user?.defaultFeedId ?? user?.id ?? '',
};
};

Expand Down
8 changes: 4 additions & 4 deletions packages/shared/src/hooks/feed/useFeedContextMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ type FeedContextMenu = {
row: number,
column: number,
) => void;
postMenuIndex: number;
postMenuLocation: PostLocation;
postMenuIndex: number | undefined;
postMenuLocation: PostLocation | undefined;
setPostMenuIndex: (value: PostLocation | undefined) => void;
};

Expand All @@ -39,7 +39,7 @@ export default function useFeedContextMenu(): FeedContextMenu {
column: number,
) => {
if (postMenuIndex === index) {
setPostMenuLocation(null);
setPostMenuLocation(undefined);
return;
}
setPostMenuLocation({ index, row, column });
Expand All @@ -53,7 +53,7 @@ export default function useFeedContextMenu(): FeedContextMenu {
column: number,
) => {
if (postMenuIndex === index) {
setPostMenuLocation(null);
setPostMenuLocation(undefined);
return;
}
setPostMenuLocation({ index, row, column });
Expand Down
39 changes: 30 additions & 9 deletions packages/shared/src/hooks/feed/useFeeds.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { renderHook, waitFor } from '@testing-library/react';
import defaultUser from '../../../__tests__/fixture/loggedUser';
import { AuthContextProvider } from '../../contexts/AuthContext';
import { useFeeds } from './useFeeds';
import type { Feed } from '../../graphql/feed';
import {
CREATE_FEED_MUTATION,
DELETE_FEED_MUTATION,
Expand All @@ -18,7 +19,7 @@ const client = new QueryClient();
const noop = jest.fn();
let queryCalled = false;

const Wrapper = ({ children }) => {
const Wrapper = ({ children }: React.PropsWithChildren) => {
return (
<QueryClientProvider client={client}>
<AuthContextProvider
Expand Down Expand Up @@ -183,7 +184,7 @@ describe('useFeeds hook', () => {
await waitFor(() => expect(queryCalled).toBe(true));

expect(result.current.feeds).toBeTruthy();
expect(result.current.feeds.edges).toMatchObject(feeds);
expect(result.current.feeds?.edges).toMatchObject(feeds);
});

it('should create a feed', async () => {
Expand All @@ -193,17 +194,27 @@ describe('useFeeds hook', () => {

await waitFor(() => expect(queryCalled).toBe(true));

let feed;
let feed: Feed | undefined;

await act(async () => {
feed = await result.current.createFeed({ name: 'New feed' });
});
rerender();

expect(feed).toBeTruthy();
expect(feed.flags.name).toBe('New feed');
if (!feed) {
throw new Error('Created feed is required');
}

if (!feed.flags) {
throw new Error('Created feed flags are required');
}

const createdFeed = feed;
const createdFeedFlags = feed.flags;
expect(createdFeedFlags.name).toBe('New feed');
expect(
result.current.feeds.edges.find((f) => f.node.id === feed.id),
result.current.feeds?.edges.find((f) => f.node.id === createdFeed.id),
).toBeTruthy();
});

Expand All @@ -214,7 +225,7 @@ describe('useFeeds hook', () => {

await waitFor(() => expect(queryCalled).toBe(true));

let feed;
let feed: Feed | undefined;
await act(async () => {
feed = await result.current.updateFeed({
feedId: 'cf1',
Expand All @@ -224,9 +235,19 @@ describe('useFeeds hook', () => {
rerender();

expect(feed).toBeTruthy();
expect(feed.flags.name).toBe('Updated feed');
if (!feed) {
throw new Error('Updated feed is required');
}

if (!feed.flags) {
throw new Error('Updated feed flags are required');
}

const updatedFeed = feed;
const updatedFeedFlags = feed.flags;
expect(updatedFeedFlags.name).toBe('Updated feed');
expect(
result.current.feeds.edges.find((f) => f.node.id === feed.id),
result.current.feeds?.edges.find((f) => f.node.id === updatedFeed.id),
).toBeTruthy();
});

Expand All @@ -244,7 +265,7 @@ describe('useFeeds hook', () => {
rerender();

expect(
result.current.feeds.edges.find((f) => f.node.id === 'cf1'),
result.current.feeds?.edges.find((f) => f.node.id === 'cf1'),
).toBeFalsy();
});
});
14 changes: 13 additions & 1 deletion packages/shared/src/hooks/feed/useFeeds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export type UpdateFeedProps = { feedId: string } & CreateFeedProps;
export type DeleteFeedProps = Pick<UpdateFeedProps, 'feedId'>;

export type UseFeeds = {
feeds: FeedList['feedList'];
feeds: FeedList['feedList'] | undefined;
createFeed: (props: CreateFeedProps) => Promise<Feed>;
updateFeed: (props: UpdateFeedProps) => Promise<Feed>;
deleteFeed: (props: DeleteFeedProps) => Promise<Pick<Feed, 'id'>>;
Expand Down Expand Up @@ -58,6 +58,10 @@ export const useFeeds = (): UseFeeds => {

onSuccess: (data) => {
queryClient.setQueryData<FeedList['feedList']>(queryKey, (current) => {
if (!current) {
return current;
}

return {
...current,
edges: [
Expand Down Expand Up @@ -87,6 +91,10 @@ export const useFeeds = (): UseFeeds => {

onSuccess: (data) => {
queryClient.setQueryData<FeedList['feedList']>(queryKey, (current) => {
if (!current) {
return current;
}

return {
...current,
edges: (current?.edges || []).map((edge) => {
Expand Down Expand Up @@ -118,6 +126,10 @@ export const useFeeds = (): UseFeeds => {

onSuccess: (data) => {
queryClient.setQueryData<FeedList['feedList']>(queryKey, (current) => {
if (!current) {
return current;
}

return {
...current,
edges: (current?.edges || []).filter(
Expand Down
9 changes: 5 additions & 4 deletions packages/shared/src/hooks/feed/useFollowPostTags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@ export const useFollowPostTags = ({
const isModerationItem = !post?.permalink;

const tags = useMemo(() => {
const all = post?.tags ?? [];

if (!isLoggedIn || isModerationItem) {
return {
all: post?.tags,
all,
followed: [],
notFollowed: post?.tags,
notFollowed: all,
};
}

const all = post?.tags ?? [];
const followedTags = new Set(feedSettings?.includeTags || []);
return all.reduce(
return all.reduce<Record<'all' | 'followed' | 'notFollowed', string[]>>(
(acc, tag) => {
const isFollowing = followedTags.has(tag);
const group = isFollowing ? 'followed' : 'notFollowed';
Expand Down
2 changes: 1 addition & 1 deletion packages/shared/src/hooks/log/useDeviceId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const getOrGenerateDeviceId = async (): Promise<string> => {
return newDeviceId;
};

export default function useDeviceId(): string {
export default function useDeviceId(): string | undefined {
const [deviceId, setDeviceId] = useState<string>();

useEffect(() => {
Expand Down
6 changes: 4 additions & 2 deletions packages/shared/src/hooks/log/useLogContextData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,10 @@ export default function useLogContextData(
const event = durationEventsQueue.current.get(id);
if (event) {
durationEventsQueue.current.delete(id);
event.event_duration =
now.getTime() - event.event_timestamp.getTime();
const eventTimestamp = event.event_timestamp;
if (eventTimestamp) {
event.event_duration = now.getTime() - eventTimestamp.getTime();
}
if (window.scrollY > 0 && event.event_name !== 'page inactive') {
event.page_state = 'active';
}
Expand Down
5 changes: 3 additions & 2 deletions packages/shared/src/hooks/log/useLogLifecycleEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ export default function useLogLifecycleEvents(

useEffect(() => {
listenToLifecycleEvents();
const callback = (event: CustomEvent) =>
lifecycleCallbackRef.current(event);
const callback = (event: Event) => {
lifecycleCallbackRef.current?.(event as CustomEvent);
};
window.addEventListener('statechange', callback);
return () => window.removeEventListener('statechange', callback);
}, []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const useLogOpportunityNudgeImpression = (
return;
}

logRef.current({
logRef.current?.({
event_name: LogEvent.ImpressionOpportunityNudge,
target_id: targetId,
extra: logExtraPayload,
Expand Down
11 changes: 7 additions & 4 deletions packages/shared/src/hooks/log/useLogPageView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { useEffect, useRef } from 'react';
import { useRouter } from 'next/router';
import { useLogContext } from '../../contexts/LogContext';

export default function useLogPageView(): MutableRefObject<() => void> {
export default function useLogPageView(): MutableRefObject<
(() => void) | undefined
> {
const router = useRouter();
const { logEventStart, logEventEnd } = useLogContext();
const routeChangedCallbackRef = useRef<() => void>();
Expand All @@ -23,11 +25,12 @@ export default function useLogPageView(): MutableRefObject<() => void> {
}, [logEventStart, logEventEnd]);

useEffect(() => {
const handleRouteChange = () => routeChangedCallbackRef.current();
const handleRouteChange = () => routeChangedCallbackRef.current?.();
router.events.on('routeChangeComplete', handleRouteChange);

const handleLifecycle = (event: CustomEvent) =>
lifecycleCallbackRef.current(event);
const handleLifecycle = (event: Event) => {
lifecycleCallbackRef.current?.(event as CustomEvent);
};
window.addEventListener('statechange', handleLifecycle);

return () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/shared/src/hooks/log/useLogSharedProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function useLogSharedProps(
deviceId: string,
): [MutableRefObject<Partial<LogEvent>>, boolean] {
// Use ref instead of state to reduce renders
const sharedPropsRef = useRef<Partial<LogEvent>>();
const sharedPropsRef = useRef<Partial<LogEvent>>({});
const { query } = useRouter();
const { themeMode, spaciness, insaneMode } = useContext(SettingsContext);
const { visit, anonymous, tokenRefreshed, user } = useContext(AuthContext);
Expand Down