/ shared / components / src / utils / shelfAspectRatio.ts
shelfAspectRatio.ts
 1  import { getAspectRatio } from '@amp/web-app-components/src/components/Artwork/utils/artProfile';
 2  import { setContext, getContext, hasContext } from 'svelte';
 3  import { derived, writable } from 'svelte/store';
 4  import type { Readable } from 'svelte/store';
 5  import type { Profile } from '@amp/web-app-components/src/components/Artwork/types';
 6  import type { AspectRatioOverrideConfig } from '@amp/web-app-components/src/components/Shelf/types';
 7  
 8  const SHELF_ASPECT_RATIO_KEY = 'shelf-aspect-ratio';
 9  
10  export const getShelfAspectRatioContext = (): {
11      shelfAspectRatio: Readable<string>;
12      addProfile: (profile: string | Profile) => void;
13  } => {
14      return getContext(SHELF_ASPECT_RATIO_KEY);
15  };
16  
17  export const hasShelfAspectRatioContext = () =>
18      hasContext(SHELF_ASPECT_RATIO_KEY);
19  
20  const createShelfAspectRatioStore = (config: AspectRatioOverrideConfig) => {
21      const { subscribe, update } = writable(new Map() as Map<string, number>);
22  
23      const addProfile = (profile: string) => {
24          const ratio = getAspectRatio(profile).toFixed(2);
25  
26          update((ratiosCount) => {
27              const currentCount = ratiosCount.get(ratio);
28              const newCount = ratiosCount.has(ratio) ? currentCount + 1 : 0;
29              ratiosCount.set(ratio, newCount);
30              return ratiosCount;
31          });
32      };
33  
34      const aspectRatioStore = {
35          subscribe,
36          addProfile,
37      };
38  
39      const shelfAspectRatio = derived(aspectRatioStore, ($store) => {
40          let aspectRatio: string = null;
41  
42          // Don't set shelf aspect ratio when only 1 ratio is found
43          //
44          // This allows e.g. a shelf with only tall artwork Powerswooshes to use
45          // their native 3:4 aspect ratio, even when the shelf is set to use the
46          // fixed 1:1 aspect ratio or a dominant aspect ratio.
47          if ($store.size > 1) {
48              if (config.type === 'fixed') {
49                  aspectRatio = config.aspectRatio;
50              } else if (config.type === 'dominant') {
51                  let highestCount = 0;
52                  for (const [ratio, count] of $store.entries()) {
53                      if (highestCount < count) {
54                          aspectRatio = ratio;
55                          highestCount = count;
56                      }
57                  }
58              }
59          }
60  
61          return aspectRatio;
62      });
63  
64      return {
65          shelfAspectRatio,
66          addProfile,
67      };
68  };
69  
70  export const createShelfAspectRatioContext = (
71      config: AspectRatioOverrideConfig,
72  ) => {
73      setContext(SHELF_ASPECT_RATIO_KEY, createShelfAspectRatioStore(config));
74      return getShelfAspectRatioContext();
75  };