@traky-app/ui 1.6.7 → 1.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/RELEASE.md +14 -2
- package/package.json +2 -2
- package/registry/traky/json/file-manager.json +25 -0
- package/registry/traky/json/globe.json +1 -1
- package/registry/traky/json/lib-file-items.json +14 -0
- package/registry/traky/json/lib-file-manager-utils.json +14 -0
- package/registry/traky/json/world-globe.json +20 -0
- package/registry/traky/lib/file-items.ts +99 -0
- package/registry/traky/lib/file-manager-utils.ts +116 -0
- package/registry/traky/registry.json +40 -0
- package/registry/traky/ui/file-manager.tsx +646 -0
- package/registry/traky/ui/globe.tsx +71 -32
- package/registry/traky/ui/world-globe.tsx +292 -0
- package/src/lib/file-items.ts +99 -0
- package/src/lib/file-manager-utils.test.tsx +71 -0
- package/src/lib/file-manager-utils.ts +116 -0
- package/src/ui/file-manager.tsx +646 -0
- package/src/ui/globe.tsx +71 -32
- package/src/ui/world-globe.tsx +292 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { FileItem, FileStorageProvider } from "./file-items"
|
|
2
|
+
|
|
3
|
+
export const ACCEPTED_TYPES = ".png,.jpg,.jpeg,.webp,.gif,.pdf"
|
|
4
|
+
export const ACCEPTED_TYPES_WITH_VIDEO =
|
|
5
|
+
".png,.jpg,.jpeg,.webp,.gif,.pdf,.mp4,.webm,.mov,.mkv"
|
|
6
|
+
export const ACCEPTED_MIME = [
|
|
7
|
+
"image/png",
|
|
8
|
+
"image/jpeg",
|
|
9
|
+
"image/webp",
|
|
10
|
+
"image/gif",
|
|
11
|
+
"application/pdf",
|
|
12
|
+
]
|
|
13
|
+
export const VIDEO_MIME = [
|
|
14
|
+
"video/mp4",
|
|
15
|
+
"video/webm",
|
|
16
|
+
"video/quicktime",
|
|
17
|
+
"video/x-matroska",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
export function isImageFile(file: FileItem) {
|
|
21
|
+
const type = file.type ?? ""
|
|
22
|
+
const name = file.name ?? ""
|
|
23
|
+
const url = file.url ?? ""
|
|
24
|
+
return (
|
|
25
|
+
type.startsWith("image/") ||
|
|
26
|
+
/\.(png|jpe?g|gif|webp|bmp|svg)$/i.test(name) ||
|
|
27
|
+
/\.(png|jpe?g|gif|webp|bmp|svg)(\?|$)/i.test(url)
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function isPdfFile(file: FileItem) {
|
|
32
|
+
const type = file.type ?? ""
|
|
33
|
+
const name = file.name ?? ""
|
|
34
|
+
const url = file.url ?? ""
|
|
35
|
+
return (
|
|
36
|
+
type.includes("pdf") || /\.pdf$/i.test(name) || /\.pdf(\?|$)/i.test(url)
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function isVideoFile(file: FileItem) {
|
|
41
|
+
const type = file.type ?? ""
|
|
42
|
+
const name = file.name ?? ""
|
|
43
|
+
const url = file.url ?? ""
|
|
44
|
+
return (
|
|
45
|
+
type.startsWith("video/") ||
|
|
46
|
+
/\.(mp4|webm|mov|mkv)$/i.test(name) ||
|
|
47
|
+
/\.(mp4|webm|mov|mkv)(\?|$)/i.test(url)
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function isAcceptedFile(file: File, acceptVideos: boolean) {
|
|
52
|
+
const type = file.type ?? ""
|
|
53
|
+
if (ACCEPTED_MIME.includes(type)) return true
|
|
54
|
+
if (acceptVideos && (VIDEO_MIME.includes(type) || type.startsWith("video/"))) {
|
|
55
|
+
return true
|
|
56
|
+
}
|
|
57
|
+
if (/\.(png|jpe?g|webp|gif|pdf)$/i.test(file.name)) return true
|
|
58
|
+
if (acceptVideos && /\.(mp4|webm|mov|mkv)$/i.test(file.name)) return true
|
|
59
|
+
return false
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function getFileDisplayName(file: FileItem, maxLength = 40): string {
|
|
63
|
+
let label = file.name?.trim() ?? ""
|
|
64
|
+
const looksLikeUrl =
|
|
65
|
+
/^https?:\/\//i.test(label) || (label.length > 72 && !label.includes(" "))
|
|
66
|
+
|
|
67
|
+
if (!label || looksLikeUrl) {
|
|
68
|
+
try {
|
|
69
|
+
const pathname = decodeURIComponent(new URL(file.url ?? "").pathname)
|
|
70
|
+
const fromUrl = pathname.split("/").filter(Boolean).pop() ?? ""
|
|
71
|
+
if (fromUrl) label = fromUrl
|
|
72
|
+
} catch {
|
|
73
|
+
// ignore invalid URL
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!label) return "Archivo"
|
|
78
|
+
if (label.length <= maxLength) return label
|
|
79
|
+
|
|
80
|
+
const dot = label.lastIndexOf(".")
|
|
81
|
+
const ext = dot > 0 && label.length - dot <= 8 ? label.slice(dot) : ""
|
|
82
|
+
const stem = ext ? label.slice(0, dot) : label
|
|
83
|
+
const budget = maxLength - ext.length - 1
|
|
84
|
+
if (budget < 8) return `${label.slice(0, maxLength - 1)}…`
|
|
85
|
+
return `${stem.slice(0, budget)}…${ext}`
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function getFileFullName(file: FileItem): string {
|
|
89
|
+
const label = file.name?.trim()
|
|
90
|
+
if (label && !/^https?:\/\//i.test(label)) return label
|
|
91
|
+
return getFileDisplayName(file, 200)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function downloadFile(file: FileItem) {
|
|
95
|
+
const link = document.createElement("a")
|
|
96
|
+
link.href = file.url
|
|
97
|
+
link.download = file.name || "archivo"
|
|
98
|
+
link.target = "_blank"
|
|
99
|
+
link.rel = "noopener noreferrer"
|
|
100
|
+
document.body.appendChild(link)
|
|
101
|
+
link.click()
|
|
102
|
+
link.remove()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function toFileItem(
|
|
106
|
+
file: File,
|
|
107
|
+
url: string,
|
|
108
|
+
provider?: FileStorageProvider,
|
|
109
|
+
): FileItem {
|
|
110
|
+
return {
|
|
111
|
+
name: file.name,
|
|
112
|
+
url,
|
|
113
|
+
type: file.type,
|
|
114
|
+
...(provider ? { provider } : {}),
|
|
115
|
+
}
|
|
116
|
+
}
|