From 38ed083693846d81ff6da89db05aadece05a47d2 Mon Sep 17 00:00:00 2001 From: Kendall Garner <17521368+kgarner7@users.noreply.github.com> Date: Sat, 25 May 2024 11:15:30 -0700 Subject: [PATCH] [enhancement]: support using native image aspect ratio --- src/i18n/locales/en.json | 2 ++ src/renderer/app.tsx | 6 +++++ src/renderer/components/card/poster-card.tsx | 2 +- .../components/feature-carousel/index.tsx | 2 +- .../virtual-grid/grid-card/default-card.tsx | 2 +- .../virtual-grid/grid-card/poster-card.tsx | 2 +- .../cells/combined-title-cell.tsx | 2 +- .../player/components/left-controls.tsx | 2 +- .../components/library-command-item.tsx | 2 +- .../components/general/control-settings.tsx | 22 +++++++++++++++++++ .../components/library-header.module.scss | 2 +- .../features/sidebar/components/sidebar.tsx | 2 +- src/renderer/store/settings.store.ts | 2 ++ 13 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index e855427b..55e92a07 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -531,6 +531,8 @@ "hotkey_volumeUp": "volume up", "hotkey_zoomIn": "zoom in", "hotkey_zoomOut": "zoom out", + "imageAspectRatio": "use native cover art aspect ratio", + "imageAspectRatio_description": "if enabled, cover art will be shown using their native aspect ratio. for art that is not 1:1, the remaining space will be empty", "language": "language", "language_description": "sets the language for the application ($t(common.restartRequired))", "lyricFetch": "fetch lyrics from the internet", diff --git a/src/renderer/app.tsx b/src/renderer/app.tsx index b0b71eb5..94ae27a0 100644 --- a/src/renderer/app.tsx +++ b/src/renderer/app.tsx @@ -40,6 +40,7 @@ export const App = () => { const theme = useTheme(); const accent = useSettingsStore((store) => store.general.accent); const language = useSettingsStore((store) => store.general.language); + const nativeImageAspect = useSettingsStore((store) => store.general.nativeAspectRatio); const { builtIn, custom, system, type } = useSettingsStore((state) => state.font); const { type: playbackType } = usePlaybackSettings(); const { bindings } = useHotkeySettings(); @@ -90,6 +91,11 @@ export const App = () => { root.style.setProperty('--primary-color', accent); }, [accent]); + useEffect(() => { + const root = document.documentElement; + root.style.setProperty('--image-fit', nativeImageAspect ? 'scale-down' : 'cover'); + }, [nativeImageAspect]); + const providerValue = useMemo(() => { return { handlePlayQueueAdd }; }, [handlePlayQueueAdd]); diff --git a/src/renderer/components/card/poster-card.tsx b/src/renderer/components/card/poster-card.tsx index feff941d..140b335f 100644 --- a/src/renderer/components/card/poster-card.tsx +++ b/src/renderer/components/card/poster-card.tsx @@ -92,7 +92,7 @@ const Image = styled(SimpleImg)` img { height: 100%; - object-fit: cover; + object-fit: var(--image-fit); } `; diff --git a/src/renderer/components/feature-carousel/index.tsx b/src/renderer/components/feature-carousel/index.tsx index 7e97c035..677a93c4 100644 --- a/src/renderer/components/feature-carousel/index.tsx +++ b/src/renderer/components/feature-carousel/index.tsx @@ -63,7 +63,7 @@ const BackgroundImage = styled.img` height: 150%; user-select: none; filter: blur(24px); - object-fit: cover; + object-fit: var(--image-fit); object-position: 0 30%; `; diff --git a/src/renderer/components/virtual-grid/grid-card/default-card.tsx b/src/renderer/components/virtual-grid/grid-card/default-card.tsx index 46578029..e309d799 100644 --- a/src/renderer/components/virtual-grid/grid-card/default-card.tsx +++ b/src/renderer/components/virtual-grid/grid-card/default-card.tsx @@ -122,7 +122,7 @@ const Image = styled(SimpleImg)` img { height: 100%; - object-fit: cover; + object-fit: var(--image-fit); } `; diff --git a/src/renderer/components/virtual-grid/grid-card/poster-card.tsx b/src/renderer/components/virtual-grid/grid-card/poster-card.tsx index d227b6c2..7749506d 100644 --- a/src/renderer/components/virtual-grid/grid-card/poster-card.tsx +++ b/src/renderer/components/virtual-grid/grid-card/poster-card.tsx @@ -110,7 +110,7 @@ const Image = styled(SimpleImg)` img { height: 100%; - object-fit: cover; + object-fit: var(--image-fit); } `; diff --git a/src/renderer/components/virtual-table/cells/combined-title-cell.tsx b/src/renderer/components/virtual-table/cells/combined-title-cell.tsx index cd7d74a1..6d94afa3 100644 --- a/src/renderer/components/virtual-table/cells/combined-title-cell.tsx +++ b/src/renderer/components/virtual-table/cells/combined-title-cell.tsx @@ -44,7 +44,7 @@ const MetadataWrapper = styled.div` const StyledImage = styled(SimpleImg)` img { - object-fit: cover; + object-fit: var(--image-fit); } `; diff --git a/src/renderer/features/player/components/left-controls.tsx b/src/renderer/features/player/components/left-controls.tsx index 70076b28..52f63f05 100644 --- a/src/renderer/features/player/components/left-controls.tsx +++ b/src/renderer/features/player/components/left-controls.tsx @@ -62,7 +62,7 @@ const Image = styled(motion.div)` const PlayerbarImage = styled.img` width: 100%; height: 100%; - object-fit: cover; + object-fit: var(--image-fit); `; const LineItem = styled.div<{ $secondary?: boolean }>` diff --git a/src/renderer/features/search/components/library-command-item.tsx b/src/renderer/features/search/components/library-command-item.tsx index 54716fe7..380cc09b 100644 --- a/src/renderer/features/search/components/library-command-item.tsx +++ b/src/renderer/features/search/components/library-command-item.tsx @@ -46,7 +46,7 @@ const MetadataWrapper = styled.div` `; const StyledImage = styled.img` - object-fit: cover; + object-fit: var(--image-fit); border-radius: 4px; `; diff --git a/src/renderer/features/settings/components/general/control-settings.tsx b/src/renderer/features/settings/components/general/control-settings.tsx index 5c7aeac2..be3bb9d0 100644 --- a/src/renderer/features/settings/components/general/control-settings.tsx +++ b/src/renderer/features/settings/components/general/control-settings.tsx @@ -90,6 +90,28 @@ export const ControlSettings = () => { isHidden: false, title: t('setting.playerAlbumArtResolution', { postProcess: 'sentenceCase' }), }, + { + control: ( + + setSettings({ + general: { + ...settings, + nativeAspectRatio: e.currentTarget.checked, + }, + }) + } + /> + ), + description: t('setting.imageAspectRatio', { + context: 'description', + postProcess: 'sentenceCase', + }), + isHidden: false, + title: t('setting.imageAspectRatio', { postProcess: 'sentenceCase' }), + }, { control: ( ` const SidebarImage = styled.img` width: 100%; height: 100%; - object-fit: cover; + object-fit: var(--image-fit); background: var(--placeholder-bg); `; diff --git a/src/renderer/store/settings.store.ts b/src/renderer/store/settings.store.ts index 529450e3..7bf88419 100644 --- a/src/renderer/store/settings.store.ts +++ b/src/renderer/store/settings.store.ts @@ -201,6 +201,7 @@ export interface SettingsState { homeFeature: boolean; homeItems: SortableItem[]; language: string; + nativeAspectRatio: boolean; passwordStore?: string; playButtonBehavior: Play; resume: boolean; @@ -323,6 +324,7 @@ const initialState: SettingsState = { homeFeature: true, homeItems, language: 'en', + nativeAspectRatio: false, passwordStore: undefined, playButtonBehavior: Play.NOW, resume: false,