mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
feat(reconnect): replace top banner with animated sidebar overlay (#1510)
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
// biome-ignore format: keep compact to stay within file size limit
|
||||
import { MessageCirclePlus } from "lucide-react";
|
||||
|
||||
import * as React from "react";
|
||||
import { AnimatePresence } from "motion/react";
|
||||
import { FeatureGate } from "@/shared/features";
|
||||
import { SidebarDndContext } from "@/features/sidebar/ui/SidebarDnd";
|
||||
|
||||
import type { Workspace } from "@/features/workspaces/types";
|
||||
import { AddWorkspaceDialog } from "@/features/workspaces/ui/AddWorkspaceDialog";
|
||||
import { useIsMobile } from "@/shared/hooks/use-mobile";
|
||||
import { useDeferredLoad } from "@/shared/hooks/useDeferredStartup";
|
||||
import {
|
||||
useChannelSections,
|
||||
@@ -34,7 +35,7 @@ import { CreateChannelDialog } from "@/features/sidebar/ui/CreateChannelDialog";
|
||||
import { NewDirectMessageDialog } from "@/features/sidebar/ui/NewDirectMessageDialog";
|
||||
import { SidebarProfileCard } from "@/features/sidebar/ui/SidebarProfileCard";
|
||||
import { SidebarRelayConnectionCard } from "@/features/sidebar/ui/SidebarRelayConnectionCard";
|
||||
import { useSidebarRelayConnectionCard } from "@/features/sidebar/ui/useSidebarRelayConnectionCard";
|
||||
import type { useSidebarRelayConnectionCard } from "@/features/sidebar/ui/useSidebarRelayConnectionCard";
|
||||
import {
|
||||
SidebarLoadingContent,
|
||||
useSidebarLoadingShape,
|
||||
@@ -62,6 +63,7 @@ import {
|
||||
SidebarMenu,
|
||||
SidebarMenuItem,
|
||||
SidebarRail,
|
||||
useSidebar,
|
||||
} from "@/shared/ui/sidebar";
|
||||
|
||||
type CollapsibleSidebarGroup =
|
||||
@@ -84,6 +86,7 @@ type AppSidebarProps = {
|
||||
isCreatingForum: boolean;
|
||||
isOpeningDm: boolean;
|
||||
profile?: Profile;
|
||||
relayConnectionCard: ReturnType<typeof useSidebarRelayConnectionCard>;
|
||||
selfPresenceStatus: PresenceStatus;
|
||||
errorMessage?: string;
|
||||
selectedChannelId: string | null;
|
||||
@@ -174,6 +177,7 @@ export function AppSidebar({
|
||||
isCreatingForum,
|
||||
isOpeningDm,
|
||||
profile,
|
||||
relayConnectionCard,
|
||||
selfPresenceStatus,
|
||||
errorMessage,
|
||||
selectedChannelId,
|
||||
@@ -225,10 +229,8 @@ export function AppSidebar({
|
||||
const activeWorkingByChannelId = useActiveWorkingChannelsById();
|
||||
const { status: updateStatus } = useUpdaterContext();
|
||||
const canShowSidebarUpdateCard = shouldShowSidebarUpdateCard(updateStatus);
|
||||
const sidebarRelayConnectionCard = useSidebarRelayConnectionCard(
|
||||
errorMessage,
|
||||
activeWorkspace?.relayUrl,
|
||||
);
|
||||
const { open: sidebarOpen, openMobile } = useSidebar();
|
||||
const isMobile = useIsMobile();
|
||||
const [isSidebarUpdateCardDismissed, setIsSidebarUpdateCardDismissed] =
|
||||
React.useState(false);
|
||||
const showSidebarUpdateCard =
|
||||
@@ -741,8 +743,7 @@ export function AppSidebar({
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{errorMessage &&
|
||||
!sidebarRelayConnectionCard.hasRelayUnreachableError ? (
|
||||
{errorMessage && !relayConnectionCard.hasRelayUnreachableError ? (
|
||||
<div className="px-3 py-2 text-sm text-destructive">
|
||||
{errorMessage}
|
||||
</div>
|
||||
@@ -762,27 +763,19 @@ export function AppSidebar({
|
||||
) : null}
|
||||
|
||||
<SidebarFooter>
|
||||
<AnimatePresence>
|
||||
{sidebarRelayConnectionCard.showSidebarRelayConnectionCard ? (
|
||||
<SidebarRelayConnectionCard
|
||||
className="mb-2 group-data-[collapsible=icon]:hidden"
|
||||
isConnected={
|
||||
sidebarRelayConnectionCard.isRelayConnectionSuccess
|
||||
}
|
||||
isReconnectPending={
|
||||
sidebarRelayConnectionCard.isRelayReconnectPending
|
||||
}
|
||||
isWaitingOnReconnectHook={
|
||||
sidebarRelayConnectionCard.isWaitingOnReconnectHook
|
||||
}
|
||||
onDismiss={
|
||||
sidebarRelayConnectionCard.onDismissRelayConnectionCard
|
||||
}
|
||||
onReconnect={sidebarRelayConnectionCard.onReconnectRelay}
|
||||
key="sidebar-relay-connection-card"
|
||||
/>
|
||||
) : null}
|
||||
</AnimatePresence>
|
||||
{relayConnectionCard.showSidebarRelayConnectionCard &&
|
||||
(isMobile ? openMobile : sidebarOpen) ? (
|
||||
<SidebarRelayConnectionCard
|
||||
className="mb-2"
|
||||
isConnected={relayConnectionCard.isRelayConnectionSuccess}
|
||||
isReconnectPending={relayConnectionCard.isRelayReconnectPending}
|
||||
isWaitingOnReconnectHook={
|
||||
relayConnectionCard.isWaitingOnReconnectHook
|
||||
}
|
||||
onDismiss={relayConnectionCard.onDismissRelayConnectionCard}
|
||||
onReconnect={relayConnectionCard.onReconnectRelay}
|
||||
/>
|
||||
) : null}
|
||||
{showSidebarUpdateCard ? (
|
||||
<div className="mb-2 group-data-[collapsible=icon]:hidden">
|
||||
<SidebarUpdateCard
|
||||
|
||||
@@ -68,9 +68,16 @@ export function useSidebarRelayConnectionCard(
|
||||
const hasRelayUnreachableError = errorMessage
|
||||
? isRelayUnreachableError(errorMessage)
|
||||
: false;
|
||||
// True when the error is an application-level issue (e.g. auth rejection)
|
||||
// rather than a network-level relay-unreachable error. In this case, the
|
||||
// disconnected state should NOT trigger the reconnect card — the app shows
|
||||
// a dedicated error path instead.
|
||||
const hasNonUnreachableError =
|
||||
Boolean(errorMessage) && !hasRelayUnreachableError;
|
||||
const isRelayConnectionStateDegraded =
|
||||
relayConnectionState === "reconnecting" ||
|
||||
relayConnectionState === "stalled";
|
||||
relayConnectionState === "stalled" ||
|
||||
(relayConnectionState === "disconnected" && !hasNonUnreachableError);
|
||||
const isRelayConnectionConnected = relayConnectionState === "connected";
|
||||
const isRelayConnectionDisconnected = relayConnectionState === "disconnected";
|
||||
const [isDismissed, setIsDismissed] = React.useState(false);
|
||||
|
||||
Reference in New Issue
Block a user