/ src / components / jet / item / AppEventItem.svelte
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>