Sync stage and rail ambient media

This commit is contained in:
DCCONSTRUCTIONS 2026-05-02 11:03:27 +03:00
parent 69eb5260b0
commit adad0bd344
3 changed files with 19 additions and 14 deletions

View File

@ -0,0 +1,11 @@
import type { LauncherServiceView, MediaKind } from "./types";
export const DEFAULT_AMBIENT_MEDIA = "/storage/default.gif";
export const DEFAULT_AMBIENT_MEDIA_KIND: MediaKind = "gif";
export function resolveAmbientMedia(service?: LauncherServiceView): { src: string; kind: MediaKind } {
return {
src: service?.media.ambientVideo ?? DEFAULT_AMBIENT_MEDIA,
kind: service?.media.ambientKind ?? DEFAULT_AMBIENT_MEDIA_KIND,
};
}

View File

@ -1,9 +1,8 @@
import { ChevronRight } from "lucide-react";
import { DEFAULT_AMBIENT_MEDIA, resolveAmbientMedia } from "../../entities/service/media";
import type { LauncherServiceView } from "../../entities/service/types";
import { cn } from "../../shared/lib/cn";
const DEFAULT_RAIL_MEDIA = "/storage/default.gif";
export function ServiceRail({
services,
selectedServiceId,
@ -13,13 +12,12 @@ export function ServiceRail({
selectedServiceId?: string;
onSelect: (serviceId: string) => void;
}) {
const selectedService = services.find((service) => service.id === selectedServiceId) ?? services[0];
const railMediaSrc = selectedService?.media.ambientVideo ?? selectedService?.media.coverImage ?? DEFAULT_RAIL_MEDIA;
const railMediaKind = selectedService?.media.ambientKind ?? selectedService?.media.coverKind;
const selectedService = services.find((service) => service.id === selectedServiceId);
const railMedia = resolveAmbientMedia(selectedService);
return (
<div className="service-rail" aria-label="Доступные сервисы">
<RailMedia className="service-rail__backdrop-media" src={railMediaSrc} kind={railMediaKind} />
<RailMedia className="service-rail__backdrop-media" src={railMedia.src} kind={railMedia.kind} />
<div className="service-rail__glass" />
<div className="service-rail__scroll">
<div className="service-rail__track">
@ -36,7 +34,7 @@ export function ServiceRail({
>
<RailMedia
className="service-tile__media-asset"
src={service.media.coverImage ?? service.media.ambientVideo ?? DEFAULT_RAIL_MEDIA}
src={service.media.coverImage ?? service.media.ambientVideo ?? DEFAULT_AMBIENT_MEDIA}
kind={service.media.coverKind ?? service.media.ambientKind}
/>
</span>

View File

@ -12,12 +12,11 @@ import {
Network,
Wrench,
} from "lucide-react";
import { resolveAmbientMedia } from "../../entities/service/media";
import type { LauncherServiceView } from "../../entities/service/types";
import { Button } from "../../shared/ui/Button";
import { ServiceStatusBadge, StatusBadge } from "../../shared/ui/StatusBadge";
const DEFAULT_STAGE_MEDIA = "/storage/default.gif";
export function ServiceStage({
service,
hasServices,
@ -46,6 +45,7 @@ export function ServiceStage({
const style = {
"--service-accent": service?.accentColor ?? "#C3FF66",
} as React.CSSProperties;
const ambientMedia = resolveAmbientMedia(service);
const disabledReason = service
? service.status === "maintenance"
? "Сервис временно недоступен"
@ -60,11 +60,7 @@ export function ServiceStage({
<section className="service-stage" style={style}>
<div className="stage-video-shell">
<div className="stage-video-stream" aria-hidden="true">
{service?.media.ambientVideo ? (
<StageMedia className="stage-video-gif" src={service.media.ambientVideo} kind={service.media.ambientKind} />
) : (
<img className="stage-video-gif" src={DEFAULT_STAGE_MEDIA} alt="" />
)}
<StageMedia className="stage-video-gif" src={ambientMedia.src} kind={ambientMedia.kind} />
</div>
<div className="stage-video-topline">