forked from Archives/Athou_commafeed
Adding red dot indicator feature, got main components done
This commit is contained in:
@@ -43,6 +43,20 @@ export const treeSlice = createSlice({
|
|||||||
},
|
},
|
||||||
extraReducers: builder => {
|
extraReducers: builder => {
|
||||||
builder.addCase(reloadTree.fulfilled, (state, action) => {
|
builder.addCase(reloadTree.fulfilled, (state, action) => {
|
||||||
|
visitCategoryTree(action.payload, category => {
|
||||||
|
category.feeds = category.feeds.map(feed => {
|
||||||
|
const storageKey = `feed-${feed.id}-unread`
|
||||||
|
const prevUnread = parseInt(localStorage.getItem(storageKey) || "0", 10)
|
||||||
|
const hasNewEntries = feed.unread > prevUnread
|
||||||
|
|
||||||
|
localStorage.setItem(storageKey, feed.unread.toString())
|
||||||
|
|
||||||
|
return {
|
||||||
|
...feed,
|
||||||
|
hasNewEntries
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
state.rootCategory = action.payload
|
state.rootCategory = action.payload
|
||||||
})
|
})
|
||||||
builder.addCase(collapseTreeCategory.pending, (state, action) => {
|
builder.addCase(collapseTreeCategory.pending, (state, action) => {
|
||||||
|
|||||||
@@ -30,13 +30,17 @@ export interface Subscription {
|
|||||||
filter?: string
|
filter?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TreeSubscription extends Subscription {
|
||||||
|
hasNewEntries?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export interface Category {
|
export interface Category {
|
||||||
id: string
|
id: string
|
||||||
parentId?: string
|
parentId?: string
|
||||||
parentName?: string
|
parentName?: string
|
||||||
name: string
|
name: string
|
||||||
children: Category[]
|
children: Category[]
|
||||||
feeds: Subscription[]
|
feeds: TreeSubscription[]
|
||||||
expanded: boolean
|
expanded: boolean
|
||||||
position: number
|
position: number
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
} from "app/redirect/thunks";
|
} from "app/redirect/thunks";
|
||||||
import { useAppDispatch, useAppSelector } from "app/store";
|
import { useAppDispatch, useAppSelector } from "app/store";
|
||||||
import { collapseTreeCategory } from "app/tree/thunks";
|
import { collapseTreeCategory } from "app/tree/thunks";
|
||||||
import type { Category, Subscription } from "app/types";
|
import type { Category, Subscription, TreeSubscription } from "app/types";
|
||||||
import { categoryUnreadCount, flattenCategoryTree } from "app/utils";
|
import { categoryUnreadCount, flattenCategoryTree } from "app/utils";
|
||||||
import { Loader } from "components/Loader";
|
import { Loader } from "components/Loader";
|
||||||
import { OnDesktop } from "components/responsive/OnDesktop";
|
import { OnDesktop } from "components/responsive/OnDesktop";
|
||||||
@@ -35,7 +35,6 @@ const collapsedIcon = <TbChevronRight size={16} />;
|
|||||||
const errorThreshold = 9;
|
const errorThreshold = 9;
|
||||||
|
|
||||||
export function Tree() {
|
export function Tree() {
|
||||||
const [hasNewMessages, setHasNewMessages] = useState(false);
|
|
||||||
const root = useAppSelector((state) => state.tree.rootCategory);
|
const root = useAppSelector((state) => state.tree.rootCategory);
|
||||||
const source = useAppSelector((state) => state.entries.source);
|
const source = useAppSelector((state) => state.entries.source);
|
||||||
const tags = useAppSelector((state) => state.user.tags);
|
const tags = useAppSelector((state) => state.user.tags);
|
||||||
@@ -91,15 +90,7 @@ export function Tree() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
console.log(root?.feeds.map(f => f.hasNewEntries));
|
||||||
const prevCount = JSON.parse(localStorage.getItem("FeedCount") || "0");
|
|
||||||
const currentCount = categoryUnreadCount(root);
|
|
||||||
|
|
||||||
if (currentCount > prevCount) {
|
|
||||||
setHasNewMessages(true);
|
|
||||||
}
|
|
||||||
localStorage.setItem("FeedCount", JSON.stringify(currentCount));
|
|
||||||
}, [root?.feeds.length]);
|
|
||||||
|
|
||||||
const allCategoryNode = () => (
|
const allCategoryNode = () => (
|
||||||
|
|
||||||
@@ -116,7 +107,6 @@ export function Tree() {
|
|||||||
level={0}
|
level={0}
|
||||||
hasError={false}
|
hasError={false}
|
||||||
onClick={categoryClicked}
|
onClick={categoryClicked}
|
||||||
newMessages={hasNewMessages}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
const starredCategoryNode = () => (
|
const starredCategoryNode = () => (
|
||||||
@@ -163,7 +153,7 @@ export function Tree() {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const feedNode = (feed: Subscription, level = 0) => {
|
const feedNode = (feed: TreeSubscription, level = 0) => {
|
||||||
if (!isFeedDisplayed(feed)) return null;
|
if (!isFeedDisplayed(feed)) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -178,6 +168,7 @@ export function Tree() {
|
|||||||
hasError={feed.errorCount > errorThreshold}
|
hasError={feed.errorCount > errorThreshold}
|
||||||
onClick={feedClicked}
|
onClick={feedClicked}
|
||||||
key={feed.id}
|
key={feed.id}
|
||||||
|
newMessages={feed.hasNewEntries}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ export function UnreadCount(props: { unreadCount: number, newMessages: boolean |
|
|||||||
|
|
||||||
const count = props.unreadCount >= 10000 ? "10k+" : props.unreadCount
|
const count = props.unreadCount >= 10000 ? "10k+" : props.unreadCount
|
||||||
|
|
||||||
|
console.log(props.newMessages);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip label={props.unreadCount} disabled={props.unreadCount === count} openDelay={Constants.tooltip.delay}>
|
<Tooltip label={props.unreadCount} disabled={props.unreadCount === count} openDelay={Constants.tooltip.delay}>
|
||||||
<Indicator disabled={!props.newMessages} size={4} offset={10} position="top-start" color="orange" withBorder={false} zIndex={5}>
|
<Indicator disabled={!props.newMessages} size={4} offset={10} position="top-start" color="orange" withBorder={false} zIndex={5}>
|
||||||
|
|||||||
Reference in New Issue
Block a user