Files

138 lines
3.9 KiB
JavaScript

var IMAGE_EXTENSIONS = {
jpg: true, jpeg: true, png: true, gif: true, webp: true, avif: true, heic: true,
svg: true, bmp: true, tif: true, tiff: true
}
var VIDEO_EXTENSIONS = {
mp4: true, mov: true, mkv: true, webm: true, avi: true, m4v: true, mpg: true,
mpeg: true, wmv: true
}
var DOCUMENT_EXTENSIONS = {
pdf: true, txt: true, md: true, doc: true, docx: true, xls: true, xlsx: true,
ppt: true, pptx: true, odt: true, ods: true, odp: true, rtf: true, csv: true,
pages: true, numbers: true, key: true
}
function parseStatus(raw) {
var text = String(raw || "").trim()
if (text === "") return defaultStatus()
try {
var parsed = JSON.parse(text)
if (!parsed || typeof parsed !== "object") return defaultStatus()
parsed.files = Array.isArray(parsed.files) ? parsed.files : []
return parsed
} catch (e) {
var failed = defaultStatus()
failed.ok = false
failed.lastError = "Failed to parse Dropbox status"
return failed
}
}
function defaultStatus() {
return {
ok: true,
installed: false,
running: false,
authenticated: false,
statusText: "Unavailable",
accountPath: "",
plan: "",
usedBytes: 0,
quotaBytes: 0,
usagePercent: 0,
quotaKnown: false,
files: []
}
}
function fileExtension(name) {
var value = String(name || "").toLowerCase()
var index = value.lastIndexOf(".")
return index >= 0 ? value.substring(index + 1) : ""
}
function fileKind(name) {
var ext = fileExtension(name)
if (IMAGE_EXTENSIONS[ext]) return "image"
if (VIDEO_EXTENSIONS[ext]) return "video"
if (DOCUMENT_EXTENSIONS[ext]) return "document"
return "misc"
}
function fileGlyph(name) {
var kind = fileKind(name)
if (kind === "image") return "󰋩"
if (kind === "video") return "󰈫"
if (kind === "document") return "󰈙"
return "󰈔"
}
function formatBytes(bytes) {
var value = Number(bytes || 0)
if (!isFinite(value) || value <= 0) return "0 B"
var units = ["B", "KB", "MB", "GB", "TB"]
var index = 0
while (value >= 1000 && index < units.length - 1) {
value = value / 1000
index++
}
var decimals = value >= 100 || index === 0 ? 0 : (value >= 10 ? 1 : 2)
return value.toFixed(decimals).replace(/\.0+$/, "").replace(/(\.\d)0$/, "$1") + " " + units[index]
}
function formatPercent(value) {
var number = Number(value || 0)
if (!isFinite(number) || number <= 0) return "0%"
if (number >= 10) return Math.round(number) + "%"
return number.toFixed(1).replace(/\.0$/, "") + "%"
}
function usageText(usedBytes, quotaBytes, quotaKnown) {
if (quotaKnown && Number(quotaBytes || 0) > 0) {
return formatBytes(usedBytes) + " of " + formatBytes(quotaBytes)
}
return formatBytes(usedBytes)
}
function relativeTime(timestampSec, nowMs) {
var ts = Number(timestampSec || 0)
if (!isFinite(ts) || ts <= 0) return "Unknown time"
var now = nowMs === undefined ? Date.now() : Number(nowMs)
var diff = Math.max(0, Math.floor((now - ts * 1000) / 1000))
if (diff < 60) return "Just now"
var minutes = Math.floor(diff / 60)
if (minutes < 60) return minutes + "m ago"
var hours = Math.floor(minutes / 60)
if (hours < 24) return hours + "h ago"
var days = Math.floor(hours / 24)
if (days < 30) return days + "d ago"
var months = Math.floor(days / 30)
if (months < 12) return months + "mo ago"
return Math.floor(days / 365) + "y ago"
}
function fileMeta(file, nowMs) {
if (!file) return ""
var parts = [relativeTime(file.modifiedTs, nowMs)]
var folder = String(file.folder || "")
if (folder !== "") parts.push(folder)
return parts.join(" · ")
}
if (typeof module !== "undefined") {
module.exports = {
parseStatus: parseStatus,
defaultStatus: defaultStatus,
fileExtension: fileExtension,
fileKind: fileKind,
fileGlyph: fileGlyph,
formatBytes: formatBytes,
formatPercent: formatPercent,
usageText: usageText,
relativeTime: relativeTime,
fileMeta: fileMeta
}
}