Browse Source

FeaturedPosts: fix bugs with updating the store, make a local storage hook

pull/2/head
eiknat 1 year ago
parent
commit
70d8d69c60
  1. 89
      src/components/FeaturedPosts.tsx
  2. 18
      src/hooks/useLocalStorage.tsx

89
src/components/FeaturedPosts.tsx

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React from 'react';
import {
Disclosure,
DisclosureButton,
@ -13,6 +13,7 @@ import { GetPostsResponse, SortType } from '../interfaces';
import { UserService } from '../services';
import { toQueryString, fetcher } from '../utils';
import { PostListings } from './post-listings';
import useLocalStorage from '../hooks/useLocalStorage';
interface FeaturedPostStore {
open: boolean;
@ -27,7 +28,7 @@ interface DisclosureProps {
}
const FeaturedDisclosure = (props: DisclosureProps) => {
const displayUpdate = props.updated ? ' - (Click to view new posts!)' : '';
const displayUpdate = props.updated ? '!' : '';
return (
<Button
variant="borderless"
@ -42,64 +43,35 @@ const FeaturedDisclosure = (props: DisclosureProps) => {
>
<Block>
<Icon color="#F8786F" name="broadcast" style={{ marginRight: '5px' }} />
Featured Posts <small>{displayUpdate}</small>
Featured Posts
</Block>
<Block color="red">
{displayUpdate}
<Icon
color="#C4C4C4"
name={props.open ? 'minus' : 'plus'}
style={{ marginLeft: '15px', marginRight: '15px' }}
/>
</Block>
<Icon
name={props.open ? 'minus' : 'plus'}
style={{ marginRight: '15px' }}
/>
</Button>
);
};
const getFeaturedPostStore = (): FeaturedPostStore => {
const store = localStorage.getItem('fp_store');
if (!store) {
return {
open: true,
changed: false,
postIds: [],
} as FeaturedPostStore;
}
return JSON.parse(store) as FeaturedPostStore;
};
const updateFeaturedStore = (newStore: FeaturedPostStore) => {
localStorage.setItem('fp_store', JSON.stringify(newStore));
};
const updateFeaturedPosts = (store: FeaturedPostStore, ids: number[]): void => {
const { postIds } = store;
let update = false;
ids.forEach(id => {
if (!postIds.includes(id)) {
update = true;
}
});
if (update) {
const updated: FeaturedPostStore = {
...store,
changed: true,
postIds: ids,
};
updateFeaturedStore(updated);
}
};
const FeaturedPosts = (): JSX.Element => {
const store = getFeaturedPostStore();
const [store, setStore] = useLocalStorage('fp_store', {
open: true,
changed: false,
postIds: [],
} as FeaturedPostStore);
const [open, setOpen] = useState(store.open || true);
const handleOpenChange = (): void => {
setOpen(prev => {
const updated: FeaturedPostStore = {
...store,
changed: false,
open: !prev,
};
updateFeaturedStore(updated);
return !prev;
});
setStore({ ...store, changed: false, open: !store.open });
};
const handlePostsChange = (postIds: number[]): void => {
if (postIds.some(id => !store.postIds.includes(id))) {
setStore({ ...store, changed: true, postIds });
}
};
let featuredParams = '';
@ -114,12 +86,11 @@ const FeaturedPosts = (): JSX.Element => {
fetcher,
{
revalidateOnFocus: false,
onSuccess: data => {
handlePostsChange(data.posts.flatMap(p => p.id));
},
}
);
if (data) {
const postIds = data.posts.flatMap(p => p.id);
updateFeaturedPosts(store, postIds);
}
return (
<>
@ -135,7 +106,11 @@ const FeaturedPosts = (): JSX.Element => {
>
<Disclosure defaultOpen={store.open}>
<FeaturedDisclosure
{...{ open, updated: store.changed, handleOpenChange }}
{...{
open: store.open,
updated: store.changed,
handleOpenChange,
}}
/>
<DisclosurePanel>
<PostListings

18
src/hooks/useLocalStorage.tsx

@ -0,0 +1,18 @@
import { useState, useEffect, Dispatch } from 'react';
const useLocalStorage = <T extends unknown>(
key: string,
defaultValue: T
): [T, Dispatch<T>] => {
const store = localStorage.getItem(key);
const initial = store ? JSON.parse(store) : defaultValue;
const [value, setValue] = useState(initial);
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
};
export default useLocalStorage;
Loading…
Cancel
Save