@mundogamernetwork/shared-ui 1.16.12 → 1.16.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,85 @@
1
+ <script setup lang="ts">
2
+ import { storeToRefs } from "pinia";
3
+
4
+ /**
5
+ * The account-menu toggle icon in the header top bar (not the dropdown
6
+ * panel itself — see MgHeaderUIUser for that). Every host used to inline
7
+ * this exact 3-line ClientOnly block, and all of them had the same gap:
8
+ * the very first thing painted — the ClientOnly #fallback, shown during
9
+ * SSR and until the client mounts — was a hardcoded guest icon. SSR can
10
+ * never know the real auth state here (the oauth_token cookie isn't
11
+ * readable server-side), so every real user saw themselves rendered as
12
+ * signed-out for a beat on every single page load, before the client's
13
+ * own getUser() call resolved and swapped in the real avatar. Showing a
14
+ * neutral skeleton instead — both in the fallback and while the client's
15
+ * own check is still in flight — means the icon is never confidently
16
+ * wrong, only "still figuring it out."
17
+ */
18
+ const props = withDefaults(defineProps<{ size?: number }>(), { size: 32 });
19
+
20
+ const authStore = useAuthStore();
21
+ const { user, signedIn } = storeToRefs(authStore);
22
+
23
+ // Not every host's store has adopted `initialized` yet (it's the signal
24
+ // that getUser() has settled, one way or the other — see stores/auth.ts
25
+ // in any already-migrated host for the reference shape). Read it
26
+ // defensively instead of destructuring: a host whose store doesn't expose
27
+ // it treats the state as already known, skipping the skeleton rather than
28
+ // getting stuck showing it forever.
29
+ const initialized = computed(() => {
30
+ const raw = (authStore as unknown as { initialized?: boolean }).initialized;
31
+ return raw === undefined ? true : raw;
32
+ });
33
+ </script>
34
+
35
+ <template>
36
+ <ClientOnly>
37
+ <div
38
+ v-if="!initialized"
39
+ class="mg-avatar-skeleton"
40
+ :style="{ width: `${props.size}px`, height: `${props.size}px` }"
41
+ />
42
+ <MGIcon v-else-if="!signedIn" icon="profile" />
43
+ <img
44
+ v-else
45
+ :src="user?.avatar_url"
46
+ :width="props.size"
47
+ :height="props.size"
48
+ class="mg-avatar-img"
49
+ />
50
+ <template #fallback>
51
+ <div
52
+ class="mg-avatar-skeleton"
53
+ :style="{ width: `${props.size}px`, height: `${props.size}px` }"
54
+ />
55
+ </template>
56
+ </ClientOnly>
57
+ </template>
58
+
59
+ <style scoped lang="scss">
60
+ .mg-avatar-skeleton {
61
+ // No border-radius — MGN is angular by brand decision, no rounded
62
+ // corners anywhere.
63
+ background: linear-gradient(
64
+ 90deg,
65
+ var(--skeleton-base, rgba(128, 128, 128, 0.18)) 25%,
66
+ var(--skeleton-shine, rgba(128, 128, 128, 0.32)) 50%,
67
+ var(--skeleton-base, rgba(128, 128, 128, 0.18)) 75%
68
+ );
69
+ background-size: 200% 100%;
70
+ animation: mg-avatar-skeleton-shimmer 1.4s ease-in-out infinite;
71
+ }
72
+
73
+ @keyframes mg-avatar-skeleton-shimmer {
74
+ 0% {
75
+ background-position: 200% 0;
76
+ }
77
+ 100% {
78
+ background-position: -200% 0;
79
+ }
80
+ }
81
+
82
+ .mg-avatar-img {
83
+ display: block;
84
+ }
85
+ </style>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mundogamernetwork/shared-ui",
3
- "version": "1.16.12",
3
+ "version": "1.16.13",
4
4
  "description": "Mundo Gamer Network - Shared UI Layer (Nuxt 3)",
5
5
  "type": "module",
6
6
  "main": "./nuxt.config.ts",