diff --git a/CHANGELOG.md b/CHANGELOG.md index 53a7107..d7e0b27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ Generated by the awesome [`auto-changelog`](https://github.com/CookPete/auto-changelog) package 👏🏽. -## [v16](https://github.com/digitalmaster/roam-memo/compare/v15...v16) - 29 March 2024 +## [v16](https://github.com/digitalmaster/roam-memo/compare/v15...v16) - 7 April 2024 ### New Features @@ -20,6 +20,7 @@ Generated by the awesome [`auto-changelog`](https://github.com/CookPete/auto-cha ### Other Changes - Improve changelog rendering template [`713947d`](https://github.com/digitalmaster/roam-memo/commit/713947d804db455baa4c5d4c5e934cce10ba27d4) +- Refactor review reminder counts to include all tags [`02fdfdc`](https://github.com/digitalmaster/roam-memo/commit/02fdfdc34dc0bf6930339efa555dddbec8057b73) diff --git a/src/app.tsx b/src/app.tsx index af3748c..fb70d9b 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -43,6 +43,7 @@ const App = () => { completedTodayCount, remainingDueCardsCount, } = usePracticeData({ + tagsList, selectedTag, dataPageTitle, isCramming, @@ -161,6 +162,7 @@ const App = () => { dailyLimit={dailyLimit} remainingDueCardsCount={remainingDueCardsCount} rtlEnabled={rtlEnabled} + displayCardCounts={displayCardCounts} /> )} diff --git a/src/components/SidePandelWidget.tsx b/src/components/SidePandelWidget.tsx index 83f3178..11006bc 100644 --- a/src/components/SidePandelWidget.tsx +++ b/src/components/SidePandelWidget.tsx @@ -15,7 +15,8 @@ const Tag = styled(Blueprint.Tag)` `; const SidePandelWidget = ({ onClickCallback, displayCardCounts }) => { - const totalCardsCount = displayCardCounts.new + displayCardCounts.due; + const combinedCounts = displayCardCounts.combined; + const totalCardsCount = combinedCounts.new + combinedCounts.due; const isDone = totalCardsCount === 0; const iconClass = isDone ? 'bp3-icon-confirm' : 'bp3-icon-box'; @@ -29,19 +30,19 @@ const SidePandelWidget = ({ onClickCallback, displayCardCounts }) => {
- {displayCardCounts.due > 0 && ( + {combinedCounts.due > 0 && ( // @ts-ignore - {displayCardCounts.due} + {combinedCounts.due} )} - {displayCardCounts.new > 0 && ( + {combinedCounts.new > 0 && ( // @ts-ignore - {displayCardCounts.new} + {combinedCounts.new} )} diff --git a/src/components/overlay/PracticeOverlay.tsx b/src/components/overlay/PracticeOverlay.tsx index 0e7cbcd..0a13460 100644 --- a/src/components/overlay/PracticeOverlay.tsx +++ b/src/components/overlay/PracticeOverlay.tsx @@ -35,6 +35,7 @@ const PracticeOverlay = ({ onCloseCallback, practiceCardUids, practiceData, + displayCardCounts, handlePracticeClick, handleMemoTagChange, handleReviewMoreClick, @@ -230,6 +231,7 @@ const PracticeOverlay = ({ setShowBreadcrumbs={setShowBreadcrumbs} isCramming={isCramming} dailyLimitDelta={dailyLimitDelta} + displayCardCounts={displayCardCounts} /> { +const TagSelector = ({ tagsList, selectedTag, onTagChange, displayCardCounts }) => { return ( // @ts-ignore { filterable={false} itemRenderer={(tag, { handleClick, modifiers }) => { return ( - + ); }} onItemSelect={(tag) => { @@ -339,6 +348,8 @@ const TagSelector = ({ tagsList, selectedTag, onTagChange }) => { }; const TagSelectorItemWrapper = styled.div<{ active: boolean }>` + display: flex; + justify-content: space-between; padding: 4px 6px; background-color: ${({ active }) => (active ? '#e8edf4' : 'white')}; user-select: none; @@ -349,10 +360,42 @@ const TagSelectorItemWrapper = styled.div<{ active: boolean }>` } `; -const TagSelectorItem = ({ text, onClick, active, key }) => { +const Tag = styled(Blueprint.Tag)` + &.bp3-tag { + font-size: 11px; + padding: 1px 3px; + min-height: auto; + min-width: auto; + } +`; + +const TagSelectorItem = ({ text, onClick, active, tagsList, displayCardCounts }) => { + const dueCount = displayCardCounts[text].due; + const newCount = displayCardCounts[text].new; + const index = tagsList.indexOf(text); + const placement = index === tagsList.length - 1 ? 'bottom' : 'top'; + return ( - + {text} +
+ {dueCount > 0 && ( + // @ts-ignore + + + {dueCount} + + + )} + {newCount > 0 && ( + // @ts-ignore + + + {newCount} + + + )} +
); }; @@ -425,13 +468,19 @@ const Header = ({ setShowBreadcrumbs, isCramming, dailyLimitDelta, + displayCardCounts, }) => { return (
- +
diff --git a/src/hooks/usePracticeData.tsx b/src/hooks/usePracticeData.tsx index b962903..8d890a2 100644 --- a/src/hooks/usePracticeData.tsx +++ b/src/hooks/usePracticeData.tsx @@ -2,7 +2,21 @@ import * as React from 'react'; import { NewRecords, Records, RecordUid } from '~/models/session'; import * as queries from '~/queries'; +const calculateCombinedCardCounts = (displayCardCounts) => { + const combinedCounts = { combined: { new: 0, due: 0 } }; + for (const key of Object.keys(displayCardCounts)) { + combinedCounts.combined.new += displayCardCounts[key].new; + combinedCounts.combined.due += displayCardCounts[key].due; + } + + return { + ...displayCardCounts, + ...combinedCounts, + }; +}; + const usePracticeCardsData = ({ + tagsList, selectedTag, dataPageTitle, isCramming, @@ -11,14 +25,18 @@ const usePracticeCardsData = ({ }) => { const [practiceCardsUids, setPracticeCardsUids] = React.useState([]); const [practiceData, setPracticeData] = React.useState({}); - const [refetchTrigger, setRefetchTrigger] = React.useState(false); - const [displayCardCounts, setDisplayCardCounts] = React.useState({ new: 0, due: 0 }); + + const [displayCardCounts, setDisplayCardCounts] = React.useState({}); + const [completedTodayCount, setCompletedTodayCount] = React.useState(0); const [remainingDueCardsCount, setRemainingDueCardsCount] = React.useState(0); + const refetchTriggerFn = () => setRefetchTrigger((trigger) => !trigger); React.useEffect(() => { (async () => { + if (!selectedTag) return; + const { pluginPageData, newCardsUids, @@ -47,15 +65,41 @@ const usePracticeCardsData = ({ // @TODO: Perhaps make this order configurable? setPracticeCardsUids([...dueCardsUids, ...newCardsUids]); } - setDisplayCardCounts({ new: newCardsUids.length, due: dueCardsUids.length }); + + const displayCountsData = { + [selectedTag]: { new: newCardsUids.length, due: dueCardsUids.length }, + }; + for (const tag of tagsList) { + if (tag === selectedTag) continue; + + const { newCardsUids, dueCardsUids } = await queries.getPracticeData({ + selectedTag: tag, + dataPageTitle, + dailyLimit, + isCramming, + lastCompletedDate, + }); + + displayCountsData[tag] = { new: newCardsUids.length, due: dueCardsUids.length }; + } + + setDisplayCardCounts(displayCountsData); })(); - }, [selectedTag, dataPageTitle, refetchTrigger, isCramming, dailyLimit, lastCompletedDate]); + }, [ + selectedTag, + dataPageTitle, + refetchTrigger, + isCramming, + dailyLimit, + lastCompletedDate, + tagsList, + ]); return { practiceCardsUids, practiceData, - displayCardCounts, - fetchPracticeData: () => setRefetchTrigger((trigger) => !trigger), + displayCardCounts: calculateCombinedCardCounts(displayCardCounts), + fetchPracticeData: refetchTriggerFn, completedTodayCount, remainingDueCardsCount, }; diff --git a/src/hooks/useTags.tsx b/src/hooks/useTags.tsx index 148be88..99ca65b 100644 --- a/src/hooks/useTags.tsx +++ b/src/hooks/useTags.tsx @@ -28,11 +28,8 @@ const useTags = ({ tagsListString }: { tagsListString: string }) => { React.useEffect(() => { const tagsList = splitStringByCommas(tagsListString); setTagsList(tagsList); - }, [tagsListString, setTagsList]); - - React.useEffect(() => { setSelectedTag(tagsList[0]); - }, [tagsList]); + }, [tagsListString, setTagsList]); return { selectedTag,