2025-01-09 15:24:56 +01:00
<!DOCTYPE html> < html lang = "en" > < head > < meta charset = "UTF-8" > < title > MARL - Mastodon Archive Reader Lite< / title > < meta name = "viewport" content = "width=device-width, initial-scale=1.0" > < link rel = "icon" href = "data:," > < base target = "_blank" > < link rel = "stylesheet" href = "./_astro/index.uwcihdcd.css" > < / head > < body > < noscript > < div class = "nojs" > JavaScript is required for this app to run.< / div > < / noscript > < div class = "main-page" id = "app" x-data :class = "$store.ui.appClasses" x-init = "$watch('$store.files.appReady', value => checkAppReady(value))" > < template x-if = "!$store.files.appReady && !$store.files.someFilesLoaded && !$store.files.loading" > < main class = "welcome" > < div class = "intro" > < h1 x-html = "$t('welcome.title', {appName: `MARL <span class='accronym'>(Mastodon Archive Reader Lite)</span>`})" > < / h1 > < p x-html = "$t('welcome.p1')" > < / p > < p x-html = "$t('welcome.p2')" > < / p > < p x-html = "$t('welcome.p3', {labelStart: `<label for='file-loader' tabindex='0'>`, labelEnd: `</label>`})" > < / p > < input id = "file-loader" class = "file-loader" type = "file" accept = ".zip" multiple @ change = "unZip(Object.values($event.target.files))" > < / div > < div class = "about" > < a href = "https://github.com/s427/MARL" > < span x-text = "$t('welcome.projectPage')" > < / span > < / a > < / div > < / main > < / template > < template x-if = "(!$store.files.appReady && $store.files.someFilesLoaded) || $store.files.loading" > < main class = "welcome loading-more" > < div class = "intro" > < div class = "file-loader loading" > < div > ... < span x-text = "$t('misc.loading')" > < / span > ...< / div > < div class = "filename" x-text = "$store.files.loadingName" > < / div > < / div > < / div > < / main > < / template > < template x-if = "$store.files.appReady" > < main class = "main-section" id = "main-section" tabindex = "-1" x-on:resize . window = "$store.ui.checkMenuState()" > < div class = "main-section-inner" id = "main-section-inner" :class = "$store.files.sources.length > 1 ? 'multiple-actors' : ''" > < div class = "mobile-menu" id = "mobile-menu" > < nav > < ul > < li > < button class = "menu-actor" @ click = "$store.ui.menuToggle('actor')" > < svg aria-hidden = "true" > < use href = "#menu-actor" > < / use > < / svg > < span x-text = "$t('menu.profile')" > < / span > < / button > < / li > < li > < button class = "menu-filters" :class = "$store.files.filtersActive ? 'filters-active' : ''" @ click = "$store.ui.menuToggle('filters')" > < svg aria-hidden = "true" > < use href = "#menu-filters" > < / use > < / svg > < span x-text = "$t('menu.filters')" > < / span > < em x-text = "$t('menu.filtersActive')" x-show = "$store.files.filtersActive" class = "visually-hidden" > < / em > < / button > < / li > < li > < button class = "menu-tags" @ click = "$store.ui.menuToggle('tags')" > < svg aria-hidden = "true" > < use href = "#menu-tags" > < / use > < / svg > < span x-text = "$t('menu.tags')" > < / span > < / button > < / li > < li > < button class = "menu-new" @ click = "startOver" > < svg aria-hidden = "true" > < use href = "#menu-new" > < / use > < / svg > < span x-text = "$t('menu.newFile')" > < / span > < / button > < / li > < / ul > < / nav > < / div > < div class = "panel-backdrop" aria-hidden = "true" @ click = "$store.ui.menuClose()" @ keyup . esc = "$store.ui.menuClose()" > < / div > < div class = "actor mobile-menu-panel" id = "panel-actor" role = "region" aria-labelledby = "actor-title" tabindex = "-1" > < button class = "panel-close" @ click = "$store.ui.menuClose()" x-show = "$store.ui.menuIsActive" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#close" > < / use > < / svg > < span class = "visually-hidden" x-text = "$t('misc.closePanelBtn')" > < / span > < / button > < h2 class = "visually-hidden" id = "actor-title" x-text = "$t('actor.accountInfo')" > < / h2 > < h3 class = "visually-hidden" id = "actor-tabs-title" x-text = "$t('actor.accounts')" > < / h3 > < div class = "actors-wrapper" :style = "'--actor-hue: '+ $store.files.sources[$store.ui.actorPanel].hue" > < template x-if = "$store.files.sources.length > 1" > < div class = "actors-tabs" role = "tablist" aria-labelledby = "actor-tabs-title" > < template x-for = "(_, source) in $store.files.sources" > < button type = "button" role = "tab" :id = "'actortab-' + source" :aria-selected = "source === $store.ui.actorPanel ? 'true': 'false'" :aria-controls = "'actorpanel-' + source" :style = "'--actor-hue: '+ $store.files.sources[source].hue" @ click = "$store.ui.openActorPanel(source)" @ keyup . right = "$store.ui.switchActorP
(< span class = "count" x-text = "source.likes.length" > < / span > )
< / h2 > < / summary > < div class = "details-content" > < template x-if = "source.likes.length" > < ul > < template x-for = "url in source.likes" > < li > < a :href = "url" x-html = "formatLikesBookmarks(url)" > < / a > < / li > < / template > < / ul > < / template > < template x-if = "! source.likes.length" > < p class = "no-content" > … < span x-text = "$t('actor.likesEmpty')" > < / span > …< / p > < / template > < / div > < / details > < / div > < div class = "actor-bookmarks" > < details > < summary > < span class = "summary-icon" > < svg aria-hidden = "true" > < use href = "#favorite" > < / use > < / svg > < / span > < h2 class = "summary-label" > < span x-text = "$t('actor.bookmarks')" > < / span >
(< span class = "count" x-text = "source.bookmarks.length" > < / span > )
< / h2 > < / summary > < div class = "details-content" > < template x-if = "source.bookmarks.length" > < ul > < template x-for = "url in source.bookmarks" > < li > < a :href = "url" x-html = "formatLikesBookmarks(url)" > < / a > < / li > < / template > < / ul > < / template > < template x-if = "! source.bookmarks.length" > < p class = "no-content" > … < span x-text = "$t('actor.bookmarksEmpty')" > < / span > …< / p > < / template > < / div > < / details > < / div > < / div > < / div > < / template > < / div > < / div > < div class = "toots-filters mobile-menu-panel" id = "panel-filters" role = "search" aria-labelledby = "toots-filter-title" tabindex = "-1" > < button class = "panel-close" @ click = "$store.ui.menuClose()" x-show = "$store.ui.menuIsActive" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#close" > < / use > < / svg > < span class = "visually-hidden" x-text = "$t('misc.closePanelBtn')" > < / span > < / button > < h2 id = "toots-filter-title" x-text = "$t('filters.panelTitle')" > < / h2 > < p class = "visually-hidden" x-text = "$t('filters.panelNotice')" > < / p > < div class = "toots-filters-group" > < div class = "toots-filter text" :class = "isFilterActive('fullText') ? 'active' : ''" > < label for = "filter-fullText" x-text = "$t('filters.fullText')" > < / label > < div class = "input-wrapper" > < input id = "filter-fullText" type = "text" x-model . debounce = "$store.files.filters.fullText" @ keyup . debounce = "$store.files.setFilter()" @ change . debounce = "$store.files.setFilter()" > < / div > < / div > < div class = "toots-filter text" :class = "isFilterActive('hashtagText') ? 'active' : ''" > < label for = "filter-hashtagText" x-text = "$t('filters.hashtagText')" > < / label > < div class = "input-wrapper" > < input id = "filter-hashtagText" type = "text" x-model . debounce = "$store.files.filters.hashtagText" @ keyup . debounce = "$store.files.setFilter()" @ change . debounce = "$store.files.setFilter()" > < / div > < / div > < div class = "toots-filter text" :class = "isFilterActive('mentionText') ? 'active' : ''" > < label for = "filter-mentionText" x-text = "$t('filters.mentionText')" > < / label > < div class = "input-wrapper" > < input id = "filter-mentionText" type = "text" x-model . debounce = "$store.files.filters.mentionText" @ keyup . debounce = "$store.files.setFilter()" @ change . debounce = "$store.files.setFilter()" > < / div > < / div > < div class = "toots-filter text" :class = "isFilterActive('externalLink') ? 'active' : ''" > < label for = "filter-externalLink" x-text = "$t('filters.externalLink')" > < / label > < div class = "input-wrapper" > < input id = "filter-externalLink" type = "text" x-model . debounce = "$store.files.filters.externalLink" @ keyup . debounce = "$store.files.setFilter()" @ change . debounce = "$store.files.setFilter()" > < / div > < / div > < div class = "toots-filter text" :class = "isFilterActive('summary') ? 'active' : ''" > < label for = "filter-summary" x-text = "$t('filters.summary')" > < / label > < div class = "input-wrapper" > < input id = "filter-summary" type = "text" x-model . debounce = "$store.files.filters.summary" @ keyup . debounce = "$store.files.setFilter()" @ change . debounce = "$store.files.setFilter()" > < / div > < / div > < / div > < div class = "toots-filters-group" > < div class = "toots-filter checkbox" :class = "isFilterActive('isEdited') ? 'active' : ''" > < label for = "filter-isEdited" > < input id = "filter-isEdited" type = "checkbox" x-model . debounce = "$store.files.filters.isEdited" @ change . debounce = "$store.files.setFilter()" > < span x-text = "$t('filters.isEdited')" > < / span > < / label > < / div > < template x-show = "$store.files.duplicates" > < div class = "toots-filter checkbox" :class = "isFilterActive('isDuplicate') ? 'active' : ''" > < label for = "filter-isDuplicate" > < input id = "filter-isDuplicate" type = "checkbox" x-model . debounce = "$store.files.filters.isDuplicate" @ change . debounce = "$store.files.setFilter()" > < span x-text = "$t('filters.isDuplicate')" > < / span > < / label > < / div > < / template > < / div > < div class = "toots-filters-group" > < h3 class = "toots-filters-group-title" x-text = "$t('filters.mustContain')" > < / h3 > < div class = "toots-filter checkbox" :class = "isFilterActive('hasHashtags') ? 'active' : ''" > < label for = "filter-hasHashtags" > < input id = "filter-hasHashtags" type = "checkbox" x-model . debounce = "$store.files.filters.hasHashtags" @ change . debounce = "$store.files.setFilter()" > < span x-text = "$t('filters.hasHashtags')" > < / span > < /la
2025-01-06 18:14:41 +01:00
(< span x-text = "lang[1]" > < / span > )
2025-01-09 15:24:56 +01:00
< / span > < / label > < / div > < / template > < / div > < template x-if = "$store.files.sources.length > 1" > < div class = "toots-filters-group" > < h3 class = "toots-filters-group-title" x-text = "$t('filters.author')" > < / h3 > < template x-for = "source in $store.files.sources" > < div class = "toots-filter checkbox" :class = "isFilterActive('actor_' + source.id) ? 'active' : ''" > < label :for = "'filter-actor-' + source.id" > < input :id = "'filter-actor-' + source.id" type = "checkbox" x-model = "$store.files.filters['actor_' + source.id]" @ change = "$store.files.setFilter()" > < span > < span x-text = "source.actor.name" > < / span > < / span > < / label > < / div > < / template > < / div > < / template > < div class = "toots-filters-reset" > < button @ click = "$store.files.resetFilters(true)" :disabled = "!$store.files.filtersActive" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#reset-filters" > < / use > < / svg > < span class = "btn-label" x-text = "$t('filters.resetFilters')" > < / span > < / button > < / div > < / div > < header class = "toots-header" aria-labelledby = "toots-header-title" > < h2 id = "toots-header-title" > < span class = "count" > < span x-text = "await formatNumber($store.files.filteredToots.length)" class = "nb" > < / span > < span x-text = "$t('header.countLabel')" > < / span > < / span > < span class = "order" >
2025-01-06 18:14:41 +01:00
-
2025-01-09 15:24:56 +01:00
< span x-text = "await $store.files.sortAsc ? $t('header.oldestFirst') : $t('header.latestFirst')" > < / span > < button @ click = "$store.files.toggleTootsOrder()" class = "toggle-order" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#toggle-order" > < / use > < / svg > < span class = "btn-label" x-text = "$t('header.reverse')" > < / span > < / button > < / span > < button @ click = "startOver" class = "load-new" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#load-file" > < / use > < / svg > < span class = "btn-label" x-text = "$t('header.loadNewFile')" > < / span > < / button > < / h2 > < div class = "paging" > < div class = "direction-back" > < button id = "paging-btn-first" @ click = "$store.files.firstPage()" :disabled = "$store.files.currentPage <= 1" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#nav-first" > < / use > < / svg > < span class = "btn-label" x-text = "$t('paging.first')" > < / span > < / button > < button id = "paging-btn-prev" @ click = "$store.files.prevPage()" :disabled = "$store.files.currentPage <= 1" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#nav-prev" > < / use > < / svg > < span class = "btn-label" x-text = "$t('paging.prev')" > < / span > < / button > < / div > < div class = "paging-options-toggle" > < button @ click = "$store.ui.togglePagingOptions()" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#options" > < / use > < / svg > < span class = "btn-label" x-text = "$t('paging.pagingOptions')" > < / span > < / button > < / div > < div class = "paging-options" id = "paging-options" :class = "$store.ui.pagingOptionsClass" tabindex = "-1" > < div class = "paging-options-inner" > < label for = "paging-current-page" x-text = "$t('paging.page')" > < / label > < input class = "current-page" id = "paging-current-page" type = "number" min = "1" max = "$store.files.totalPages" x-model = "$store.files.currentPage" @ keyup = "$store.files.checkPagingValue()" @ change = "$store.files.checkPagingValue()" onclick = "this.select()" >
2025-01-06 18:14:41 +01:00
/
< span class = "total-pages" x-text = "formatNumber($store.files.totalPages)" > < / span >
(
2025-01-09 15:24:56 +01:00
< input class = "page-size" id = "paging-page-size" type = "number" min = "1" x-model = "$store.files.pageSize" @ keyup = "$store.files.checkPagingValue()" @ change = "$store.files.checkPagingValue()" onclick = "this.select()" > < label for = "paging-page-size" x-text = "$t('paging.postsPerPage')" > < / label > )
< / div > < div class = "paging-options-reverse" > < button @ click = "$store.files.toggleTootsOrder()" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#toggle-order" > < / use > < / svg > < span class = "btn-label" x-text = "$t('paging.reverseOrder')" > < / span > < / button > < / div > < / div > < div class = "direction-fwd" > < button id = "paging-btn-next" @ click = "$store.files.nextPage()" :disabled = "$store.files.currentPage >= $store.files.totalPages" > < span class = "btn-label" x-text = "$t('paging.next')" > < / span > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#nav-next" > < / use > < / svg > < / button > < button id = "paging-btn-last" @ click = "$store.files.lastPage()" :disabled = "$store.files.currentPage >= $store.files.totalPages" > < span class = "btn-label" x-text = "$t('paging.last')" > < / span > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#nav-last" > < / use > < / svg > < / button > < / div > < / div > < / header > < div class = "toots" id = "toots" role = "region" aria-labelledby = "toots-title" tabindex = "-1" > < h2 id = "toots-title" class = "visually-hidden" x-text = "$t('posts.panelTitle')" > < / h2 > < template x-show = "$store.files.pagedToots.length" x-for = "toot in await $store.files.pagedToots" > < div class = "toot" :class = "['toot-type-' + contentType(toot.type).toLowerCase(), 'toot-visibility-' + toot._marl.visibility[0]]" :style = "'--actor-hue: '+ $store.files.sources[toot._marl.source].hue" > < h3 class = "toot-header visually-hidden" > < span x-text = "contentType(toot.type)" > < / span > < span x-text = "$t('post.by')" > < / span > < span x-text = "formatAuthor(toot.actor, true)" > < / span > ,
< span x-text = "formatDateTime(toot.published)" > < / span > < / h3 > < template x-if = "toot.type === 'Create'" > < div class = "toot-pretty" > < div class = "toot-summary" x-show = "toot.object.summary" > < span x-text = "toot.object.summary" > < / span > < / div > < div class = "toot-content" x-html = "toot.object.content" > < / div > < div class = "toot-attachments" x-show = "toot.object.attachment && toot.object.attachment.length" > < ul > < template x-for = "(att, index) in toot.object.attachment" > < li :class = "attachmentWrapperClass(att)" :data-trigger = "loadAttachedMedia(att, toot._marl.source)" > < template x-if = "attachmentIsImage(att) && $store.files.sources[toot._marl.source][att.url]" > < div class = "att-wrapper" > < button class = "att-img-wrapper" @ click = "$store.lightbox.open(toot, index, 'att-' + toot._marl.id + '-' + index)" :id = "'att-' + toot._marl.id + '-' + index" > < img alt = "" :src = "`data:${att.mediaType}; base64,${await $store.files.sources[toot._marl.source][att.url].content}`" :aria-labelledby = "'att-' + toot._marl.id + '-' + index + '-desc'" > < / button > < div class = "att-description" > < span class = "desc-body" x-text = "att.name ?? $t('posts.attachmentNoAlt')" :id = "'att-' + toot._marl.id + '-' + index + '-desc'" aria-hidden = "true" > < / span > < span class = "desc-source" > < strong x-text = "$t('post.attachmentInArchive')" > < / strong > < span x-text = "att.url" > < / span > < / span > < / div > < / div > < / template > < template x-if = "attachmentIsSound(att) && $store.files.sources[toot._marl.source][att.url]" > < div class = "att-wrapper" > < audio controls :src = "`data:${att.mediaType}; base64,${await $store.files.sources[toot._marl.source][att.url].content}`" :aria-labelledby = "'att-' + toot._marl.id + '-' + index + '-desc'" > < / audio > < div class = "att-description" > < span class = "desc-body" x-text = "att.name ?? $t('posts.attachmentNoAlt')" :id = "'att-' + toot._marl.id + '-' + index + '-desc'" aria-hidden = "true" > < / span > < span class = "desc-source" > < strong x-text = "$t('post.attachmentInArchive')" > < / strong > < span x-text = "att.url" > < / span > < / span > < / div > < / div > < / template > < template x-if = "attachmentIsVideo(att) && $store.files.sources[toot._marl.source][att.url]" > < div class = "att-wrapper" > < video controls :width = "att.width" :height = "att.height" :src = "`data:${att.mediaType}; base64,${await $store.files.sources[toot._marl.source][att.url].content}`" :aria-labelledby = "'att-' + toot._marl.id + '-' + index + '-desc'" > < / video > < div class = "att-description" > < span class = "desc-body" x-text = "att.name ?? $t('posts.attachmentNoAlt')" :id = "'att-' + toot._marl.id + '-' + index + '-desc'" aria-hidden = "true" > < / span > < span class = "desc-source" > < strong x-text = "$t('post.attachmentInArchive')" > < / strong > < span x-text = "att.url" > < / span > < / span > < / div > < / div > < / template > < / li > < / template > < / ul > < / div > < / div > < / template > < template x-if = "toot.type === 'Announce' && toot.object && toot.object.content" > < div class = "toot-pretty" > < div class = "toot-content" > < div class = "toot-content-inner" x-html = "toot.object.content" > < / div > < / div > < / div > < / template > < template x-if = "toot.type === 'Announce' && toot.object && !toot.object.content" > < div class = "toot-pretty" > < div class = "toot-content" > < div class = "toot-content-inner" > < a :href = "toot.object" x-text = "toot.object" > < / a > < / div > < / div > < / div > < / template > < div class = "toot-infos" > < span class = "type" > < span x-text = "contentType(toot.type)" > < / span >
< / span > < span class = "author" > < span x-text = "$t('post.by')" > < / span > < span x-html = "formatAuthor(toot.actor)" > < / span > < / span > < span class = "published" > < span x-text = "formatDateTime(toot.published)" > < / span > < span x-show = "toot.object && toot.object.updated" class = "updated" > < span x-text = "$t('post.lastUpdated')" > < / span > < span x-text = "formatDateTime(toot.object.updated)" > < / span > < / span > < / span > < span class = "visibility" > < span x-text = "toot._marl.visibility[1]" > < / span > < / span > < span class = "link" > < a x-show = "toot.object.id" :href = "toot.object.id" x-text = "$t('post.linkToPost')" > < / a > < / span > < / div > < template x-if = "(toot.object.tag && toot.object.tag.length) || (toot._marl.externalLinks && toot._marl.externalLinks.length)" > < div class = "toot-meta" > < template x-if = "toot.object.tag && toot.object.tag.filter(x => x.type === 'Mention').length" > < div class = "toot-people" > < h4 x-text = "$t('post.people')" > < / h4 > < ul > < template x-for = "tag in toot.object.tag" > < li x-show = "tag.type === 'Mention'" > < a :href = "tag.href" x-text = "tag.name" > < / a > < / li > < / template > < / ul > < / div > < / template > < template x-if = "toot.object.tag && toot.object.tag.filter(x => x.type === 'Hashtag').length" > < div class = "toot-hashtags" > < h4 x-text = "$t('post.hashtags')" > < / h4 > < ul > < template x-for = "tag in toot.object.tag" > < li x-show = "tag.type === 'Hashtag'" > < a :href = "tag.href" x-text = "tag.name" > < / a > < / li > < / template > < / ul > < / div > < / template > < template x-if = "toot._marl.externalLinks.length" > < div class = "toot-links" > < h4 x-text = "$t('post.extLinks')" > < / h4 > < ul > < template x-for = "link in toot._marl.externalLinks" > < li > < a :href = "link.href" x-text = "link.text" > < / a > < / li > < / template > < / ul > < / div > < / template > < / div > < / template > < div class = "toot-raw" > < details > < summary > < span class = "summary-icon" > < svg aria-hidden = "true" > < use href = "#json" > < / use > < / svg > < / span > < span class = "summary-label" :id = "'raw-' + toot._marl.id" x-text = "$t('post.rawData')" > < / span > < / summary > < div class = "details-content" > < textarea x-text = "formatJson(toot)" :aria-labelledby = "'raw-' + toot._marl.id" readonly > < / textarea > < / div > < / details > < / div > < / div > < / template > < div class = "toots-no-results" x-show = "$store.files.pagedToots.length === 0" > < div x-show = "$store.files.filtersActive" > < p x-text = "$t('posts.noResults')" > < / p > < p class = "action" > < button @ click = "$store.files.resetFilters(true)" :disabled = "!$store.files.filtersActive" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#reset-filters" > < / use > < / svg > < span class = "btn-label" x-text = "$t('filters.resetFilters')" > < / span > < / button > < / p > < / div > < div x-show = "!$store.files.filtersActive" > < p x-text = "$t('posts.noPostsError')" > < / p > < / div > < / div > < div class = "paging" > < div class = "direction-back" > < button @ click = "$store.files.firstPage('toots')" :disabled = "$store.files.currentPage <= 1" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#nav-first" > < / use > < / svg > < span class = "btn-label" x-text = "$t('paging.first')" > < / span > < / button > < button @ click = "$store.files.prevPage('paging-btn-prev')" :disabled = "$store.files.currentPage <= 1" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#nav-prev" > < / use > < / svg > < span class = "btn-label" x-text = "$t('paging.prev')" > < / span > < / button > < / div > < div class = "direction-fwd" > < button @ click = "$store.files.nextPage('paging-btn-next')" :disabled = "$store.files.currentPage >= $store.files.totalPages" > < span class = "btn-label" x-text = "$t('paging.next')" > < / span > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#nav-next" > < / use > < / svg > < / button > < button @ click = "$store.files.lastPage('toots')" :disabled = "$store.files.currentPage >= $store.files.totalPages" > < span class = "btn-label" x-text = "$t('paging.last')" > < / span > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#nav-last" > < / use > < / svg > < / button > < / div > < / div > < / div > < aside class = "toots-tags mobile-menu-panel" id = "panel-tags" aria-labelledby = "toots-tags-title" tabindex = "-1" > < button class = "panel-close" @ click = "$store.ui.menuClose()" x-show = "$store.ui.menuIsActive" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#close" > < / use > < / svg > < span class = "visually-hidden" x-text = "$t('misc.close
2025-01-06 18:14:41 +01:00
(< span x-text = "formatNumber($store.files.listHashtags.length)" > < / span > )
2025-01-09 15:24:56 +01:00
< / span > < / h3 > < div class = "tags-group-filter" > < label for = "tags-group-hashtags-filter" class = "visually-hidden" x-text = "$t('tags.hashtagsFilter')" > < / label > < input id = "tags-group-hashtags-filter" type = "text" onclick = "this.select()" x-model . debounce = "$store.files.tagsFilters.hashtags" > < / div > < / div > < div class = "tags-group-scroll" > < ul x-show = "$store.files.listHashtags.length" > < template x-for = "item in await $store.files.listHashtags" > < li :class = "item.name === $store.files.filters.hashtagText ? 'active' : ''" > < button :id = "'filter-hashtag-' + item.name.toLowerCase().slice(1)" @ click = "$store.files.filterByTag('hashtagText', item.name, 'filter-hashtag-' + item.name.toLowerCase().slice(1))" > < div > < span class = "visually-hidden" x-text = "item.name === $store.files.filters.hashtagText ? 'active item:' : ''" > < / span > < span class = "count" x-text = "`(${item.nb})`" > < / span > < span class = "name" x-text = "item.name" > < / span > < / div > < / button > < / li > < / template > < / ul > < / div > < / div > < div class = "tags-group" > < div class = "tags-group-header" > < h3 > < span x-text = "$t('tags.mentions')" > < / span > < span class = "count" >
2025-01-06 18:14:41 +01:00
(< span x-text = "formatNumber($store.files.listMentions.length)" > < / span > )
2025-01-09 15:24:56 +01:00
< / span > < / h3 > < div class = "tags-group-filter" > < label for = "tags-group-mentions-filter" class = "visually-hidden" x-text = "$t('tags.mentionsFilter')" > < / label > < input id = "tags-group-mentions-filter" type = "text" onclick = "this.select()" x-model . debounce = "$store.files.tagsFilters.mentions" > < / div > < / div > < div class = "tags-group-scroll" > < ul x-show = "$store.files.listMentions.length" > < template x-for = "item in await $store.files.listMentions" > < li :class = "item.name === $store.files.filters.mentionText ? 'active' : ''" > < button :id = "'filter-mention-' + item.name.toLowerCase().replaceAll('@', '_').replaceAll('.', '_')" @ click = "$store.files.filterByTag('mentionText', item.name, 'filter-mention-' + item.name.toLowerCase().replaceAll('@', '_').replaceAll('.', '_'))" > < div > < span class = "visually-hidden" x-text = "item.name === $store.files.filters.mentionText ? 'active item:' : ''" > < / span > < span class = "count" x-text = "`(${item.nb})`" > < / span > < span class = "name" x-text = "item.name" > < / span > < / div > < / button > < / li > < / template > < / ul > < / div > < / div > < div class = "tags-group" > < div class = "tags-group-header" > < h3 > < span x-text = "$t('tags.boosts')" > < / span > < span class = "count" >
2025-01-06 18:14:41 +01:00
(< span x-text = "formatNumber($store.files.listBoostsAuthors.length)" > < / span > )
2025-01-09 15:24:56 +01:00
< / span > < / h3 > < div class = "tags-group-filter" > < label for = "tags-group-boostsAuthors-filter" class = "visually-hidden" x-text = "$t('tags.boostsFilter')" > < / label > < input id = "tags-group-boostsAuthors-filter" type = "text" onclick = "this.select()" x-model . debounce = "$store.files.tagsFilters.boostsAuthors" > < / div > < / div > < div class = "tags-group-scroll" > < ul x-show = "$store.files.listBoostsAuthors.length" > < template x-for = "item in await $store.files.listBoostsAuthors" > < li :class = "item.url === $store.files.filters.fullText ? 'active' : ''" > < button :id = "'filter-boost-author-' + item.url.toLowerCase().replaceAll('/', '_')" @ click = "$store.files.filterByTag('fullText', item.url, 'filter-boost-author-' + item.url.toLowerCase().replaceAll('/', '_'))" > < div > < span class = "visually-hidden" x-text = "item.url === $store.files.filters.fullText ? 'active item:' : ''" > < / span > < span class = "count" x-text = "`(${item.nb})`" > < / span > < span class = "name" > < span x-text = "item.name" > < / span > < span x-text = "item.domain" class = "domain" > < / span > < / span > < / div > < / button > < / li > < / template > < / ul > < / div > < / div > < / aside > < / div > < template x-if = "$store.lightbox.show && $store.lightbox.data.length" > < div id = "lightbox" class = "lightbox overlay" tabindex = "-1" @ keyup . left = "$store.lightbox.showPrev()" @ keyup . right = "$store.lightbox.showNext()" @ keyup . esc = "$store.lightbox.close()" > < div class = "overlay-content" > < img :alt = "$store.lightbox.data[$store.lightbox.index].name" :src = "`data:${$store.lightbox.data[$store.lightbox.index].mediaType}; base64,${$store.files.sources[$store.lightbox.source][$store.lightbox.data[$store.lightbox.index].url].content}`" @ click = "$store.lightbox.showNext()" > < / div > < div class = "overlay-ui" > < div class = "backdrop" @ click = "$store.lightbox.close()" > < / div > < button x-show = "$store.lightbox.data.length > 1" class = "viewer-next" @ click = "$store.lightbox.showNext()" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#viewer-next" > < / use > < / svg > < span class = "visually-hidden" x-text = "$t('lightbox.next')" > < / span > < / button > < button x-show = "$store.lightbox.data.length > 1" class = "viewer-prev" @ click = "$store.lightbox.showPrev()" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#viewer-prev" > < / use > < / svg > < span class = "visually-hidden" x-text = "$t('lightbox.prev')" > < / span > < / button > < button class = "viewer-close" @ click = "$store.lightbox.close()" > < svg class = "btn-icon" aria-hidden = "true" > < use href = "#close" > < / use > < / svg > < span class = "visually-hidden" x-text = "$t('lightbox.close')" > < / span > < / button > < / div > < / div > < / template > < / main > < / template > < / div > < svg style = "display: none" > < symbol viewBox = "0 -960 960 960" id = "reset-filters" > < path d = "m653-208-46 46q-17 17-42 17.5T522-162q-17-17-17-42.5t17-42.5l46-46q-4-11-6-23t-2-24q0-58 41-99t99-41q9 0 18 .5t17 3.5q11 4 13.5 16.5T743-439l-43 43q-11 11-11 28t11 28q11 11 28 11t28-11l43-43q8-8 20.5-5.5T836-375q3 8 3.5 17t.5 18q0 58-41 99t-99 41q-13 0-24.5-2t-22.5-6ZM480-760q-117 0-198.5 81.5T200-480q0 72 32.5 132t87.5 98v-70q0-17 11.5-28.5T360-360q17 0 28.5 11.5T400-320v160q0 17-11.5 28.5T360-120H200q-17 0-28.5-11.5T160-160q0-17 11.5-28.5T200-200h54q-62-50-98-122.5T120-480q0-75 28.5-140.5t77-114q48.5-48.5 114-77T480-840q113 0 203.5 63T814-615q6 16 0 31t-22 21q-16 6-31.5 0T739-585q-31-78-100.5-126.5T480-760Z" > < / path > < / symbol > < symbol viewBox = "0 -960 960 960" id = "toggle-order" > < path d = "M360-440q-17 0-28.5-11.5T320-480v-247l-75 75q-11 11-27.5 11T189-652q-12-12-12-28.5t12-28.5l143-143q6-6 13-8.5t15-2.5q8 0 15 2.5t13 8.5l144 144q12 12 11.5 28T531-652q-12 11-28 11.5T475-652l-75-75v247q0 17-11.5 28.5T360-440ZM600-97q-8 0-15-2.5t-13-8.5L428-252q-12-12-11.5-28t12.5-28q12-11 28-11.5t28 11.5l75 75v-247q0-17 11.5-28.5T600-520q17 0 28.5 11.5T640-480v247l75-75q11-11 27.5-11t28.5 11q12 12 12 28.5T771-251L628-108q-6 6-13 8.5T600-97Z" > < / path > < / symbol > < symbol viewBox = "0 -960 960 960" id = "load-file" > < path d = "M160-160q-33 0-56 . 5-23 . 5T80-240v-480q0-33 23 . 5-56 . 5T160-800h207q16 0 30 . 5 6t25 . 5 17l57 57h360q17 0 28 . 5 11 . 5T880-680q0 17-11 . 5 28 . 5T840-640H447l-80-80H160v480l79-263q8-26 29 . 5-41 . 5T316-560h516q41 0 64 . 5 32 . 5T909-457l-72 240q-8 26-29 . 5 41 . 5T760-160H160Zm84-80h516l72-240H