mirror of
https://github.com/colanode/colanode.git
synced 2025-12-29 00:25:03 +01:00
Reuse read state indicator component
This commit is contained in:
@@ -3,6 +3,7 @@ import { ChannelNode } from '@colanode/core';
|
||||
import { Avatar } from '@/renderer/components/avatars/avatar';
|
||||
import { useWorkspace } from '@/renderer/contexts/workspace';
|
||||
import { useRadar } from '@/renderer/contexts/radar';
|
||||
import { ReadStateIndicator } from '@/renderer/components/layouts/read-state-indicator';
|
||||
|
||||
interface ChannelSidebarItemProps {
|
||||
node: ChannelNode;
|
||||
@@ -39,13 +40,11 @@ export const ChannelSidebarItem = ({ node }: ChannelSidebarItemProps) => {
|
||||
>
|
||||
{node.attributes.name ?? 'Unnamed'}
|
||||
</span>
|
||||
{!isActive && mentionsCount > 0 && (
|
||||
<span className="mr-1 rounded-md bg-sidebar-accent px-1 py-0.5 text-xs bg-red-400 text-white">
|
||||
{mentionsCount}
|
||||
</span>
|
||||
)}
|
||||
{!isActive && mentionsCount === 0 && unreadCount > 0 && (
|
||||
<span className="size-2 rounded-full bg-red-500" />
|
||||
{!isActive && (
|
||||
<ReadStateIndicator
|
||||
count={mentionsCount}
|
||||
hasChanges={unreadCount > 0}
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Avatar } from '@/renderer/components/avatars/avatar';
|
||||
import { useWorkspace } from '@/renderer/contexts/workspace';
|
||||
import { useQuery } from '@/renderer/hooks/use-query';
|
||||
import { useRadar } from '@/renderer/contexts/radar';
|
||||
import { ReadStateIndicator } from '@/renderer/components/layouts/read-state-indicator';
|
||||
|
||||
interface ChatSidebarItemProps {
|
||||
node: ChatNode;
|
||||
@@ -55,11 +56,7 @@ export const ChatSidebarItem = ({ node }: ChatSidebarItemProps) => {
|
||||
>
|
||||
{data.attributes.name ?? 'Unnamed'}
|
||||
</span>
|
||||
{!isActive && unreadCount > 0 && (
|
||||
<span className="mr-1 rounded-md px-1 py-0.5 text-xs bg-red-400 text-white">
|
||||
{unreadCount}
|
||||
</span>
|
||||
)}
|
||||
<ReadStateIndicator count={unreadCount} hasChanges={unreadCount > 0} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -19,30 +19,13 @@ import { ChevronsUpDown, LogOut, Plus, Settings } from 'lucide-react';
|
||||
import { useApp } from '@/renderer/contexts/app';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useRadar } from '@/renderer/contexts/radar';
|
||||
import { ReadStateIndicator } from '@/renderer/components/layouts/read-state-indicator';
|
||||
|
||||
interface ReadStateIndicatorProps {
|
||||
interface AccountReadState {
|
||||
importantCount: number;
|
||||
hasUnseenChanges: boolean;
|
||||
}
|
||||
|
||||
const ReadStateIndicator = ({
|
||||
importantCount,
|
||||
hasUnseenChanges,
|
||||
}: ReadStateIndicatorProps) => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{importantCount > 0 && (
|
||||
<span className="mr-1 rounded-md px-1 py-0.5 text-xs bg-red-400 text-white">
|
||||
{importantCount}
|
||||
</span>
|
||||
)}
|
||||
{importantCount === 0 && hasUnseenChanges && (
|
||||
<span className="size-2 rounded-full bg-red-500" />
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export function LayoutSidebarFooter() {
|
||||
const app = useApp();
|
||||
const account = useAccount();
|
||||
@@ -53,13 +36,13 @@ export function LayoutSidebarFooter() {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const otherAccounts = app.accounts.filter((a) => a.id !== account.id);
|
||||
|
||||
const accountStates: Record<string, ReadStateIndicatorProps> = {};
|
||||
const accountStates: Record<string, AccountReadState> = {};
|
||||
for (const otherAccount of otherAccounts) {
|
||||
const accountWorkspaces = app.workspaces.filter(
|
||||
(w) => w.accountId === otherAccount.id
|
||||
);
|
||||
|
||||
const state: ReadStateIndicatorProps = {
|
||||
const state: AccountReadState = {
|
||||
importantCount: 0,
|
||||
hasUnseenChanges: false,
|
||||
};
|
||||
@@ -103,8 +86,8 @@ export function LayoutSidebarFooter() {
|
||||
</div>
|
||||
<ChevronsUpDown className="ml-auto size-4" />
|
||||
<ReadStateIndicator
|
||||
importantCount={importantCount}
|
||||
hasUnseenChanges={hasUnseenChanges}
|
||||
count={importantCount}
|
||||
hasChanges={hasUnseenChanges}
|
||||
/>
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
@@ -179,8 +162,8 @@ export function LayoutSidebarFooter() {
|
||||
</span>
|
||||
</div>
|
||||
<ReadStateIndicator
|
||||
importantCount={state.importantCount}
|
||||
hasUnseenChanges={state.hasUnseenChanges}
|
||||
count={state.importantCount}
|
||||
hasChanges={state.hasUnseenChanges}
|
||||
/>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
|
||||
@@ -19,29 +19,7 @@ import {
|
||||
} from '@/renderer/components/ui/sidebar';
|
||||
import { ChevronsUpDown, Settings, Plus, Bell } from 'lucide-react';
|
||||
import { useRadar } from '@/renderer/contexts/radar';
|
||||
|
||||
interface ReadStateIndicatorProps {
|
||||
importantCount: number;
|
||||
hasUnseenChanges: boolean;
|
||||
}
|
||||
|
||||
const ReadStateIndicator = ({
|
||||
importantCount,
|
||||
hasUnseenChanges,
|
||||
}: ReadStateIndicatorProps) => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{importantCount > 0 && (
|
||||
<span className="mr-1 rounded-md px-1 py-0.5 text-xs bg-red-400 text-white">
|
||||
{importantCount}
|
||||
</span>
|
||||
)}
|
||||
{importantCount === 0 && hasUnseenChanges && (
|
||||
<span className="size-2 rounded-full bg-red-500" />
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
import { ReadStateIndicator } from '@/renderer/components/layouts/read-state-indicator';
|
||||
|
||||
export const LayoutSidebarHeader = () => {
|
||||
const workspace = useWorkspace();
|
||||
@@ -86,8 +64,8 @@ export const LayoutSidebarHeader = () => {
|
||||
</div>
|
||||
<ChevronsUpDown className="ml-auto size-4" />
|
||||
<ReadStateIndicator
|
||||
importantCount={importantCount}
|
||||
hasUnseenChanges={hasUnseenChanges}
|
||||
count={importantCount}
|
||||
hasChanges={hasUnseenChanges}
|
||||
/>
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
@@ -153,8 +131,8 @@ export const LayoutSidebarHeader = () => {
|
||||
{otherWorkspace.name}
|
||||
</p>
|
||||
<ReadStateIndicator
|
||||
importantCount={workspaceState.importantCount}
|
||||
hasUnseenChanges={workspaceState.hasUnseenChanges}
|
||||
count={workspaceState.importantCount}
|
||||
hasChanges={workspaceState.hasUnseenChanges}
|
||||
/>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
interface ReadStateIndicatorProps {
|
||||
count: number;
|
||||
hasChanges: boolean;
|
||||
}
|
||||
|
||||
export const ReadStateIndicator = ({
|
||||
count,
|
||||
hasChanges,
|
||||
}: ReadStateIndicatorProps) => {
|
||||
if (count === 0 && !hasChanges) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
return (
|
||||
<span className="mr-1 rounded-md px-1 py-0.5 text-xs bg-red-400 text-white">
|
||||
{count}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return <span className="size-2 rounded-full bg-red-500" />;
|
||||
};
|
||||
Reference in New Issue
Block a user