diff --git a/resources/js/components/profile-back-button.tsx b/resources/js/components/profile-back-button.tsx new file mode 100644 index 000000000..fdce5151e --- /dev/null +++ b/resources/js/components/profile-back-button.tsx @@ -0,0 +1,21 @@ +import { ArrowLeft } from 'lucide-react'; +import { useGoBack } from '@/hooks/use-go-back'; +import { cn } from '@/lib/utils'; + +export function ProfileBackButton({ className }: { className?: string }) { + const goBack = useGoBack(); + + return ( + + ); +} diff --git a/resources/js/hooks/use-go-back.ts b/resources/js/hooks/use-go-back.ts new file mode 100644 index 000000000..44808496d --- /dev/null +++ b/resources/js/hooks/use-go-back.ts @@ -0,0 +1,31 @@ +import { router, usePage } from '@inertiajs/react'; +import LogController from '@/actions/App/Http/Controllers/LogController'; +import { home } from '@/routes'; + +function hasPreviousEntry(): boolean { + // `history.length` counts forward entries too, so it cannot tell whether + // `history.back()` will actually navigate. The Navigation API can. + if (typeof window.navigation?.canGoBack === 'boolean') { + return window.navigation.canGoBack; + } + + return window.history.length > 1; +} + +/** + * Navigates back, falling back to the viewer's log (or the home page for + * guests) when there is no previous entry to go back to. + */ +export function useGoBack(): () => void { + const { auth } = usePage().props; + + return () => { + if (hasPreviousEntry()) { + window.history.back(); + + return; + } + + router.visit(auth.log === null ? home() : LogController.show(auth.log)); + }; +} diff --git a/resources/js/pages/commit/show.tsx b/resources/js/pages/commit/show.tsx index 1daf2f57d..7b9ea6cdf 100644 --- a/resources/js/pages/commit/show.tsx +++ b/resources/js/pages/commit/show.tsx @@ -1,14 +1,13 @@ -import { Head, router, usePage } from '@inertiajs/react'; +import { Head } from '@inertiajs/react'; import { ArrowLeft } from 'lucide-react'; -import LogController from '@/actions/App/Http/Controllers/LogController'; import { CommitCard, CommitTombstone } from '@/components/commit-card'; import { CopyLinkButton } from '@/components/copy-link-button'; import { GraphCanvas } from '@/components/graph-canvas'; import { RelatedCommits } from '@/components/related-commits'; import { useContinuation } from '@/hooks/use-continuation'; +import { useGoBack } from '@/hooks/use-go-back'; import AppLayout from '@/layouts/app-layout'; import { isDeleted, laneOf, shortHash } from '@/lib/utils'; -import { home } from '@/routes'; import type { Commit, CursorPaginated, @@ -29,9 +28,9 @@ export default function Show({ continuation: ThreadContinuation; replies: CursorPaginated | null; }) { - const { auth } = usePage().props; const { shown, nextId, size, isCapped, isLoading, loadMore } = useContinuation(continuation); + const goBack = useGoBack(); const focusedPosition = continuation.position; const positionAt = (position: number) => size > 1 && position >= 1 ? { position, size, isCapped } : undefined; @@ -41,16 +40,6 @@ export default function Show({ ? `${commit.body.slice(0, titleLength).trimEnd()}…` : commit.body; - const goBack = () => { - if (window.history.length > 1) { - window.history.back(); - - return; - } - - router.visit(auth.log === null ? home() : LogController.show(auth.log)); - }; - const lastAncestor = ancestors.at(-1); return ( @@ -62,7 +51,7 @@ export default function Show({ type="button" onClick={goBack} aria-label="Back" - className="text-muted-foreground hover:text-foreground" + className="-m-3 inline-flex items-center justify-center p-3 text-muted-foreground transition-colors hover:text-foreground" > diff --git a/resources/js/pages/user/show.tsx b/resources/js/pages/user/show.tsx index 28cc13e3b..9ce1218c3 100644 --- a/resources/js/pages/user/show.tsx +++ b/resources/js/pages/user/show.tsx @@ -32,6 +32,7 @@ import { LocalTime } from '@/components/local-time'; import { PageTabs } from '@/components/page-tabs'; import { PinCommitButton } from '@/components/pin-commit-button'; import { ProfileActionsMenu } from '@/components/profile-actions-menu'; +import { ProfileBackButton } from '@/components/profile-back-button'; import { ProfileReadme } from '@/components/profile-readme'; import { ProfileShareButton } from '@/components/profile-share-button'; import { Button } from '@/components/ui/button'; @@ -123,6 +124,7 @@ export default function Show({
+

{user.name}