AppEventItem.svelte
1 <script lang="ts"> 2 import type { AppEvent } from '@jet-app/app-store/api/models'; 3 4 import LineClamp from '@amp/web-app-components/src/components/LineClamp/LineClamp.svelte'; 5 import Artwork from '~/components/Artwork.svelte'; 6 import GradientOverlay from '~/components/GradientOverlay.svelte'; 7 import HoverWrapper from '~/components/HoverWrapper.svelte'; 8 import LinkWrapper from '~/components/LinkWrapper.svelte'; 9 import Video from '~/components/jet/Video.svelte'; 10 import AppEventDate from '~/components/AppEventDate.svelte'; 11 import SmallLockupItem from './SmallLockupItem.svelte'; 12 13 export let item: AppEvent; 14 export let isArticleContext: boolean = false; 15 16 $: artwork = item.moduleArtwork; 17 $: video = item.moduleVideo; 18 $: hasLightArtwork = item.mediaOverlayStyle === 'light'; 19 $: gradientColor = hasLightArtwork 20 ? 'rgb(240 240 240 / 48%)' 21 : 'rgb(83 83 83 / 48%)'; 22 $: shouldShowLockup = !!item.lockup && !item.hideLockupWhenNotInstalled; 23 </script> 24 25 <div 26 class="app-event-item" 27 class:with-lockup={!!item.lockup && !item.hideLockupWhenNotInstalled} 28 > 29 <span class="time-indicator"> 30 <AppEventDate appEvent={item} /> 31 </span> 32 33 <div class="lockup-container"> 34 <HoverWrapper hasChin={shouldShowLockup} --display="block"> 35 <LinkWrapper action={item.clickAction}> 36 <div class="text-over-artwork"> 37 {#if video} 38 <div class="video-container"> 39 <Video 40 {video} 41 autoplay 42 loop={true} 43 useControls={false} 44 profile="app-promotion" 45 /> 46 </div> 47 {:else if artwork} 48 <div class="artwork-container"> 49 <Artwork 50 {artwork} 51 profile={isArticleContext 52 ? 'app-promotion-in-article' 53 : 'app-promotion'} 54 /> 55 </div> 56 {/if} 57 58 <div class="gradient-container"> 59 <GradientOverlay 60 --border-radius={0} 61 --color={gradientColor} 62 --height="80%" 63 shouldDarken={!hasLightArtwork} 64 /> 65 </div> 66 67 <div class="text-container" class:dark={hasLightArtwork}> 68 <h4>{item.kind}</h4> 69 70 <h3>{item.title}</h3> 71 72 <LineClamp clamp={1}> 73 <p>{item.detail}</p> 74 </LineClamp> 75 </div> 76 </div> 77 </LinkWrapper> 78 </HoverWrapper> 79 80 {#if item.lockup && shouldShowLockup} 81 <div class="small-lockup-container"> 82 <SmallLockupItem item={item.lockup} appIconProfile="app-icon" /> 83 </div> 84 {/if} 85 </div> 86 </div> 87 88 <style> 89 .app-event-item { 90 height: 100%; 91 display: grid; 92 grid-template-areas: 93 'time-indicator' 94 'lockup'; 95 grid-template-rows: 1rem 1fr; 96 gap: 4px; 97 } 98 99 .time-indicator { 100 grid-area: time-indicator; 101 color: var(--keyColor); 102 font-weight: bold; 103 } 104 105 .lockup-container { 106 grid-area: lockup; 107 } 108 109 .text-over-artwork { 110 /* Allow artwork, overlay and text containers to overlap by targeting the same grid area */ 111 display: grid; 112 grid-template-areas: 'content'; 113 } 114 115 .artwork-container { 116 grid-area: content; 117 border-radius: var(--global-border-radius-large); 118 } 119 120 .video-container { 121 grid-area: content; 122 border-radius: var(--global-border-radius-large); 123 line-height: 0; 124 } 125 126 .app-event-item.with-lockup .artwork-container, 127 .app-event-item.with-lockup .video-container { 128 border-radius: 0; 129 } 130 131 .gradient-container { 132 grid-area: content; 133 z-index: 1; 134 position: relative; 135 } 136 137 .text-container { 138 color: var(--systemPrimary-onDark); 139 padding: 12px 16px; 140 grid-area: content; 141 z-index: 2; 142 143 /* Float text to the bottom of the lockup */ 144 display: flex; 145 flex-direction: column; 146 justify-content: flex-end; 147 } 148 149 .text-container.dark { 150 color: var(--systemPrimary-onLight); 151 } 152 153 .small-lockup-container { 154 background: var(--systemPrimary-onDark); 155 border-radius: 0 0 var(--global-border-radius-large) 156 var(--global-border-radius-large); 157 box-shadow: var(--shadow-small); 158 padding: 12px; 159 160 @media (prefers-color-scheme: dark) { 161 background: var(--systemQuinary-onDark); 162 } 163 } 164 165 h3 { 166 font: var(--title-2-tall); 167 } 168 169 h4 { 170 font: var(--callout-emphasized-tall); 171 } 172 173 p { 174 font: var(--callout-emphasized); 175 } 176 </style>