|
13 | 13 | import { canInstallMods, favoriteMods, lockfileMods, manifestMods, progress, selectedInstallMetadata } from '$lib/store/ficsitCLIStore';
|
14 | 14 | import { error, siteURL } from '$lib/store/generalStore';
|
15 | 15 | import { type PartialMod, search } from '$lib/store/modFiltersStore';
|
| 16 | + import { largeNumberFormat } from '$lib/utils/dataFormats'; |
16 | 17 | import { getAuthor } from '$lib/utils/getModAuthor';
|
17 | 18 | import { type CompatibilityWithSource, getCompatibility, getVersionCompatibility } from '$lib/utils/modCompatibility';
|
18 | 19 | import type { ButtonDisplay } from '$lib/utils/responsiveButton';
|
|
261 | 262 | </script>
|
262 | 263 |
|
263 | 264 | <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" |
265 | 266 | class:bg-surface-50-900-token={selected}
|
266 | 267 | class:rounded-lg={selected}
|
267 | 268 | role="tab"
|
|
278 | 279 | value={$progress?.progress === -1 ? undefined : $progress?.progress}/>
|
279 | 280 | </div>
|
280 | 281 | {/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}> |
282 | 283 | <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]" |
284 | 285 | class:grayscale={isInstalled && !isEnabled}
|
285 | 286 | alt="{mod.name} Logo"
|
286 | 287 | 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}> |
288 | 289 | <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> |
292 | 296 | <div class="shrink-0 hidden @lg/mods-list:block truncate w-[7rem] grow">
|
293 | 297 | <span class="pl-1">by</span>
|
294 | 298 | <!-- 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 | 304 | on:keypress|stopPropagation={authorClick}>{author}</span>
|
301 | 305 | </div>
|
302 | 306 | </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 |
| - <!-- 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} |
329 | 331 | </div>
|
330 |
| - {:else} |
331 |
| - <span>{$progress?.message}</span> |
332 |
| - {/if} |
| 332 | + </div> |
333 | 333 | </div>
|
| 334 | + {#if inProgress} |
| 335 | + <span class="shrink-0 text-sm">{$progress?.message}</span> |
| 336 | + {/if} |
334 | 337 | </div>
|
335 | 338 | <!-- 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" -->
|
336 | 339 | <!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
|
342 | 345 | on:keypress|stopPropagation={() => { /* empty */ }}>
|
343 | 346 | <ResponsiveButton
|
344 | 347 | 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" |
346 | 349 | buttonClass="w-full h-full"
|
347 | 350 | disabled={enableButtonDisabled}
|
348 | 351 | display={enableButtonDisplay}
|
|
351 | 354 | />
|
352 | 355 | <ResponsiveButton
|
353 | 356 | 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" |
355 | 358 | buttonClass="w-full h-full"
|
356 | 359 | disabled={installButtonDisabled}
|
357 | 360 | display={installButtonDisplay}
|
358 | 361 | onClickAction={toggleModInstalled}
|
359 | 362 | />
|
360 | 363 | <ResponsiveButton
|
361 | 364 | 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" |
363 | 366 | buttonClass="w-full h-full"
|
364 | 367 | display={favoriteButtonDisplay}
|
365 | 368 | onClickAction={toggleModFavorite}
|
|
0 commit comments