2024-10-04 14:43:02 +10:00
|
|
|
<template>
|
2024-10-08 16:13:46 +11:00
|
|
|
<div class="hidden lg:flex bg-zinc-950 flex-row px-12 xl:px-48 py-5">
|
|
|
|
|
<div class="grow inline-flex items-center gap-x-20">
|
2025-05-07 18:42:13 -04:00
|
|
|
<NuxtLink :to="homepageURL">
|
2025-04-16 12:03:42 -04:00
|
|
|
<DropWordmark class="h-8" />
|
2024-10-08 16:13:46 +11:00
|
|
|
</NuxtLink>
|
|
|
|
|
<nav class="inline-flex items-center">
|
|
|
|
|
<ol class="inline-flex items-center gap-x-12">
|
community: wire server registry deep links + main nav (friends widget, Community submenu, profile link)
- Resolve gameServerRegistry.json's null deep_link entries against the
live drop-db catalog (WoW, EverQuest, Among Us match real Game rows;
OpenDAoC and the Goldberg relay genuinely have none, left null and
documented why).
- Fix the "0 online now" panel bug: the community landing page's
persistent-world quick-strip was inferring presence from PlaySession
name-matching (presenceService.getServerPresence), which hardcodes
available=true even with zero matches -- always showing a fake "0"
for EQEmu instead of the honest unavailable state. Switched it to the
same probe-backed GameServer feed ServerStatusPanel already uses
(joined by the shared wow/eqemu/daoc slug), so known-zero and
count-unavailable never render the same.
- Header people icon now opens a friends flyout (list, incoming
requests with accept/decline, entry into chat with a friend) instead
of going nowhere, mirroring the existing notifications bell's
Menu/MenuButton/MenuItems pattern; badge shows pending request count.
Mobile sidebar links it straight to /community/friends.
- Community gets a hover submenu in the main nav (desktop) / inline
sublist (mobile) listing Friends, Chat, Devices, Mods, Servers,
Issues, Achievements.
- User dropdown menu gets a "Your profile" entry resolved from the
signed-in user's own username (/community/profile/<username>), not
hardcoded.
2026-08-03 11:02:58 -04:00
|
|
|
<template v-for="(nav, navIdx) in navigation" :key="navIdx">
|
|
|
|
|
<!-- Community gets a hover submenu listing its sections, same
|
|
|
|
|
spot players already look for site nav, instead of only
|
|
|
|
|
being reachable by first landing on /community itself. The
|
|
|
|
|
link underneath still navigates normally on click/tap --
|
|
|
|
|
only hover (desktop) reveals the submenu. -->
|
|
|
|
|
<div
|
|
|
|
|
v-if="nav.prefix === '/community'"
|
|
|
|
|
class="relative h-full group"
|
|
|
|
|
>
|
|
|
|
|
<NuxtLink
|
|
|
|
|
:href="nav.route"
|
|
|
|
|
:class="[
|
|
|
|
|
'transition hover:text-zinc-200 uppercase font-display font-semibold text-md',
|
|
|
|
|
navIdx === currentPageIndex
|
|
|
|
|
? 'text-zinc-100'
|
|
|
|
|
: 'text-zinc-400',
|
|
|
|
|
]"
|
|
|
|
|
>
|
|
|
|
|
{{ nav.label }}
|
|
|
|
|
</NuxtLink>
|
|
|
|
|
<div
|
|
|
|
|
class="absolute left-0 top-full pt-3 hidden group-hover:block group-focus-within:block z-50"
|
|
|
|
|
>
|
|
|
|
|
<PanelWidget class="flex-col gap-y-0.5 w-52">
|
|
|
|
|
<NuxtLink
|
|
|
|
|
v-for="sub in communitySubNav"
|
|
|
|
|
:key="sub.route"
|
|
|
|
|
:to="sub.route"
|
|
|
|
|
class="transition block rounded-sm px-4 py-2 text-sm font-display text-zinc-400 hover:bg-zinc-800 hover:text-zinc-100"
|
|
|
|
|
>
|
|
|
|
|
{{ sub.label }}
|
|
|
|
|
</NuxtLink>
|
|
|
|
|
</PanelWidget>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<NuxtLink
|
|
|
|
|
v-else
|
|
|
|
|
:href="nav.route"
|
|
|
|
|
:class="[
|
|
|
|
|
'transition hover:text-zinc-200 uppercase font-display font-semibold text-md',
|
|
|
|
|
navIdx === currentPageIndex ? 'text-zinc-100' : 'text-zinc-400',
|
|
|
|
|
]"
|
|
|
|
|
>
|
|
|
|
|
{{ nav.label }}
|
|
|
|
|
</NuxtLink>
|
|
|
|
|
</template>
|
2024-10-08 16:13:46 +11:00
|
|
|
</ol>
|
|
|
|
|
</nav>
|
2024-10-04 14:43:02 +10:00
|
|
|
</div>
|
2024-10-08 16:13:46 +11:00
|
|
|
<div class="inline-flex items-center">
|
|
|
|
|
<ol class="inline-flex gap-3">
|
2024-11-16 19:41:19 +11:00
|
|
|
<li>
|
community: wire server registry deep links + main nav (friends widget, Community submenu, profile link)
- Resolve gameServerRegistry.json's null deep_link entries against the
live drop-db catalog (WoW, EverQuest, Among Us match real Game rows;
OpenDAoC and the Goldberg relay genuinely have none, left null and
documented why).
- Fix the "0 online now" panel bug: the community landing page's
persistent-world quick-strip was inferring presence from PlaySession
name-matching (presenceService.getServerPresence), which hardcodes
available=true even with zero matches -- always showing a fake "0"
for EQEmu instead of the honest unavailable state. Switched it to the
same probe-backed GameServer feed ServerStatusPanel already uses
(joined by the shared wow/eqemu/daoc slug), so known-zero and
count-unavailable never render the same.
- Header people icon now opens a friends flyout (list, incoming
requests with accept/decline, entry into chat with a friend) instead
of going nowhere, mirroring the existing notifications bell's
Menu/MenuButton/MenuItems pattern; badge shows pending request count.
Mobile sidebar links it straight to /community/friends.
- Community gets a hover submenu in the main nav (desktop) / inline
sublist (mobile) listing Friends, Chat, Devices, Mods, Servers,
Issues, Achievements.
- User dropdown menu gets a "Your profile" entry resolved from the
signed-in user's own username (/community/profile/<username>), not
hardcoded.
2026-08-03 11:02:58 -04:00
|
|
|
<!-- Social entry point: friends list, incoming requests, and a
|
|
|
|
|
way into chat with a friend, matching the notifications
|
|
|
|
|
bell's own Menu/MenuButton/MenuItems flyout pattern right
|
|
|
|
|
next to it rather than a bare link to /community/friends. -->
|
|
|
|
|
<Menu as="div" class="relative inline-block">
|
|
|
|
|
<MenuButton>
|
|
|
|
|
<UserHeaderWidget :notifications="incomingFriendRequestCount">
|
|
|
|
|
<UserGroupIcon class="h-5" />
|
|
|
|
|
</UserHeaderWidget>
|
|
|
|
|
</MenuButton>
|
|
|
|
|
|
|
|
|
|
<transition
|
|
|
|
|
enter-active-class="transition ease-out duration-100"
|
|
|
|
|
enter-from-class="transform opacity-0 scale-95"
|
|
|
|
|
enter-to-class="transform opacity-100 scale-100"
|
|
|
|
|
leave-active-class="transition ease-in duration-75"
|
|
|
|
|
leave-from-class="transform opacity-100 scale-100"
|
|
|
|
|
leave-to-class="transform opacity-0 scale-95"
|
|
|
|
|
>
|
|
|
|
|
<MenuItems
|
|
|
|
|
class="absolute inset-x-0 -translate-x-1/2 top-10 z-50 w-96 focus:outline-none shadow-md"
|
|
|
|
|
>
|
|
|
|
|
<UserHeaderFriendsWidgetPanel :friends="friends" />
|
|
|
|
|
</MenuItems>
|
|
|
|
|
</transition>
|
|
|
|
|
</Menu>
|
2024-11-16 19:41:19 +11:00
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
<li>
|
|
|
|
|
<Menu as="div" class="relative inline-block">
|
|
|
|
|
<MenuButton>
|
|
|
|
|
<UserHeaderWidget :notifications="unreadNotifications.length">
|
|
|
|
|
<BellIcon class="h-5" />
|
|
|
|
|
</UserHeaderWidget>
|
|
|
|
|
</MenuButton>
|
|
|
|
|
|
|
|
|
|
<transition
|
|
|
|
|
enter-active-class="transition ease-out duration-100"
|
|
|
|
|
enter-from-class="transform opacity-0 scale-95"
|
|
|
|
|
enter-to-class="transform opacity-100 scale-100"
|
|
|
|
|
leave-active-class="transition ease-in duration-75"
|
|
|
|
|
leave-from-class="transform opacity-100 scale-100"
|
|
|
|
|
leave-to-class="transform opacity-0 scale-95"
|
|
|
|
|
>
|
|
|
|
|
<MenuItems
|
|
|
|
|
class="absolute inset-x-0 -translate-x-1/2 top-10 z-50 w-96 focus:outline-none shadow-md"
|
|
|
|
|
>
|
|
|
|
|
<UserHeaderNotificationWidgetPanel
|
|
|
|
|
:notifications="unreadNotifications"
|
|
|
|
|
/>
|
|
|
|
|
</MenuItems>
|
|
|
|
|
</transition>
|
|
|
|
|
</Menu>
|
2024-10-08 16:13:46 +11:00
|
|
|
</li>
|
2024-11-16 19:41:19 +11:00
|
|
|
<UserHeaderUserWidget />
|
2024-10-08 16:13:46 +11:00
|
|
|
</ol>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-10-27 15:52:30 +11:00
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
class="sticky lg:hidden top-0 z-40 flex h-16 justify-between items-center gap-x-4 border-b border-zinc-700 bg-zinc-950 px-4 shadow-sm sm:gap-x-6 sm:px-6 lg:px-8"
|
|
|
|
|
>
|
2025-05-07 18:42:13 -04:00
|
|
|
<NuxtLink :to="homepageURL">
|
2025-05-08 19:26:46 -04:00
|
|
|
<DropWordmark class="mb-0.5" />
|
2025-05-07 18:42:13 -04:00
|
|
|
</NuxtLink>
|
|
|
|
|
|
2024-10-27 15:52:30 +11:00
|
|
|
<div class="flex gap-x-4 lg:gap-x-6">
|
|
|
|
|
<div class="flex items-center gap-x-3">
|
|
|
|
|
<!-- Profile dropdown -->
|
2024-11-16 19:41:19 +11:00
|
|
|
<UserHeaderUserWidget />
|
2024-10-27 15:52:30 +11:00
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
2024-11-19 11:11:59 +11:00
|
|
|
class="-m-2.5 p-2.5 text-zinc-400 lg:hidden"
|
2024-10-27 15:52:30 +11:00
|
|
|
@click="sidebarOpen = true"
|
|
|
|
|
>
|
2025-06-04 19:53:30 -04:00
|
|
|
<span class="sr-only">{{ $t("header.openSidebar") }}</span>
|
2024-10-27 15:52:30 +11:00
|
|
|
<Bars3Icon class="h-6 w-6" aria-hidden="true" />
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<TransitionRoot as="template" :show="sidebarOpen">
|
|
|
|
|
<Dialog class="relative z-50 lg:hidden" @close="sidebarOpen = false">
|
|
|
|
|
<TransitionChild
|
|
|
|
|
as="template"
|
|
|
|
|
enter="transition-opacity ease-linear duration-300"
|
|
|
|
|
enter-from="opacity-0"
|
|
|
|
|
enter-to="opacity-100"
|
|
|
|
|
leave="transition-opacity ease-linear duration-300"
|
|
|
|
|
leave-from="opacity-100"
|
|
|
|
|
leave-to="opacity-0"
|
|
|
|
|
>
|
|
|
|
|
<div class="fixed inset-0 bg-zinc-900/80" />
|
|
|
|
|
</TransitionChild>
|
|
|
|
|
|
|
|
|
|
<div class="fixed inset-0 flex">
|
|
|
|
|
<TransitionChild
|
|
|
|
|
as="template"
|
|
|
|
|
enter="transition ease-in-out duration-300 transform"
|
|
|
|
|
enter-from="-translate-x-full"
|
|
|
|
|
enter-to="translate-x-0"
|
|
|
|
|
leave="transition ease-in-out duration-300 transform"
|
|
|
|
|
leave-from="translate-x-0"
|
|
|
|
|
leave-to="-translate-x-full"
|
|
|
|
|
>
|
|
|
|
|
<DialogPanel class="relative mr-16 flex w-full max-w-xs flex-1">
|
|
|
|
|
<TransitionChild
|
|
|
|
|
as="template"
|
|
|
|
|
enter="ease-in-out duration-300"
|
|
|
|
|
enter-from="opacity-0"
|
|
|
|
|
enter-to="opacity-100"
|
|
|
|
|
leave="ease-in-out duration-300"
|
|
|
|
|
leave-from="opacity-100"
|
|
|
|
|
leave-to="opacity-0"
|
|
|
|
|
>
|
|
|
|
|
<div
|
|
|
|
|
class="absolute left-full top-0 flex w-16 justify-center pt-5"
|
|
|
|
|
>
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
class="-m-2.5 p-2.5"
|
|
|
|
|
@click="sidebarOpen = false"
|
|
|
|
|
>
|
2025-06-04 19:53:30 -04:00
|
|
|
<span class="sr-only">{{
|
|
|
|
|
$t("userHeader.closeSidebar")
|
|
|
|
|
}}</span>
|
2024-10-27 15:52:30 +11:00
|
|
|
<XMarkIcon class="h-6 w-6 text-zinc-400" aria-hidden="true" />
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</TransitionChild>
|
|
|
|
|
<!-- Sidebar component, swap this element with another sidebar if you like -->
|
|
|
|
|
<div
|
|
|
|
|
class="flex grow flex-col gap-y-5 overflow-y-auto bg-zinc-950 px-6 pb-4"
|
|
|
|
|
>
|
|
|
|
|
<div class="flex shrink-0 h-16 items-center justify-between">
|
2025-05-07 18:42:13 -04:00
|
|
|
<NuxtLink :to="homepageURL">
|
2026-02-06 00:43:21 +00:00
|
|
|
<ApplicationLogo class="h-8 w-auto" />
|
2024-10-27 15:52:30 +11:00
|
|
|
</NuxtLink>
|
|
|
|
|
|
2024-11-16 19:41:19 +11:00
|
|
|
<UserHeaderUserWidget />
|
2024-10-27 15:52:30 +11:00
|
|
|
</div>
|
|
|
|
|
<nav class="flex flex-1 flex-col gap-y-8">
|
|
|
|
|
<ol class="flex flex-col gap-y-3">
|
community: wire server registry deep links + main nav (friends widget, Community submenu, profile link)
- Resolve gameServerRegistry.json's null deep_link entries against the
live drop-db catalog (WoW, EverQuest, Among Us match real Game rows;
OpenDAoC and the Goldberg relay genuinely have none, left null and
documented why).
- Fix the "0 online now" panel bug: the community landing page's
persistent-world quick-strip was inferring presence from PlaySession
name-matching (presenceService.getServerPresence), which hardcodes
available=true even with zero matches -- always showing a fake "0"
for EQEmu instead of the honest unavailable state. Switched it to the
same probe-backed GameServer feed ServerStatusPanel already uses
(joined by the shared wow/eqemu/daoc slug), so known-zero and
count-unavailable never render the same.
- Header people icon now opens a friends flyout (list, incoming
requests with accept/decline, entry into chat with a friend) instead
of going nowhere, mirroring the existing notifications bell's
Menu/MenuButton/MenuItems pattern; badge shows pending request count.
Mobile sidebar links it straight to /community/friends.
- Community gets a hover submenu in the main nav (desktop) / inline
sublist (mobile) listing Friends, Chat, Devices, Mods, Servers,
Issues, Achievements.
- User dropdown menu gets a "Your profile" entry resolved from the
signed-in user's own username (/community/profile/<username>), not
hardcoded.
2026-08-03 11:02:58 -04:00
|
|
|
<template v-for="(nav, navIdx) in navigation" :key="navIdx">
|
|
|
|
|
<NuxtLink
|
|
|
|
|
:href="nav.route"
|
|
|
|
|
:class="[
|
|
|
|
|
'transition hover:text-zinc-200 uppercase font-display font-semibold text-md',
|
|
|
|
|
navIdx === currentPageIndex
|
|
|
|
|
? 'text-zinc-100'
|
|
|
|
|
: 'text-zinc-400',
|
|
|
|
|
]"
|
|
|
|
|
>
|
|
|
|
|
{{ nav.label }}
|
|
|
|
|
</NuxtLink>
|
|
|
|
|
<!-- No hover on touch, so the mobile sidebar lists
|
|
|
|
|
Community's sections inline instead of behind a
|
|
|
|
|
hover flyout. -->
|
|
|
|
|
<div
|
|
|
|
|
v-if="nav.prefix === '/community'"
|
|
|
|
|
class="flex flex-col gap-y-2 pl-4 border-l border-zinc-800"
|
|
|
|
|
>
|
|
|
|
|
<NuxtLink
|
|
|
|
|
v-for="sub in communitySubNav"
|
|
|
|
|
:key="sub.route"
|
|
|
|
|
:to="sub.route"
|
|
|
|
|
class="transition hover:text-zinc-200 font-display font-semibold text-sm text-zinc-500"
|
|
|
|
|
>
|
|
|
|
|
{{ sub.label }}
|
|
|
|
|
</NuxtLink>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
2024-10-27 15:52:30 +11:00
|
|
|
</ol>
|
|
|
|
|
<div class="h-px w-full bg-zinc-700" />
|
|
|
|
|
<div class="flex flex-row gap-x-4 justify-stretch">
|
2024-11-16 19:41:19 +11:00
|
|
|
<li class="w-full">
|
community: wire server registry deep links + main nav (friends widget, Community submenu, profile link)
- Resolve gameServerRegistry.json's null deep_link entries against the
live drop-db catalog (WoW, EverQuest, Among Us match real Game rows;
OpenDAoC and the Goldberg relay genuinely have none, left null and
documented why).
- Fix the "0 online now" panel bug: the community landing page's
persistent-world quick-strip was inferring presence from PlaySession
name-matching (presenceService.getServerPresence), which hardcodes
available=true even with zero matches -- always showing a fake "0"
for EQEmu instead of the honest unavailable state. Switched it to the
same probe-backed GameServer feed ServerStatusPanel already uses
(joined by the shared wow/eqemu/daoc slug), so known-zero and
count-unavailable never render the same.
- Header people icon now opens a friends flyout (list, incoming
requests with accept/decline, entry into chat with a friend) instead
of going nowhere, mirroring the existing notifications bell's
Menu/MenuButton/MenuItems pattern; badge shows pending request count.
Mobile sidebar links it straight to /community/friends.
- Community gets a hover submenu in the main nav (desktop) / inline
sublist (mobile) listing Friends, Chat, Devices, Mods, Servers,
Issues, Achievements.
- User dropdown menu gets a "Your profile" entry resolved from the
signed-in user's own username (/community/profile/<username>), not
hardcoded.
2026-08-03 11:02:58 -04:00
|
|
|
<NuxtLink to="/community/friends" class="block w-full">
|
|
|
|
|
<UserHeaderWidget
|
|
|
|
|
class="w-full"
|
|
|
|
|
:notifications="incomingFriendRequestCount"
|
|
|
|
|
>
|
|
|
|
|
<UserGroupIcon class="h-5" />
|
|
|
|
|
</UserHeaderWidget>
|
|
|
|
|
</NuxtLink>
|
2024-11-16 19:41:19 +11:00
|
|
|
</li>
|
|
|
|
|
<li class="w-full">
|
|
|
|
|
<UserHeaderWidget
|
|
|
|
|
class="w-full"
|
|
|
|
|
:notifications="unreadNotifications.length"
|
2024-10-27 15:52:30 +11:00
|
|
|
>
|
2024-11-16 19:41:19 +11:00
|
|
|
<BellIcon class="h-5" />
|
|
|
|
|
</UserHeaderWidget>
|
2024-10-27 15:52:30 +11:00
|
|
|
</li>
|
2025-06-04 19:53:30 -04:00
|
|
|
<li class="w-full">
|
2025-06-08 10:33:41 +10:00
|
|
|
<UserHeaderWidget class="w-full" />
|
2025-06-04 19:53:30 -04:00
|
|
|
</li>
|
2024-10-27 15:52:30 +11:00
|
|
|
</div>
|
|
|
|
|
</nav>
|
|
|
|
|
</div>
|
|
|
|
|
</DialogPanel>
|
|
|
|
|
</TransitionChild>
|
|
|
|
|
</div>
|
|
|
|
|
</Dialog>
|
|
|
|
|
</TransitionRoot>
|
2024-10-04 14:43:02 +10:00
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2025-05-08 19:26:46 -04:00
|
|
|
import { BellIcon, UserGroupIcon } from "@heroicons/vue/16/solid";
|
2024-10-27 15:52:30 +11:00
|
|
|
import {
|
|
|
|
|
Dialog,
|
|
|
|
|
DialogPanel,
|
|
|
|
|
TransitionChild,
|
|
|
|
|
TransitionRoot,
|
2024-11-16 19:41:19 +11:00
|
|
|
Menu,
|
|
|
|
|
MenuButton,
|
|
|
|
|
MenuItems,
|
2024-10-27 15:52:30 +11:00
|
|
|
} from "@headlessui/vue";
|
2024-11-16 19:41:19 +11:00
|
|
|
import type { NavigationItem } from "../composables/types";
|
2024-10-27 15:52:30 +11:00
|
|
|
import { Bars3Icon } from "@heroicons/vue/24/outline";
|
|
|
|
|
import { XMarkIcon } from "@heroicons/vue/24/solid";
|
|
|
|
|
|
|
|
|
|
const router = useRouter();
|
2025-06-04 19:53:30 -04:00
|
|
|
const { t } = useI18n();
|
2024-10-04 14:43:02 +10:00
|
|
|
|
2025-05-07 18:42:13 -04:00
|
|
|
const homepageURL = "/store";
|
2025-06-08 10:33:41 +10:00
|
|
|
const navigation: Ref<Array<NavigationItem>> = computed(() => [
|
2024-10-08 16:13:46 +11:00
|
|
|
{
|
|
|
|
|
prefix: "/store",
|
|
|
|
|
route: "/store",
|
2025-06-04 19:53:30 -04:00
|
|
|
label: t("store.title"),
|
2024-10-08 16:13:46 +11:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
prefix: "/library",
|
|
|
|
|
route: "/library",
|
2025-06-04 19:53:30 -04:00
|
|
|
label: t("userHeader.links.library"),
|
2024-10-08 16:13:46 +11:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
prefix: "/community",
|
|
|
|
|
route: "/community",
|
2025-06-04 19:53:30 -04:00
|
|
|
label: t("userHeader.links.community"),
|
2024-10-08 16:13:46 +11:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
prefix: "/news",
|
|
|
|
|
route: "/news",
|
2025-06-04 19:53:30 -04:00
|
|
|
label: t("userHeader.links.news"),
|
2024-10-08 16:13:46 +11:00
|
|
|
},
|
2025-06-08 10:33:41 +10:00
|
|
|
]);
|
2024-10-04 14:43:02 +10:00
|
|
|
|
2025-06-08 10:33:41 +10:00
|
|
|
const currentPageIndex = useCurrentNavigationIndex(navigation.value);
|
2024-10-11 22:45:02 +11:00
|
|
|
|
community: wire server registry deep links + main nav (friends widget, Community submenu, profile link)
- Resolve gameServerRegistry.json's null deep_link entries against the
live drop-db catalog (WoW, EverQuest, Among Us match real Game rows;
OpenDAoC and the Goldberg relay genuinely have none, left null and
documented why).
- Fix the "0 online now" panel bug: the community landing page's
persistent-world quick-strip was inferring presence from PlaySession
name-matching (presenceService.getServerPresence), which hardcodes
available=true even with zero matches -- always showing a fake "0"
for EQEmu instead of the honest unavailable state. Switched it to the
same probe-backed GameServer feed ServerStatusPanel already uses
(joined by the shared wow/eqemu/daoc slug), so known-zero and
count-unavailable never render the same.
- Header people icon now opens a friends flyout (list, incoming
requests with accept/decline, entry into chat with a friend) instead
of going nowhere, mirroring the existing notifications bell's
Menu/MenuButton/MenuItems pattern; badge shows pending request count.
Mobile sidebar links it straight to /community/friends.
- Community gets a hover submenu in the main nav (desktop) / inline
sublist (mobile) listing Friends, Chat, Devices, Mods, Servers,
Issues, Achievements.
- User dropdown menu gets a "Your profile" entry resolved from the
signed-in user's own username (/community/profile/<username>), not
hardcoded.
2026-08-03 11:02:58 -04:00
|
|
|
// Community submenu -- the sections the user asked to have reachable from
|
|
|
|
|
// the main nav (Friends, Chat, Devices, Mods at minimum; Servers, Issues,
|
|
|
|
|
// and Achievements fit the exact same "one page per community feature"
|
|
|
|
|
// pattern so they're included too). A plain list, not NavigationItem[]:
|
|
|
|
|
// these are never the "current top-level section" for the prefix-matching
|
|
|
|
|
// highlighter above, they're always rendered as a flat submenu.
|
|
|
|
|
const communitySubNav = computed(() => [
|
|
|
|
|
{ route: "/community/friends", label: t("community.friends.title") },
|
|
|
|
|
{ route: "/community/chat", label: t("community.chat.title") },
|
|
|
|
|
{ route: "/community/devices", label: t("community.devices.title") },
|
|
|
|
|
{ route: "/community/mods", label: t("community.mods.title") },
|
|
|
|
|
{ route: "/community/servers", label: t("community.servers.title") },
|
|
|
|
|
{ route: "/community/issues", label: t("community.issues.title") },
|
|
|
|
|
{
|
|
|
|
|
route: "/community/achievements",
|
|
|
|
|
label: t("community.achievements.title"),
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
|
2024-11-16 19:41:19 +11:00
|
|
|
const notifications = useNotifications();
|
|
|
|
|
const unreadNotifications = computed(() =>
|
2025-04-15 21:46:34 -04:00
|
|
|
notifications.value.filter((e) => !e.read),
|
2024-11-16 19:41:19 +11:00
|
|
|
);
|
2024-10-27 15:52:30 +11:00
|
|
|
|
community: wire server registry deep links + main nav (friends widget, Community submenu, profile link)
- Resolve gameServerRegistry.json's null deep_link entries against the
live drop-db catalog (WoW, EverQuest, Among Us match real Game rows;
OpenDAoC and the Goldberg relay genuinely have none, left null and
documented why).
- Fix the "0 online now" panel bug: the community landing page's
persistent-world quick-strip was inferring presence from PlaySession
name-matching (presenceService.getServerPresence), which hardcodes
available=true even with zero matches -- always showing a fake "0"
for EQEmu instead of the honest unavailable state. Switched it to the
same probe-backed GameServer feed ServerStatusPanel already uses
(joined by the shared wow/eqemu/daoc slug), so known-zero and
count-unavailable never render the same.
- Header people icon now opens a friends flyout (list, incoming
requests with accept/decline, entry into chat with a friend) instead
of going nowhere, mirroring the existing notifications bell's
Menu/MenuButton/MenuItems pattern; badge shows pending request count.
Mobile sidebar links it straight to /community/friends.
- Community gets a hover submenu in the main nav (desktop) / inline
sublist (mobile) listing Friends, Chat, Devices, Mods, Servers,
Issues, Achievements.
- User dropdown menu gets a "Your profile" entry resolved from the
signed-in user's own username (/community/profile/<username>), not
hardcoded.
2026-08-03 11:02:58 -04:00
|
|
|
// Friends widget (people icon) -- fetched on mount rather than at module
|
|
|
|
|
// scope like notifications' websocket, since this is a plain request that
|
|
|
|
|
// only makes sense once a signed-in user exists. Re-fetched on every
|
|
|
|
|
// "friend.request" event (new request, accept, decline) the same way
|
|
|
|
|
// pages/community/friends.vue already does, so the header badge and any
|
|
|
|
|
// open flyout both stay live without a page reload.
|
|
|
|
|
const user = useUser();
|
|
|
|
|
const friends = useCommunityFriends();
|
|
|
|
|
const incomingFriendRequestCount = computed(
|
|
|
|
|
() => friends.value?.incomingRequests.length ?? 0,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
if (user.value) refreshCommunityFriends();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const communityChat = useCommunityChatSocket();
|
|
|
|
|
communityChat.on((envelope) => {
|
|
|
|
|
if (envelope.t === "friend.request" && user.value) refreshCommunityFriends();
|
|
|
|
|
});
|
|
|
|
|
|
2024-10-27 15:52:30 +11:00
|
|
|
const sidebarOpen = ref(false);
|
|
|
|
|
router.afterEach(() => (sidebarOpen.value = false));
|
2024-10-08 16:13:46 +11:00
|
|
|
</script>
|