Skip to content

Commit 54718d5

Browse files
Small redesign & improvements (#494)
* Subtle improvements * Update font * increase size of image carousel * improved sidebar styling * ensure popovers stay visible * Fix loading issues for image comparisons * linting
1 parent d1da880 commit 54718d5

10 files changed

Lines changed: 172 additions & 47 deletions

File tree

src/elements/components/carousel/comparison.tsx

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const ImageComparison = ({ image }: ImageComparisonProps) => {
1919
scale: 1,
2020
});
2121
const prevTransformStateRef = useRef(transformState);
22+
const imagesLoadedRef = useRef({ lr: false, sr: false });
2223

2324
useEffect(() => {
2425
const prevTransformState = prevTransformStateRef.current;
@@ -38,11 +39,66 @@ export const ImageComparison = ({ image }: ImageComparisonProps) => {
3839
}, [transformState]);
3940

4041
useEffect(() => {
41-
lrRef.current?.centerView(1, 0);
42-
srRef.current?.centerView(1, 0);
42+
// Reset transform state when image changes
43+
setTransformState({
44+
positionX: 0,
45+
positionY: 0,
46+
scale: 1,
47+
});
48+
// Reset image load tracking
49+
imagesLoadedRef.current = { lr: false, sr: false };
4350
setHandlePosition(50);
4451
}, [image]);
4552

53+
// Track image loading and center images once loaded
54+
useEffect(() => {
55+
// Center images function
56+
const centerImages = () => {
57+
if (lrRef.current && srRef.current) {
58+
// Use requestAnimationFrame to ensure DOM is updated
59+
requestAnimationFrame(() => {
60+
lrRef.current?.centerView(1, 0);
61+
srRef.current?.centerView(1, 0);
62+
});
63+
}
64+
};
65+
66+
const lrImg = new Image();
67+
const srImg = new Image();
68+
let loadedCount = 0;
69+
70+
const checkAndCenter = () => {
71+
loadedCount++;
72+
if (loadedCount === 2) {
73+
// Both images loaded, center them
74+
setTimeout(() => {
75+
centerImages();
76+
}, 50); // Small delay to ensure DOM is ready
77+
}
78+
};
79+
80+
lrImg.onload = () => {
81+
imagesLoadedRef.current.lr = true;
82+
checkAndCenter();
83+
};
84+
srImg.onload = () => {
85+
imagesLoadedRef.current.sr = true;
86+
checkAndCenter();
87+
};
88+
89+
lrImg.src = image.LR;
90+
srImg.src = image.SR;
91+
92+
// Fallback: center after a timeout even if images don't load
93+
const fallbackTimer = setTimeout(() => {
94+
centerImages();
95+
}, 500);
96+
97+
return () => {
98+
clearTimeout(fallbackTimer);
99+
};
100+
}, [image]);
101+
46102
return (
47103
<ReactCompareSlider
48104
onlyHandleDraggable
@@ -137,6 +193,7 @@ export const ImageComparison = ({ image }: ImageComparisonProps) => {
137193
</TransformComponent>
138194
</TransformWrapper>
139195
}
196+
key={`${image.LR}-${image.SR}`}
140197
position={handlePosition}
141198
onPositionChange={setHandlePosition}
142199
/>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
.imageWrapper {
2+
height: 350px;
3+
4+
@media screen and (min-width: 768px) {
5+
height: 450px;
6+
}
7+
8+
@media screen and (min-width: 1024px) {
9+
height: 500px;
10+
}
11+
212
@media screen and (max-width: 1023px) {
313
border-radius: 0;
414
margin: -1rem 0 0 -1rem;
515
width: calc(100% + 2rem);
16+
height: 300px;
617
}
718
}

src/elements/components/image-carousel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export const ImageCarousel = ({ images, readonly, indexKey, onChange }: ImageCar
4747
return (
4848
<div className="relative w-full">
4949
<div
50-
className={`${style.imageWrapper} flex h-96 w-full overflow-hidden rounded-lg bg-fade-100 align-middle dark:bg-fade-800`}
50+
className={`${style.imageWrapper} flex w-full overflow-hidden rounded-lg bg-fade-100 align-middle dark:bg-fade-800`}
5151
>
5252
{selectedImage ? (
5353
<ImageCarouselImage image={selectedImage} />

src/elements/components/model-card.module.scss

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,28 @@
99
border-radius: 0.5rem;
1010
border-width: 1px;
1111
border-style: solid;
12+
transition: transform 0.3s ease, box-shadow 0.3s ease;
13+
z-index: 1;
1214

1315
--inner-radius: calc(0.5rem - 1px);
1416

17+
&:hover {
18+
transform: scale(1.02);
19+
z-index: 10;
20+
}
21+
1522
&.overflowHidden {
1623
--inner-radius: 0;
1724

1825
overflow: hidden;
1926
}
2027

28+
// Ensure popovers can escape the card's bounds when open
29+
&:has([data-headlessui-state='open']) {
30+
overflow: visible;
31+
z-index: 100;
32+
}
33+
2134
.inner {
2235
position: relative;
2336
display: flex;
@@ -60,6 +73,9 @@
6073
.details {
6174
padding: 0.75rem;
6275
padding-top: 0;
76+
overflow: visible;
77+
position: relative;
78+
z-index: 10;
6379

6480
&.paired {
6581
position: absolute;
@@ -68,7 +84,7 @@
6884
right: 0;
6985
backdrop-filter: blur(2rem) saturate(2);
7086
border-radius: 0 0 var(--inner-radius) var(--inner-radius);
71-
overflow: hidden;
87+
overflow: visible;
7288

7389
@include themed using($t) {
7490
background: linear-gradient(transparent, t($t, white, $fade-900))

src/elements/components/model-card.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ const useMakeLazyCard = (lazy: boolean, card: JSX.Element) => {
257257
className={joinClasses(
258258
style.modelCard,
259259
!editMode && style.overflowHidden,
260-
'border-gray-300 bg-white shadow-lg hover:shadow-xl dark:border-gray-700 dark:bg-fade-900'
260+
'border-gray-300 bg-white shadow-lg hover:shadow-2xl dark:border-gray-700 dark:bg-fade-900'
261261
)}
262262
>
263263
{card}
@@ -270,7 +270,7 @@ const useMakeLazyCard = (lazy: boolean, card: JSX.Element) => {
270270
<LazyLoadComponent
271271
placeholder={
272272
<div
273-
className={`${style.modelCard} border-gray-300 bg-white shadow-lg hover:shadow-xl dark:border-gray-700 dark:bg-fade-900`}
273+
className={`${style.modelCard} border-gray-300 bg-white shadow-lg hover:shadow-2xl dark:border-gray-700 dark:bg-fade-900`}
274274
/>
275275
}
276276
>

src/pages/_app.tsx

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,33 @@
1+
import { Inter } from 'next/font/google';
2+
import { useEffect } from 'react';
13
import '../styles/globals.scss';
24
import 'react-tooltip/dist/react-tooltip.css';
35
import { DevicePixelRatioProvider } from '../lib/hooks/use-device-pixel-ratio';
46
import { TooltipProvider } from '../lib/hooks/use-tooltip';
57
import { WebApiProvider } from '../lib/hooks/use-web-api';
68
import type { AppProps } from 'next/app';
79

10+
const inter = Inter({
11+
subsets: ['latin'],
12+
variable: '--font-inter',
13+
display: 'swap',
14+
});
15+
816
export default function App({ Component, pageProps }: AppProps) {
17+
useEffect(() => {
18+
// Ensure the font variable is available on the root element
19+
document.documentElement.style.setProperty('--font-inter', inter.style.fontFamily);
20+
}, []);
21+
922
return (
10-
<WebApiProvider>
11-
<DevicePixelRatioProvider>
12-
<TooltipProvider>
13-
<Component {...pageProps} />
14-
</TooltipProvider>
15-
</DevicePixelRatioProvider>
16-
</WebApiProvider>
23+
<div className={inter.variable}>
24+
<WebApiProvider>
25+
<DevicePixelRatioProvider>
26+
<TooltipProvider>
27+
<Component {...pageProps} />
28+
</TooltipProvider>
29+
</DevicePixelRatioProvider>
30+
</WebApiProvider>
31+
</div>
1732
);
1833
}

src/pages/index.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,12 @@ export default function Page({ modelData: staticModelData }: Props) {
133133
</p>
134134
</div>
135135

136-
<h1 className="mb-4 text-center text-2xl font-bold capitalize text-accent-500 dark:text-fade-200 md:mb-6 lg:text-3xl">
137-
The best place to find AI Upscaling models
136+
<h1 className="mb-4 text-center text-4xl font-extrabold md:mb-6 md:text-5xl lg:text-6xl">
137+
<span className="text-gray-800 dark:text-gray-100">The best place to find </span>
138+
<span className="bg-gradient-to-r from-accent-400 via-accent-500 to-accent-600 bg-clip-text text-transparent">
139+
AI Upscaling
140+
</span>
141+
<span className="text-gray-800 dark:text-gray-100"> models</span>
138142
</h1>
139143

140144
<p className="mx-auto max-w-screen-md text-center text-gray-600 dark:text-gray-400 md:text-lg">

src/pages/models/[id].tsx

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -334,26 +334,33 @@ function isTrue<T>(value: T | null | undefined | false | '' | 0): value is T {
334334
}
335335

336336
function MetadataTable({ rows }: { rows: (false | null | undefined | readonly [string, ReactNode])[] }) {
337+
const filteredRows = rows.filter(isTrue);
337338
return (
338-
<table className="w-full border-collapse text-left text-sm text-gray-700 dark:text-gray-400 ">
339-
<tbody>
340-
{rows.filter(isTrue).map((row, i) => {
341-
const [label, value] = row;
342-
const extraPadding = i === 0 ? 'pt-3' : i === rows.length - 1 ? 'pb-3' : '';
343-
return (
344-
<tr key={i}>
345-
<th
346-
className={`${extraPadding} whitespace-nowrap bg-fade-100 px-4 py-2 text-right align-top font-medium text-fade-900 dark:bg-fade-800 dark:text-white`}
347-
scope="row"
339+
<div className="overflow-hidden rounded-lg border border-fade-200 bg-white dark:border-fade-700 dark:bg-fade-900">
340+
<table className="w-full border-collapse text-left text-sm text-gray-700 dark:text-gray-400">
341+
<tbody>
342+
{filteredRows.map((row, i) => {
343+
const [label, value] = row;
344+
const extraPadding = i === 0 ? 'pt-3' : i === filteredRows.length - 1 ? 'pb-3' : '';
345+
const isLastRow = i === filteredRows.length - 1;
346+
return (
347+
<tr
348+
className={!isLastRow ? 'border-b border-fade-200 dark:border-fade-700' : ''}
349+
key={i}
348350
>
349-
{label}
350-
</th>
351-
<td className={`${extraPadding} px-4 py-2`}>{value}</td>
352-
</tr>
353-
);
354-
})}
355-
</tbody>
356-
</table>
351+
<th
352+
className={`${extraPadding} whitespace-nowrap bg-fade-100 px-4 py-2 text-right align-top font-medium text-fade-900 dark:bg-fade-800 dark:text-white`}
353+
scope="row"
354+
>
355+
{label}
356+
</th>
357+
<td className={`${extraPadding} px-4 py-2`}>{value}</td>
358+
</tr>
359+
);
360+
})}
361+
</tbody>
362+
</table>
363+
</div>
357364
);
358365
}
359366
export default function Page({
@@ -437,16 +444,20 @@ export default function Page({
437444
</Head>
438445
)}
439446
<PageContainer searchBar>
440-
{/* Two columns */}
441-
<div className="grid h-full w-full gap-4 pb-4 sm:grid-cols-1 md:grid-cols-1 lg:grid-cols-3">
442-
{/* Left column */}
447+
{/* Full-width preview at top (YouTube-style) */}
448+
<div className="mb-6 w-full">
449+
<ImageCarousel
450+
images={model.images}
451+
indexKey={modelId}
452+
readonly={!editMode}
453+
onChange={(images) => updateModelProperty('images', images)}
454+
/>
455+
</div>
456+
457+
{/* Two columns: Description and Sidebar */}
458+
<div className="grid h-full w-full gap-6 pb-4 sm:grid-cols-1 lg:grid-cols-3">
459+
{/* Left column: Description */}
443460
<div className="relative flex h-full flex-col gap-4 sm:col-span-1 lg:col-span-2">
444-
<ImageCarousel
445-
images={model.images}
446-
indexKey={modelId}
447-
readonly={!editMode}
448-
onChange={(images) => updateModelProperty('images', images)}
449-
/>
450461
<div className="relative">
451462
<div>
452463
{editMode && (
@@ -564,7 +575,7 @@ export default function Page({
564575
</div>
565576
</div>
566577
</div>
567-
{/* Right column */}
578+
{/* Right column: Sidebar */}
568579
<div className="col-span-1 w-full">
569580
{/* Download Button */}
570581
<div className="mb-2 flex w-full flex-col gap-2">

src/styles/globals.scss

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@
5050
:root {
5151
--max-page-width: 1400px;
5252

53-
--fonts-heading: -apple-system, blinkmacsystemfont, 'Segoe UI', helvetica, arial, sans-serif, 'Apple Color Emoji',
54-
'Segoe UI Emoji', 'Segoe UI Symbol';
55-
--fonts-body: -apple-system, blinkmacsystemfont, 'Segoe UI', helvetica, arial, sans-serif, 'Apple Color Emoji',
56-
'Segoe UI Emoji', 'Segoe UI Symbol';
53+
--fonts-heading: var(--font-inter), -apple-system, blinkmacsystemfont, 'Segoe UI', helvetica, arial, sans-serif,
54+
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
55+
--fonts-body: var(--font-inter), -apple-system, blinkmacsystemfont, 'Segoe UI', helvetica, arial, sans-serif,
56+
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
5757
--fonts-mono: sfmono-regular, menlo, monaco, consolas, 'Liberation Mono', 'Courier New', monospace;
5858

5959
overflow-y: scroll;

tailwind.config.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@ module.exports = {
33
content: ['./src/**/*.{js,ts,jsx,tsx}'],
44
theme: {
55
extend: {
6+
fontFamily: {
7+
sans: [
8+
'var(--font-inter)',
9+
'-apple-system',
10+
'BlinkMacSystemFont',
11+
'Segoe UI',
12+
'Helvetica',
13+
'Arial',
14+
'sans-serif',
15+
],
16+
},
617
colors: {
718
'fade-50': '#f9f8ff',
819
'fade-100': '#f3f2fd',

0 commit comments

Comments
 (0)