@wakastellar/ui 2.1.2 → 2.3.2
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.
- package/dist/blocks/apm-overview/index.d.ts +58 -0
- package/dist/blocks/cicd-builder/index.d.ts +47 -0
- package/dist/blocks/cloud-cost-dashboard/index.d.ts +49 -0
- package/dist/blocks/container-orchestrator/index.d.ts +63 -0
- package/dist/blocks/database-admin/index.d.ts +84 -0
- package/dist/blocks/gitops-sync-status/index.d.ts +45 -0
- package/dist/blocks/incident-manager/index.d.ts +44 -0
- package/dist/blocks/index.d.ts +10 -0
- package/dist/blocks/infrastructure-map/index.d.ts +32 -0
- package/dist/blocks/on-call-schedule/index.d.ts +43 -0
- package/dist/blocks/release-notes/index.d.ts +49 -0
- package/dist/components/index.d.ts +34 -0
- package/dist/components/waka-ad-banner/index.d.ts +36 -0
- package/dist/components/waka-ad-fallback/index.d.ts +33 -0
- package/dist/components/waka-ad-inline/index.d.ts +15 -0
- package/dist/components/waka-ad-interstitial/index.d.ts +26 -0
- package/dist/components/waka-ad-placeholder/index.d.ts +17 -0
- package/dist/components/waka-ad-provider/index.d.ts +103 -0
- package/dist/components/waka-ad-sidebar/index.d.ts +18 -0
- package/dist/components/waka-ad-sticky-footer/index.d.ts +17 -0
- package/dist/components/waka-alert-panel/index.d.ts +45 -0
- package/dist/components/waka-artifact-list/index.d.ts +32 -0
- package/dist/components/waka-build-matrix/index.d.ts +36 -0
- package/dist/components/waka-config-comparator/index.d.ts +37 -0
- package/dist/components/waka-container-list/index.d.ts +51 -0
- package/dist/components/waka-content-recommendation/index.d.ts +23 -0
- package/dist/components/waka-database-card/index.d.ts +46 -0
- package/dist/components/waka-dependency-tree/index.d.ts +38 -0
- package/dist/components/waka-env-var-editor/index.d.ts +30 -0
- package/dist/components/waka-feature-flag-row/index.d.ts +45 -0
- package/dist/components/waka-kubernetes-overview/index.d.ts +98 -0
- package/dist/components/waka-log-viewer/index.d.ts +38 -0
- package/dist/components/waka-migration-list/index.d.ts +36 -0
- package/dist/components/waka-outstream-video/index.d.ts +24 -0
- package/dist/components/waka-pod-card/index.d.ts +73 -0
- package/dist/components/waka-query-explain/index.d.ts +48 -0
- package/dist/components/waka-secret-card/index.d.ts +43 -0
- package/dist/components/waka-security-scan-result/index.d.ts +45 -0
- package/dist/components/waka-service-graph/index.d.ts +44 -0
- package/dist/components/waka-sponsored-badge/index.d.ts +20 -0
- package/dist/components/waka-sponsored-card/index.d.ts +25 -0
- package/dist/components/waka-sponsored-feed/index.d.ts +31 -0
- package/dist/components/waka-test-report/index.d.ts +60 -0
- package/dist/components/waka-trace-viewer/index.d.ts +36 -0
- package/dist/components/waka-video-ad/index.d.ts +32 -0
- package/dist/components/waka-video-overlay/index.d.ts +26 -0
- package/dist/index.cjs.js +251 -200
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +47315 -35823
- package/dist/utils/security.d.ts +96 -0
- package/package.json +4 -4
- package/src/blocks/apm-overview/index.tsx +672 -0
- package/src/blocks/cicd-builder/index.tsx +738 -0
- package/src/blocks/cloud-cost-dashboard/index.tsx +597 -0
- package/src/blocks/container-orchestrator/index.tsx +729 -0
- package/src/blocks/database-admin/index.tsx +679 -0
- package/src/blocks/gitops-sync-status/index.tsx +557 -0
- package/src/blocks/incident-manager/index.tsx +586 -0
- package/src/blocks/index.ts +119 -0
- package/src/blocks/infrastructure-map/index.tsx +638 -0
- package/src/blocks/on-call-schedule/index.tsx +615 -0
- package/src/blocks/release-notes/index.tsx +643 -0
- package/src/blocks/sidebar/index.tsx +6 -6
- package/src/components/DataTable/templates/index.tsx +3 -2
- package/src/components/index.ts +283 -0
- package/src/components/waka-3d-pie-chart/index.tsx +11 -11
- package/src/components/waka-achievement-unlock/index.tsx +16 -16
- package/src/components/waka-ad-banner/index.tsx +275 -0
- package/src/components/waka-ad-fallback/index.tsx +181 -0
- package/src/components/waka-ad-inline/index.tsx +103 -0
- package/src/components/waka-ad-interstitial/index.tsx +278 -0
- package/src/components/waka-ad-placeholder/index.tsx +84 -0
- package/src/components/waka-ad-provider/index.tsx +329 -0
- package/src/components/waka-ad-sidebar/index.tsx +113 -0
- package/src/components/waka-ad-sticky-footer/index.tsx +125 -0
- package/src/components/waka-alert-panel/index.tsx +493 -0
- package/src/components/waka-artifact-list/index.tsx +416 -0
- package/src/components/waka-badge-showcase/index.tsx +12 -11
- package/src/components/waka-build-matrix/index.tsx +396 -0
- package/src/components/waka-command-bar/index.tsx +2 -1
- package/src/components/waka-config-comparator/index.tsx +416 -0
- package/src/components/waka-container-list/index.tsx +475 -0
- package/src/components/waka-content-recommendation/index.tsx +294 -0
- package/src/components/waka-cost-breakdown/index.tsx +10 -10
- package/src/components/waka-database-card/index.tsx +473 -0
- package/src/components/waka-dependency-tree/index.tsx +542 -0
- package/src/components/waka-env-var-editor/index.tsx +417 -0
- package/src/components/waka-feature-flag-row/index.tsx +386 -0
- package/src/components/waka-funnel-chart/index.tsx +8 -8
- package/src/components/waka-health-pulse/index.tsx +6 -6
- package/src/components/waka-kubernetes-overview/index.tsx +536 -0
- package/src/components/waka-leaderboard/index.tsx +9 -9
- package/src/components/waka-log-viewer/index.tsx +386 -0
- package/src/components/waka-loot-box/index.tsx +20 -20
- package/src/components/waka-migration-list/index.tsx +487 -0
- package/src/components/waka-outstream-video/index.tsx +240 -0
- package/src/components/waka-player-card/index.tsx +5 -5
- package/src/components/waka-pod-card/index.tsx +528 -0
- package/src/components/waka-query-explain/index.tsx +657 -0
- package/src/components/waka-quota-bar/index.tsx +4 -4
- package/src/components/waka-radar-score/index.tsx +10 -10
- package/src/components/waka-scratch-card/index.tsx +5 -4
- package/src/components/waka-secret-card/index.tsx +371 -0
- package/src/components/waka-security-scan-result/index.tsx +473 -0
- package/src/components/waka-server-rack/index.tsx +28 -27
- package/src/components/waka-service-graph/index.tsx +445 -0
- package/src/components/waka-sponsored-badge/index.tsx +97 -0
- package/src/components/waka-sponsored-card/index.tsx +275 -0
- package/src/components/waka-sponsored-feed/index.tsx +127 -0
- package/src/components/waka-spotlight/index.tsx +2 -1
- package/src/components/waka-success-explosion/index.tsx +4 -4
- package/src/components/waka-test-report/index.tsx +469 -0
- package/src/components/waka-trace-viewer/index.tsx +490 -0
- package/src/components/waka-video-ad/index.tsx +406 -0
- package/src/components/waka-video-overlay/index.tsx +257 -0
- package/src/components/waka-xp-bar/index.tsx +13 -13
- package/src/styles/base.css +16 -0
- package/src/styles/tailwind.preset.js +12 -0
- package/src/styles/themes/forest.css +16 -0
- package/src/styles/themes/monochrome.css +16 -0
- package/src/styles/themes/perpetuity.css +16 -0
- package/src/styles/themes/sunset.css +16 -0
- package/src/styles/themes/twilight.css +16 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { useRef, useState, useEffect } from "react"
|
|
5
|
+
import { cn } from "../../utils/cn"
|
|
6
|
+
import { useAdContext, useAdVisibility, type CustomAd } from "../waka-ad-provider"
|
|
7
|
+
import { WakaSponsoredBadge } from "../waka-sponsored-badge"
|
|
8
|
+
import { X, Volume2, VolumeX } from "lucide-react"
|
|
9
|
+
|
|
10
|
+
export interface WakaOutstreamVideoProps {
|
|
11
|
+
/** Unique slot ID */
|
|
12
|
+
slotId: string
|
|
13
|
+
/** Collapse when video ends or is closed */
|
|
14
|
+
collapseOnEnd?: boolean
|
|
15
|
+
/** Collapse animation duration (ms) */
|
|
16
|
+
collapseDuration?: number
|
|
17
|
+
/** Start muted */
|
|
18
|
+
muted?: boolean
|
|
19
|
+
/** Show close button */
|
|
20
|
+
showClose?: boolean
|
|
21
|
+
/** Close after seconds (0 = manual only) */
|
|
22
|
+
closeAfter?: number
|
|
23
|
+
/** Minimum visibility to start playing (0-1) */
|
|
24
|
+
visibilityThreshold?: number
|
|
25
|
+
/** Custom class name */
|
|
26
|
+
className?: string
|
|
27
|
+
/** Callback when video completes */
|
|
28
|
+
onComplete?: () => void
|
|
29
|
+
/** Callback when closed */
|
|
30
|
+
onClose?: () => void
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function WakaOutstreamVideo({
|
|
34
|
+
slotId,
|
|
35
|
+
collapseOnEnd = true,
|
|
36
|
+
collapseDuration = 300,
|
|
37
|
+
muted = true,
|
|
38
|
+
showClose = true,
|
|
39
|
+
closeAfter = 0,
|
|
40
|
+
visibilityThreshold = 0.5,
|
|
41
|
+
className,
|
|
42
|
+
onComplete,
|
|
43
|
+
onClose,
|
|
44
|
+
}: WakaOutstreamVideoProps) {
|
|
45
|
+
const containerRef = useRef<HTMLDivElement>(null)
|
|
46
|
+
const videoRef = useRef<HTMLVideoElement>(null)
|
|
47
|
+
const { config, isReady, hasConsent, getCustomAd, trackEvent } = useAdContext()
|
|
48
|
+
const { isVisible } = useAdVisibility(containerRef, visibilityThreshold)
|
|
49
|
+
|
|
50
|
+
const [status, setStatus] = useState<"loading" | "loaded" | "error" | "collapsed">("loading")
|
|
51
|
+
const [ad, setAd] = useState<CustomAd | null>(null)
|
|
52
|
+
const [isMuted, setIsMuted] = useState(muted)
|
|
53
|
+
const [isCollapsing, setIsCollapsing] = useState(false)
|
|
54
|
+
const [containerHeight, setContainerHeight] = useState<number | "auto">("auto")
|
|
55
|
+
const [hasStarted, setHasStarted] = useState(false)
|
|
56
|
+
|
|
57
|
+
// Load ad
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (!isReady || hasConsent === false) return
|
|
60
|
+
|
|
61
|
+
const loadAd = async () => {
|
|
62
|
+
try {
|
|
63
|
+
const customAd = await getCustomAd(slotId)
|
|
64
|
+
if (customAd?.videoUrl) {
|
|
65
|
+
setAd(customAd)
|
|
66
|
+
setStatus("loaded")
|
|
67
|
+
trackEvent({ type: "loaded", slotId, timestamp: new Date() })
|
|
68
|
+
} else {
|
|
69
|
+
setStatus("collapsed")
|
|
70
|
+
}
|
|
71
|
+
} catch {
|
|
72
|
+
setStatus("collapsed")
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
loadAd()
|
|
77
|
+
}, [isReady, hasConsent, slotId, getCustomAd, trackEvent])
|
|
78
|
+
|
|
79
|
+
// Play/pause based on visibility
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (!videoRef.current || status !== "loaded") return
|
|
82
|
+
|
|
83
|
+
if (isVisible) {
|
|
84
|
+
videoRef.current.play().then(() => {
|
|
85
|
+
if (!hasStarted) {
|
|
86
|
+
setHasStarted(true)
|
|
87
|
+
trackEvent({ type: "impression", slotId, timestamp: new Date() })
|
|
88
|
+
if (ad?.impressionUrl) {
|
|
89
|
+
fetch(ad.impressionUrl, { mode: "no-cors" }).catch(() => {})
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}).catch(() => {})
|
|
93
|
+
} else {
|
|
94
|
+
videoRef.current.pause()
|
|
95
|
+
}
|
|
96
|
+
}, [isVisible, status, hasStarted, slotId, ad, trackEvent])
|
|
97
|
+
|
|
98
|
+
// Auto-close timer
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (closeAfter === 0 || !hasStarted) return
|
|
101
|
+
|
|
102
|
+
const timer = setTimeout(() => {
|
|
103
|
+
handleCollapse()
|
|
104
|
+
}, closeAfter * 1000)
|
|
105
|
+
|
|
106
|
+
return () => clearTimeout(timer)
|
|
107
|
+
}, [closeAfter, hasStarted])
|
|
108
|
+
|
|
109
|
+
// Set initial height after load
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
if (status === "loaded" && containerRef.current) {
|
|
112
|
+
setContainerHeight(containerRef.current.offsetHeight)
|
|
113
|
+
}
|
|
114
|
+
}, [status])
|
|
115
|
+
|
|
116
|
+
const handleCollapse = () => {
|
|
117
|
+
if (collapseOnEnd) {
|
|
118
|
+
setIsCollapsing(true)
|
|
119
|
+
setContainerHeight(0)
|
|
120
|
+
setTimeout(() => {
|
|
121
|
+
setStatus("collapsed")
|
|
122
|
+
onClose?.()
|
|
123
|
+
}, collapseDuration)
|
|
124
|
+
} else {
|
|
125
|
+
setStatus("collapsed")
|
|
126
|
+
onClose?.()
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const handleEnded = () => {
|
|
131
|
+
trackEvent({ type: "viewable", slotId, timestamp: new Date(), data: { completed: true } })
|
|
132
|
+
onComplete?.()
|
|
133
|
+
handleCollapse()
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const handleToggleMute = () => {
|
|
137
|
+
if (videoRef.current) {
|
|
138
|
+
videoRef.current.muted = !isMuted
|
|
139
|
+
setIsMuted(!isMuted)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const handleClick = () => {
|
|
144
|
+
if (!ad) return
|
|
145
|
+
|
|
146
|
+
trackEvent({ type: "click", slotId, timestamp: new Date() })
|
|
147
|
+
if (ad.clickUrl) {
|
|
148
|
+
fetch(ad.clickUrl, { mode: "no-cors" }).catch(() => {})
|
|
149
|
+
}
|
|
150
|
+
if (ad.targetUrl) {
|
|
151
|
+
window.open(ad.targetUrl, "_blank", "noopener,noreferrer")
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (status === "collapsed" || status === "error") {
|
|
156
|
+
return null
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (status === "loading") {
|
|
160
|
+
return (
|
|
161
|
+
<div
|
|
162
|
+
ref={containerRef}
|
|
163
|
+
className={cn("w-full aspect-video bg-muted animate-pulse rounded-lg", className)}
|
|
164
|
+
/>
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return (
|
|
169
|
+
<div
|
|
170
|
+
ref={containerRef}
|
|
171
|
+
className={cn(
|
|
172
|
+
"relative w-full overflow-hidden rounded-lg bg-black",
|
|
173
|
+
isCollapsing && "transition-all",
|
|
174
|
+
className
|
|
175
|
+
)}
|
|
176
|
+
style={{
|
|
177
|
+
height: containerHeight,
|
|
178
|
+
transitionDuration: `${collapseDuration}ms`,
|
|
179
|
+
}}
|
|
180
|
+
>
|
|
181
|
+
<div className="relative aspect-video">
|
|
182
|
+
{/* Video */}
|
|
183
|
+
<video
|
|
184
|
+
ref={videoRef}
|
|
185
|
+
src={ad?.videoUrl}
|
|
186
|
+
muted={isMuted}
|
|
187
|
+
playsInline
|
|
188
|
+
loop={false}
|
|
189
|
+
onClick={handleClick}
|
|
190
|
+
onEnded={handleEnded}
|
|
191
|
+
className="w-full h-full object-contain cursor-pointer"
|
|
192
|
+
/>
|
|
193
|
+
|
|
194
|
+
{/* Overlay controls */}
|
|
195
|
+
<div className="absolute inset-0 pointer-events-none">
|
|
196
|
+
{/* Top bar */}
|
|
197
|
+
<div className="absolute top-0 left-0 right-0 p-3 flex items-center justify-between bg-gradient-to-b from-black/50 to-transparent pointer-events-auto">
|
|
198
|
+
<WakaSponsoredBadge variant="dark" size="sm" sponsor={ad?.sponsor} />
|
|
199
|
+
|
|
200
|
+
<div className="flex items-center gap-2">
|
|
201
|
+
<button
|
|
202
|
+
onClick={handleToggleMute}
|
|
203
|
+
className="p-1.5 rounded-full bg-black/50 hover:bg-black/70 transition-colors"
|
|
204
|
+
>
|
|
205
|
+
{isMuted ? (
|
|
206
|
+
<VolumeX className="h-4 w-4 text-white" />
|
|
207
|
+
) : (
|
|
208
|
+
<Volume2 className="h-4 w-4 text-white" />
|
|
209
|
+
)}
|
|
210
|
+
</button>
|
|
211
|
+
|
|
212
|
+
{showClose && (
|
|
213
|
+
<button
|
|
214
|
+
onClick={handleCollapse}
|
|
215
|
+
className="p-1.5 rounded-full bg-black/50 hover:bg-black/70 transition-colors"
|
|
216
|
+
>
|
|
217
|
+
<X className="h-4 w-4 text-white" />
|
|
218
|
+
</button>
|
|
219
|
+
)}
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
|
|
223
|
+
{/* CTA button */}
|
|
224
|
+
{ad?.cta && (
|
|
225
|
+
<div className="absolute bottom-3 left-3 right-3 pointer-events-auto">
|
|
226
|
+
<button
|
|
227
|
+
onClick={handleClick}
|
|
228
|
+
className="w-full px-4 py-2 bg-primary text-primary-foreground rounded-lg font-medium hover:bg-primary/90 transition-colors text-center"
|
|
229
|
+
>
|
|
230
|
+
{ad.cta}
|
|
231
|
+
</button>
|
|
232
|
+
</div>
|
|
233
|
+
)}
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
)
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export default WakaOutstreamVideo
|
|
@@ -59,7 +59,7 @@ const rarityConfig: Record<PlayerRarity, {
|
|
|
59
59
|
common: {
|
|
60
60
|
borderColor: "border-zinc-400 dark:border-zinc-500",
|
|
61
61
|
bgGradient: "from-zinc-100 to-zinc-200 dark:from-zinc-800 dark:to-zinc-900",
|
|
62
|
-
glowColor: "
|
|
62
|
+
glowColor: "hsl(var(--muted-foreground) / 0.3)",
|
|
63
63
|
textColor: "text-zinc-600 dark:text-zinc-400",
|
|
64
64
|
label: "Common",
|
|
65
65
|
frameGradient: "from-zinc-300 via-zinc-400 to-zinc-300 dark:from-zinc-600 dark:via-zinc-500 dark:to-zinc-600",
|
|
@@ -67,7 +67,7 @@ const rarityConfig: Record<PlayerRarity, {
|
|
|
67
67
|
rare: {
|
|
68
68
|
borderColor: "border-blue-400 dark:border-blue-500",
|
|
69
69
|
bgGradient: "from-blue-50 to-blue-100 dark:from-blue-950 dark:to-blue-900",
|
|
70
|
-
glowColor: "
|
|
70
|
+
glowColor: "hsl(var(--info) / 0.4)",
|
|
71
71
|
textColor: "text-blue-600 dark:text-blue-400",
|
|
72
72
|
label: "Rare",
|
|
73
73
|
frameGradient: "from-blue-300 via-blue-500 to-blue-300 dark:from-blue-600 dark:via-blue-400 dark:to-blue-600",
|
|
@@ -75,7 +75,7 @@ const rarityConfig: Record<PlayerRarity, {
|
|
|
75
75
|
epic: {
|
|
76
76
|
borderColor: "border-purple-400 dark:border-purple-500",
|
|
77
77
|
bgGradient: "from-purple-50 to-purple-100 dark:from-purple-950 dark:to-purple-900",
|
|
78
|
-
glowColor: "
|
|
78
|
+
glowColor: "hsl(var(--chart-2) / 0.5)",
|
|
79
79
|
textColor: "text-purple-600 dark:text-purple-400",
|
|
80
80
|
label: "Epic",
|
|
81
81
|
frameGradient: "from-purple-300 via-purple-500 to-purple-300 dark:from-purple-600 dark:via-purple-400 dark:to-purple-600",
|
|
@@ -83,7 +83,7 @@ const rarityConfig: Record<PlayerRarity, {
|
|
|
83
83
|
legendary: {
|
|
84
84
|
borderColor: "border-amber-400 dark:border-amber-500",
|
|
85
85
|
bgGradient: "from-amber-50 to-orange-100 dark:from-amber-950 dark:to-orange-900",
|
|
86
|
-
glowColor: "
|
|
86
|
+
glowColor: "hsl(var(--warning) / 0.5)",
|
|
87
87
|
textColor: "text-amber-600 dark:text-amber-400",
|
|
88
88
|
label: "Legendary",
|
|
89
89
|
frameGradient: "from-yellow-300 via-amber-500 to-orange-400 dark:from-yellow-500 dark:via-amber-400 dark:to-orange-500",
|
|
@@ -91,7 +91,7 @@ const rarityConfig: Record<PlayerRarity, {
|
|
|
91
91
|
mythic: {
|
|
92
92
|
borderColor: "border-rose-400 dark:border-rose-500",
|
|
93
93
|
bgGradient: "from-rose-50 via-pink-50 to-violet-50 dark:from-rose-950 dark:via-pink-950 dark:to-violet-950",
|
|
94
|
-
glowColor: "
|
|
94
|
+
glowColor: "hsl(var(--destructive) / 0.6)",
|
|
95
95
|
textColor: "text-rose-600 dark:text-rose-400",
|
|
96
96
|
label: "Mythic",
|
|
97
97
|
frameGradient: "from-rose-400 via-pink-500 to-violet-500 dark:from-rose-500 dark:via-pink-400 dark:to-violet-400",
|