Skip to content

Commit 1b0465b

Browse files
committed
Improve responsivity of mod list items when displaying progress
1 parent 723e9a6 commit 1b0465b

File tree

2 files changed

+47
-39
lines changed

2 files changed

+47
-39
lines changed

frontend/src/lib/components/mods-list/ModsListItem.svelte

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import { canInstallMods, favoriteMods, lockfileMods, manifestMods, progress, selectedInstallMetadata } from '$lib/store/ficsitCLIStore';
1414
import { error, siteURL } from '$lib/store/generalStore';
1515
import { type PartialMod, search } from '$lib/store/modFiltersStore';
16+
import { largeNumberFormat } from '$lib/utils/dataFormats';
1617
import { getAuthor } from '$lib/utils/getModAuthor';
1718
import { type CompatibilityWithSource, getCompatibility, getVersionCompatibility } from '$lib/utils/modCompatibility';
1819
import type { ButtonDisplay } from '$lib/utils/responsiveButton';
@@ -261,7 +262,7 @@
261262
</script>
262263

263264
<div
264-
class="my-1 px-0 @xl/mods-list:h-24 @md/mods-list:h-[5.5rem] h-[4.25rem]"
265+
class="my-1 px-0 @md/mods-list:h-[5.5rem] h-[4.25rem] overflow-hidden"
265266
class:bg-surface-50-900-token={selected}
266267
class:rounded-lg={selected}
267268
role="tab"
@@ -278,17 +279,20 @@
278279
value={$progress?.progress === -1 ? undefined : $progress?.progress}/>
279280
</div>
280281
{/if}
281-
<div class="flex relative h-full" class:-top-full={inProgress}>
282+
<div class="flex relative h-full space-x-2" class:-top-full={inProgress}>
282283
<img
283-
class="logo h-full @xl/mods-list:w-24 @md/mods-list:w-[5.5rem] w-[4.25rem]"
284+
class="logo h-full @md/mods-list:w-[5.5rem] w-[4.25rem]"
284285
class:grayscale={isInstalled && !isEnabled}
285286
alt="{mod.name} Logo"
286287
src={renderedLogo} />
287-
<div class="ml-2 flex flex-col grow w-0 opacity" class:opacity-30={isInstalled && !isEnabled}>
288+
<div class="flex flex-col h-full grow w-0" class:opacity-30={isInstalled && !isEnabled}>
288289
<div class="flex items-center" use:popup={popupHover}>
289-
<div class="shrink min-w-[7rem] truncate">
290-
<span class="@xl/mods-list:text-xl text-lg font-medium min-w-0 w-full" class:text-error-600={compatibility.state === CompatibilityState.Broken} class:text-warning-500={compatibility.state === CompatibilityState.Damaged}>{mod.name}</span>
291-
</div>
290+
<span
291+
class="shrink min-w-[7rem] truncate text-lg font-medium !leading-6"
292+
class:text-error-600={compatibility.state === CompatibilityState.Broken}
293+
class:text-warning-500={compatibility.state === CompatibilityState.Damaged}>
294+
{mod.name}
295+
</span>
292296
<div class="shrink-0 hidden @lg/mods-list:block truncate w-[7rem] grow">
293297
<span class="pl-1">by</span>
294298
<!-- We could offer keyboard navigation for clicking this, but it's a waste of the user's time while nagivating via keyboard. If they want to search by author, they could enter the mod description pane -->
@@ -300,37 +304,36 @@
300304
on:keypress|stopPropagation={authorClick}>{author}</span>
301305
</div>
302306
</div>
303-
<div class="truncate @md/mods-list:text-base text-sm hidden @md/mods-list:block">{'short_description' in mod ? mod.short_description : ''}</div>
304-
<div class="flex">
305-
{#if !inProgress}
306-
<div class="grow w-0 @xl/mods-list:text-base text-sm">
307-
<div class="truncate text-base @md/mods-list:text-sm block @md/mods-list:hidden">{'short_description' in mod ? mod.short_description : ''}</div>
308-
<div class="truncate h-5 @md/mods-list:h-4.5 hidden @md/mods-list:flex items-center space-x-1">
309-
{#if !('offline' in mod) && !('missing' in mod) && (mod?.tags?.length ?? -1 > 0 )}
310-
<SvgIcon class="pr-1 py-1 @xl/mods-list:w-7 w-6 shrink-0" icon={mdiTagMultiple}/>
311-
{#each mod?.tags ?? [] as tag}
312-
<span>#{tag.name}</span>
313-
{/each}
314-
{/if}
315-
&nbsp; <!-- keep div height even when no tags are available -->
316-
</div>
317-
<div class="flex h-5 @md/mods-list:h-4.5 space-x-2">
318-
{#if !('offline' in mod) && !('missing' in mod)}
319-
<div class="w-24 flex items-center space-x-0.5">
320-
<SvgIcon class="pr-1 py-1 @xl/mods-list:w-7 w-6" icon={mdiEye}/>
321-
<span>{mod.views.toLocaleString()}</span>
322-
</div>
323-
<div class="w-24 flex items-center space-x-0.5">
324-
<SvgIcon class="pr-1 py-1 @xl/mods-list:w-7 w-6" icon={mdiDownload}/>
325-
<span>{mod.downloads.toLocaleString()}</span>
326-
</div>
327-
{/if}
328-
</div>
307+
<div class="flex flex-col grow h-0 overflow-hidden justify-around flex-wrap">
308+
<div class="truncate w-full @md/mods-list:text-base text-sm">{'short_description' in mod ? mod.short_description : ''}</div>
309+
<div class="truncate w-full h-5 hidden @md/mods-list:flex items-center space-x-1">
310+
<SvgIcon class="w-5 shrink-0" icon={mdiTagMultiple}/>
311+
{#if !('offline' in mod) && !('missing' in mod) && (mod?.tags?.length ?? -1 > 0 )}
312+
{#each mod?.tags ?? [] as tag}
313+
<span>#{tag.name}</span>
314+
{/each}
315+
{:else}
316+
<span>(none available)</span>
317+
{/if}
318+
</div>
319+
<div class="text-sm w-full">
320+
<div class="flex h-5 space-x-2">
321+
{#if !('offline' in mod) && !('missing' in mod)}
322+
<div class="w-16 flex items-center space-x-1">
323+
<SvgIcon class="w-4 @md/mods-list:w-5" icon={mdiEye}/>
324+
<span>{largeNumberFormat(mod.views)}</span>
325+
</div>
326+
<div class="w-16 flex items-center space-x-1">
327+
<SvgIcon class="w-4 @md/mods-list:w-5" icon={mdiDownload}/>
328+
<span>{largeNumberFormat(mod.downloads)}</span>
329+
</div>
330+
{/if}
329331
</div>
330-
{:else}
331-
<span>{$progress?.message}</span>
332-
{/if}
332+
</div>
333333
</div>
334+
{#if inProgress}
335+
<span class="shrink-0 text-sm">{$progress?.message}</span>
336+
{/if}
334337
</div>
335338
<!-- The purpose of the event handlers here are to prevent navigating to the mod's page when clicking on one of the sub-buttons of the div. Thus, it shouldn't be focusable despite having "interactions" -->
336339
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
@@ -342,7 +345,7 @@
342345
on:keypress|stopPropagation={() => { /* empty */ }}>
343346
<ResponsiveButton
344347
id="enable-{mod.mod_reference}"
345-
class="w-8 h-8 @lg/mods-list:mx-1 @xl/mods-list:mx-2"
348+
class="w-8 h-8 @lg/mods-list:mx-1"
346349
buttonClass="w-full h-full"
347350
disabled={enableButtonDisabled}
348351
display={enableButtonDisplay}
@@ -351,15 +354,15 @@
351354
/>
352355
<ResponsiveButton
353356
id="install-{mod.mod_reference}"
354-
class="w-8 h-8 @lg/mods-list:mx-1 @xl/mods-list:mx-2"
357+
class="w-8 h-8 @lg/mods-list:mx-1"
355358
buttonClass="w-full h-full"
356359
disabled={installButtonDisabled}
357360
display={installButtonDisplay}
358361
onClickAction={toggleModInstalled}
359362
/>
360363
<ResponsiveButton
361364
id="favorite-{mod.mod_reference}"
362-
class="w-8 h-8 @lg/mods-list:mx-1 @xl/mods-list:mx-2"
365+
class="w-8 h-8 @lg/mods-list:mx-1"
363366
buttonClass="w-full h-full"
364367
display={favoriteButtonDisplay}
365368
onClickAction={toggleModFavorite}

frontend/src/lib/utils/dataFormats.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
export const largeNumberFormat = Intl.NumberFormat(undefined, { notation: 'compact' }).format;
2+
3+
// We cannot use the units mode of NumberFormat, since it is not aware of different names for larger units
4+
// For 1 TB, it uses 1 BB (1 billion bytes), and for 1000 seconds it uses 1Ks (1 thousand seconds)
5+
16
export function roundWithDecimals(number: number, decimals = 0): number {
27
return Math.round(number * (10 ** decimals)) / (10 ** decimals);
38
}

0 commit comments

Comments
 (0)