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 };