@@ -488,13 +488,14 @@ const App = {
488488 </div>
489489 </div>
490490 <!-- Categories Section -->
491- <div v-for="(score, category) in parsedMedia.categories ?? {}"
491+ <a v-for="(score, category) in parsedMedia.categories ?? {}"
492492 :key="'cat-' + category"
493+ :href="categoryHref(category)"
493494 class="group cursor-pointer relative inline-flex items-center rounded-full overflow-hidden px-3 py-1 text-xs font-medium ring-1 ring-inset hover:dark:bg-blue-900 hover:dark:ring-blue-500/80"
494- :class="score
495- ? 'text-blue-800 dark:text-blue-200 ring-blue-600/20 dark:ring-blue-400/30'
495+ :class="score
496+ ? 'text-blue-800 dark:text-blue-200 ring-blue-600/20 dark:ring-blue-400/30'
496497 : 'bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-200 ring-blue-600/20 dark:ring-blue-400/30'"
497- :title="'Score : ' + (score ? Math.round(score * 100) + '%' : 'No score ')">
498+ :title="'Search category : ' + category + (score ? ' · Score: ' + Math.round(score * 100) + '%' : '')">
498499 <!-- Background fill based on score -->
499500 <div v-if="score"
500501 class="group-hover:hidden absolute inset-0 bg-gradient-to-r from-blue-300 to-blue-400 dark:from-blue-700 dark:to-blue-800"
@@ -504,20 +505,21 @@ const App = {
504505 class="group-hover:hidden absolute inset-0 bg-blue-100 dark:bg-blue-900/30"></div>
505506 <!-- Text content -->
506507 <span class="relative z-10">{{ category }}</span>
507- </div >
508+ </a >
508509 </div>
509510 </div>
510511
511- <!-- Tags Section -->
512- <div v-if="Object.keys(parsedMedia.tags ?? {}) .length">
512+ <!-- Tags Section (ordered by strength) -->
513+ <div v-if="sortedTags .length">
513514 <div class="flex flex-wrap gap-2">
514- <div v-for="(score, tag) in parsedMedia.tags ?? {} "
515+ <a v-for="[tag, score] in sortedTags "
515516 :key="'tag-' + tag"
517+ :href="tagHref(tag)"
516518 class="group cursor-pointer relative inline-flex items-center rounded-full overflow-hidden px-3 py-1 text-xs font-medium ring-1 ring-inset hover:dark:bg-green-900 hover:dark:ring-green-600/80"
517- :class="score
518- ? 'text-emerald-800 dark:text-emerald-200 ring-emerald-600/20 dark:ring-emerald-400/30'
519+ :class="score
520+ ? 'text-emerald-800 dark:text-emerald-200 ring-emerald-600/20 dark:ring-emerald-400/30'
519521 : 'bg-emerald-100 dark:bg-emerald-900/30 text-emerald-800 dark:text-emerald-200 ring-emerald-600/20 dark:ring-emerald-400/30'"
520- :title="'Score : ' + (score ? Math.round(score * 100) + '%' : 'No score ')">
522+ :title="'Search tag : ' + tag + (score ? ' · Score: ' + Math.round(score * 100) + '%' : '')">
521523 <!-- Background fill based on score -->
522524 <div v-if="score"
523525 class="group-hover:hidden absolute inset-0 bg-gradient-to-r from-emerald-300 to-emerald-400 dark:from-emerald-700 dark:to-emerald-800"
@@ -527,7 +529,7 @@ const App = {
527529 class="group-hover:hidden absolute inset-0 bg-emerald-100 dark:bg-emerald-900/30"></div>
528530 <!-- Text content -->
529531 <span class="relative z-10">{{ tag }}</span>
530- </div >
532+ </a >
531533 </div>
532534 </div>
533535 </div>
@@ -671,6 +673,20 @@ const App = {
671673 return item
672674 } )
673675
676+ // Tags as [tag, score] entries ordered by strength (highest score first)
677+ const sortedTags = computed ( ( ) =>
678+ Object . entries ( parsedMedia . value ?. tags ?? { } )
679+ . sort ( ( a , b ) => ( b [ 1 ] || 0 ) - ( a [ 1 ] || 0 ) ) )
680+
681+ // Clicking a tag/category links to the gallery filtered by it (read by medias.mjs).
682+ // Audio media opens the Audio tab (#audio) so the filter lands on the matching grid.
683+ const galleryHref = ( kind , value ) => {
684+ const hash = ( parsedMedia . value ?. type || '' ) . toLowerCase ( ) === 'audio' ? '#audio' : ''
685+ return `/m?${ kind } =${ encodeURIComponent ( value ) } ${ hash } `
686+ }
687+ const tagHref = ( tag ) => galleryHref ( 'tag' , tag )
688+ const categoryHref = ( category ) => galleryHref ( 'category' , category )
689+
674690 const aspectRatio = computed ( ( ) => {
675691 const media = parsedMedia . value
676692 if ( ! media ) return null
@@ -1029,6 +1045,9 @@ const App = {
10291045 media,
10301046 error,
10311047 parsedMedia,
1048+ sortedTags,
1049+ tagHref,
1050+ categoryHref,
10321051 aspectRatio,
10331052 resolveUrl,
10341053 formatDate,
0 commit comments