Consolidate singles

This commit is contained in:
Tiberiu Ichim 2026-02-17 11:58:39 +02:00
parent 58fbd9510a
commit cc0b2c847a
4 changed files with 114 additions and 11 deletions

View file

@ -117,9 +117,9 @@
</div>
<!-- Not Consolidated Badge -->
<ui-tooltip v-if="isNotConsolidated && !isSelectionMode && !isHovering" text="Not Consolidated" direction="top" class="absolute left-0 z-10" :style="{ padding: 0.375 + 'em', bottom: 0.375 + 'em' }">
<div class="rounded-full bg-warning flex items-center justify-center border border-black/20 shadow-sm" :style="{ width: 1.25 + 'em', height: 1.25 + 'em' }">
<span class="material-symbols text-black" :style="{ fontSize: 0.9 + 'em' }">folder_open</span>
<ui-tooltip v-if="isNotConsolidated && !isSelectionMode" text="Not Consolidated" direction="top" class="absolute left-0 z-10" :style="{ padding: 0.375 + 'em', bottom: ebookFormat ? '1.5em' : '0.375em' }">
<div class="rounded-full bg-yellow-500 flex items-center justify-center border border-black/20 shadow-sm" :style="{ width: 1.2 + 'em', height: 1.2 + 'em' }">
<span class="material-symbols text-black" :style="{ fontSize: 0.8 + 'em' }">warning</span>
</div>
</ui-tooltip>
</div>

View file

@ -226,6 +226,40 @@ Vue.prototype.$downloadFile = (url, filename = null, openInNewTab = false) => {
})
}
Vue.prototype.$sanitizeFilename = (filename, colonReplacement = ' - ') => {
if (typeof filename !== 'string') return ''
const illegalRe = /[\/\?<>\\:\*\|"]/g
const controlRe = /[\x00-\x1f\x80-\x9f]/g
const reservedRe = /^\.+$/
const windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i
const windowsTrailingRe = /[\. ]+$/
const lineBreaks = /[\n\r]/g
let sanitized = filename
.normalize('NFC')
.replace(':', colonReplacement)
.replace(illegalRe, '')
.replace(controlRe, '')
.replace(reservedRe, '')
.replace(lineBreaks, '')
.replace(windowsReservedRe, '')
.replace(windowsTrailingRe, '')
.replace(/\s+/g, ' ')
.trim()
// Rough truncation for 255 bytes (assuming 2 bytes per char for safety)
const MAX_FILENAME_BYTES = 255
if (sanitized.length > MAX_FILENAME_BYTES / 2) {
sanitized = sanitized.substring(0, Math.floor(MAX_FILENAME_BYTES / 2)).trim()
}
return sanitized
}
Vue.prototype.$getConsolidatedFolderName = (author, title) => {
return Vue.prototype.$sanitizeFilename(`${author} - ${title}`)
}
export function supplant(str, subs) {
// source: http://crockford.com/javascript/remedial.html
return str.replace(/{([^{}]*)}/g, function (a, b) {