diff --git a/app.vue b/app.vue index 01cc22fd2..d72dbdfe0 100644 --- a/app.vue +++ b/app.vue @@ -12,6 +12,9 @@ const MatchmakingConfirm = defineAsyncComponent( const MatchActiveAlert = defineAsyncComponent( () => import("~/components/match/MatchActiveAlert.vue"), ); +const DraftActiveAlert = defineAsyncComponent( + () => import("~/components/draft-games/DraftActiveAlert.vue"), +); const PlayerNameRegistration = defineAsyncComponent( () => import("~/components/PlayerNameRegistration.vue"), ); @@ -100,10 +103,14 @@ function pageKeyWithoutTabQuery(route: { + - + diff --git a/assets/css/tailwind.css b/assets/css/tailwind.css index c66fab60a..9f5e03df8 100644 --- a/assets/css/tailwind.css +++ b/assets/css/tailwind.css @@ -339,3 +339,35 @@ mark { .share-flash { animation: share-flash 600ms ease-out; } + +/* Global route transition (NuxtPage). Kept short so each page's own + PageTransition appear-reveals still read on top of the crossfade — + smooths route changes like draft-room <-> match instead of a hard cut. */ +.page-enter-active { + transition: + opacity 280ms ease, + transform 360ms cubic-bezier(0.16, 1, 0.3, 1); +} +.page-leave-active { + transition: + opacity 200ms ease, + transform 220ms ease; +} +.page-enter-from { + opacity: 0; + transform: translateY(8px); +} +.page-leave-to { + opacity: 0; + transform: translateY(-6px); +} +@media (prefers-reduced-motion: reduce) { + .page-enter-active, + .page-leave-active { + transition-duration: 1ms; + } + .page-enter-from, + .page-leave-to { + transform: none; + } +} diff --git a/components/BreadCrumbs.vue b/components/BreadCrumbs.vue index 3c06f8495..53d782e64 100644 --- a/components/BreadCrumbs.vue +++ b/components/BreadCrumbs.vue @@ -44,6 +44,7 @@ import { useTournamentContext } from "~/composables/useTournamentContext"; import { useMatchContext } from "~/composables/useMatchContext"; import { usePlayerContext } from "~/composables/usePlayerContext"; import { useTeamContext } from "~/composables/useTeamContext"; +import { useDraftRoomContext } from "~/composables/useDraftRoomContext"; export default { computed: { @@ -59,6 +60,7 @@ export default { const mc = useMatchContext(); const pc = usePlayerContext(); const teamc = useTeamContext(); + const drc = useDraftRoomContext(); const breadcrumbs: Array<{ text: string; to: string; @@ -136,6 +138,17 @@ export default { return; } + if (segments[0] === "draft-room" && index === 1) { + if (drc.value?.id !== segment) { + return; + } + breadcrumbs.push({ + text: drc.value.name, + to: path, + }); + return; + } + breadcrumbs.push({ text: segment, to: path, diff --git a/components/MatchOptions.vue b/components/MatchOptions.vue index 33b0d49e2..a40002c03 100644 --- a/components/MatchOptions.vue +++ b/components/MatchOptions.vue @@ -2,7 +2,7 @@ import MapDisplay from "~/components/MapDisplay.vue"; import { FormControl } from "~/components/ui/form"; import { Separator } from "~/components/ui/separator"; -import { Info } from "lucide-vue-next"; +import { Info, ExternalLink } from "lucide-vue-next"; import { Check, ChevronsUpDown, @@ -11,14 +11,12 @@ import { SettingsIcon, Search, } from "lucide-vue-next"; -import { - Collapsible, - CollapsibleTrigger, - CollapsibleContent, -} from "~/components/ui/collapsible"; +import { Collapsible, CollapsibleTrigger } from "~/components/ui/collapsible"; +import AnimatedFilters from "~/components/common/AnimatedFilters.vue"; import FiveStackToolTip from "./FiveStackToolTip.vue"; import RegionStatusDot from "~/components/regions/RegionStatusDot.vue"; import { Card } from "~/components/ui/card"; +import SettingHeader from "~/components/match/SettingHeader.vue";