This commit is contained in:
metacryst
2026-04-28 20:05:00 -05:00
commit 0d6c7683ff
123 changed files with 20922 additions and 0 deletions

159
files/desktop/files.js Normal file
View File

@@ -0,0 +1,159 @@
import "./DesktopFilesSidebar.js"
import "./DesktopFilesToolbar.js"
import "./DesktopFilesGrid.js"
css(`
files- {
font-family: 'Arial';
scrollbar-width: none;
-ms-overflow-style: none;
}
@keyframes pulse-ring {
0% { transform: scale(1); opacity: 0.5; }
100% { transform: scale(2.2); opacity: 0; }
}
`)
class Files extends Shadow {
constructor() {
super()
this.viewMode = "list"
this.searchText = ""
this.activeLocation = "all"
this.groups = [
{ id: 1, name: "All Members", color: "#3b82f6", fileCount: 24 },
{ id: 2, name: "Admins", color: "#ef4444", fileCount: 8 },
{ id: 3, name: "Editors", color: "#10b981", fileCount: 15 },
{ id: 4, name: "Viewers", color: "#f59e0b", fileCount: 19 },
{ id: 5, name: "External", color: "#8b5cf6", fileCount: 4 },
]
this.activeGroupIds = new Set(this.groups.map(g => g.id))
this.locations = [
{ id: "all", label: "All Files", icon: "🗂" },
{ id: "mine", label: "My Files", icon: "👤" },
{ id: "shared", label: "Shared with Me", icon: "👥" },
{ id: "recent", label: "Recent", icon: "🕐" },
{ id: "starred", label: "Starred", icon: "⭐" },
{ id: "trash", label: "Trash", icon: "🗑" },
]
const ago = (d) => new Date(Date.now() - d * 86400000);
this.files = [
// Folders
{ id: 1, type: "folder", name: "Design Assets", groupId: 3, modifiedAt: ago(0), size: "—", sharedWith: ["Sarah McIntyre", "Jordan Kim", "Marcus Webb"], activeEditors: [], ownerId: 1, starred: true },
{ id: 2, type: "folder", name: "Engineering Docs", groupId: 2, modifiedAt: ago(1), size: "—", sharedWith: ["Marcus Webb"], activeEditors: [], ownerId: 1, starred: false },
// PDFs
{ id: 3, type: "file", name: "Q2 Board Presentation.pdf", groupId: 2, modifiedAt: ago(0), size: "4.2 MB", sharedWith: ["Priya Anand", "Marcus Webb"], activeEditors: ["Sarah McIntyre"], ownerId: 1, starred: true },
{ id: 4, type: "file", name: "Brand Guidelines.pdf", groupId: 1, modifiedAt: ago(3), size: "12.8 MB", sharedWith: ["Sarah McIntyre", "Jordan Kim"], activeEditors: [], ownerId: 2, starred: false },
{ id: 5, type: "file", name: "Legal NDA Template.pdf", groupId: 2, modifiedAt: ago(14), size: "0.9 MB", sharedWith: ["Priya Anand"], activeEditors: [], ownerId: 1, starred: false },
// Docs
{ id: 6, type: "file", name: "Product Roadmap.docx", groupId: 3, modifiedAt: ago(0), size: "1.1 MB", sharedWith: ["Sarah McIntyre", "Priya Anand", "Jordan Kim"], activeEditors: ["Marcus Webb", "Priya Anand"], ownerId: 1, starred: true },
{ id: 7, type: "file", name: "Sprint 22 Notes.md", groupId: 3, modifiedAt: ago(1), size: "18 KB", sharedWith: ["Marcus Webb"], activeEditors: [], ownerId: 3, starred: false },
{ id: 8, type: "file", name: "Onboarding Checklist.docx", groupId: 1, modifiedAt: ago(5), size: "245 KB", sharedWith: ["Sarah McIntyre", "Priya Anand"], activeEditors: [], ownerId: 1, starred: false },
// Spreadsheets
{ id: 9, type: "file", name: "Budget 2026.xlsx", groupId: 2, modifiedAt: ago(2), size: "3.3 MB", sharedWith: ["Priya Anand"], activeEditors: ["Jordan Kim"], ownerId: 1, starred: true },
{ id: 10, type: "file", name: "Member Directory.csv", groupId: 4, modifiedAt: ago(7), size: "88 KB", sharedWith: ["Priya Anand", "Marcus Webb", "Sarah McIntyre"], activeEditors: [], ownerId: 2, starred: false },
{ id: 11, type: "file", name: "Event Attendance.xlsx", groupId: 3, modifiedAt: ago(10), size: "1.4 MB", sharedWith: [], activeEditors: [], ownerId: 3, starred: false },
// Images
{ id: 12, type: "file", name: "Logo Final.png", groupId: 1, modifiedAt: ago(21), size: "2.1 MB", sharedWith: ["Jordan Kim", "Sarah McIntyre"], activeEditors: [], ownerId: 2, starred: false },
{ id: 13, type: "file", name: "Homepage Hero.jpg", groupId: 3, modifiedAt: ago(4), size: "5.6 MB", sharedWith: ["Sarah McIntyre"], activeEditors: ["Sarah McIntyre"], ownerId: 1, starred: false },
{ id: 14, type: "file", name: "Team Photo 2026.jpg", groupId: 1, modifiedAt: ago(30), size: "8.9 MB", sharedWith: ["Priya Anand", "Marcus Webb", "Jordan Kim"], activeEditors: [], ownerId: 1, starred: true },
// Code / config
{ id: 15, type: "file", name: "api-config.json", groupId: 2, modifiedAt: ago(0), size: "4 KB", sharedWith: ["Marcus Webb"], activeEditors: ["Marcus Webb"], ownerId: 3, starred: false },
// Presentations
{ id: 16, type: "file", name: "Investor Deck May.pptx", groupId: 2, modifiedAt: ago(6), size: "18.4 MB", sharedWith: ["Priya Anand"], activeEditors: [], ownerId: 1, starred: true },
// External shared
{ id: 17, type: "file", name: "Vendor Contract.pdf", groupId: 5, modifiedAt: ago(45), size: "2.2 MB", sharedWith: ["Priya Anand"], activeEditors: [], ownerId: 1, starred: false },
{ id: 18, type: "file", name: "External Proposal.docx", groupId: 5, modifiedAt: ago(8), size: "0.7 MB", sharedWith: [], activeEditors: [], ownerId: 1, starred: false },
]
}
get locationLabel() {
return this.locations.find(l => l.id === this.activeLocation)?.label || "All Files"
}
get visibleFiles() {
let files = this.files;
// Filter by active groups
files = files.filter(f => this.activeGroupIds.has(f.groupId));
// Filter by location
if (this.activeLocation === "mine") files = files.filter(f => f.ownerId === 1);
if (this.activeLocation === "shared") files = files.filter(f => f.sharedWith?.length > 0);
if (this.activeLocation === "starred") files = files.filter(f => f.starred);
if (this.activeLocation === "recent") files = files.sort((a, b) => new Date(b.modifiedAt) - new Date(a.modifiedAt)).slice(0, 10);
// Search
if (this.searchText) {
const q = this.searchText.toLowerCase();
files = files.filter(f => f.name.toLowerCase().includes(q));
}
return files;
}
render() {
HStack(() => {
// Left sidebar
VStack(() => {
DesktopFilesSidebar(
this.groups,
this.activeGroupIds,
(groupId) => {
if (this.activeGroupIds.has(groupId)) {
if (this.activeGroupIds.size > 1) this.activeGroupIds.delete(groupId);
} else {
this.activeGroupIds.add(groupId);
}
this.rerender();
},
this.locations,
this.activeLocation,
(locId) => { this.activeLocation = locId; this.rerender(); }
)
})
.width(220, px)
.minWidth(200, px)
.height(100, pct)
.borderRight("1px solid var(--divider)")
.flexShrink(0)
.overflow("hidden")
// Main area
VStack(() => {
DesktopFilesToolbar(
this.locationLabel,
this.viewMode,
this.searchText,
(mode) => { this.viewMode = mode; this.rerender(); },
(text) => { this.searchText = text; this.rerender(); },
() => {}
)
DesktopFilesGrid(
this.visibleFiles,
this.groups,
this.viewMode,
() => {}
)
.flex(1)
.minHeight(0)
.width(100, pct)
.overflow("hidden")
})
.flex(1)
.height(100, pct)
.overflow("hidden")
})
.height(100, pct)
.width(100, pct)
.overflow("hidden")
}
}
register(Files)