@anymux/ui-kit 0.1.0

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.
Files changed (244) hide show
  1. package/dist/ExplorerLayout-CSIJd7N4.js +105 -0
  2. package/dist/ExplorerLayout-CSIJd7N4.js.map +1 -0
  3. package/dist/FileBrowserContext-B6jixa2j.js +11 -0
  4. package/dist/FileBrowserContext-B6jixa2j.js.map +1 -0
  5. package/dist/calendar-DSlrbHoj.js +761 -0
  6. package/dist/calendar-DSlrbHoj.js.map +1 -0
  7. package/dist/calendar.d.ts +3 -0
  8. package/dist/calendar.js +3 -0
  9. package/dist/contacts-DQXTZzHc.js +539 -0
  10. package/dist/contacts-DQXTZzHc.js.map +1 -0
  11. package/dist/contacts.d.ts +3 -0
  12. package/dist/contacts.js +3 -0
  13. package/dist/file-browser-m5atC3kF.js +6755 -0
  14. package/dist/file-browser-m5atC3kF.js.map +1 -0
  15. package/dist/file-browser.d.ts +11 -0
  16. package/dist/file-browser.js +9 -0
  17. package/dist/git-B55e6LL-.js +561 -0
  18. package/dist/git-B55e6LL-.js.map +1 -0
  19. package/dist/git.d.ts +2 -0
  20. package/dist/git.js +3 -0
  21. package/dist/iconMap-V4B8P-Uh.js +206 -0
  22. package/dist/iconMap-V4B8P-Uh.js.map +1 -0
  23. package/dist/icons-CIsIOZXR.js +0 -0
  24. package/dist/icons.d.ts +2 -0
  25. package/dist/icons.js +4 -0
  26. package/dist/index-BNmNIWBL.d.ts +71 -0
  27. package/dist/index-BNmNIWBL.d.ts.map +1 -0
  28. package/dist/index-Bryv_GCG.d.ts +1481 -0
  29. package/dist/index-Bryv_GCG.d.ts.map +1 -0
  30. package/dist/index-CuQIjSXs.d.ts +134 -0
  31. package/dist/index-CuQIjSXs.d.ts.map +1 -0
  32. package/dist/index-DSu19mq0.d.ts +153 -0
  33. package/dist/index-DSu19mq0.d.ts.map +1 -0
  34. package/dist/index-DmsyeHFr.d.ts +149 -0
  35. package/dist/index-DmsyeHFr.d.ts.map +1 -0
  36. package/dist/index-DxnJ8FYM.d.ts +17 -0
  37. package/dist/index-DxnJ8FYM.d.ts.map +1 -0
  38. package/dist/index-DzfY1Tok.d.ts +32 -0
  39. package/dist/index-DzfY1Tok.d.ts.map +1 -0
  40. package/dist/index-Ml_SgiKa.d.ts +1847 -0
  41. package/dist/index-Ml_SgiKa.d.ts.map +1 -0
  42. package/dist/index-kHr9udZD.d.ts +1025 -0
  43. package/dist/index-kHr9udZD.d.ts.map +1 -0
  44. package/dist/index.d.ts +11 -0
  45. package/dist/index.js +15 -0
  46. package/dist/layout-Ca_4r8ka.js +89 -0
  47. package/dist/layout-Ca_4r8ka.js.map +1 -0
  48. package/dist/layout.d.ts +2 -0
  49. package/dist/layout.js +5 -0
  50. package/dist/list-CxfT6hix.js +6831 -0
  51. package/dist/list-CxfT6hix.js.map +1 -0
  52. package/dist/list.d.ts +2 -0
  53. package/dist/list.js +5 -0
  54. package/dist/media-DZ292aKK.js +557 -0
  55. package/dist/media-DZ292aKK.js.map +1 -0
  56. package/dist/media.d.ts +3 -0
  57. package/dist/media.js +3 -0
  58. package/dist/tree-Dd9Z0Aso.js +3351 -0
  59. package/dist/tree-Dd9Z0Aso.js.map +1 -0
  60. package/dist/tree.d.ts +2 -0
  61. package/dist/tree.js +6 -0
  62. package/dist/types-common-CB3kRek8.d.ts +26 -0
  63. package/dist/types-common-CB3kRek8.d.ts.map +1 -0
  64. package/dist/utils-B4fdKKsy.js +3 -0
  65. package/package.json +109 -0
  66. package/src/calendar/AgendaView.tsx +37 -0
  67. package/src/calendar/CalendarBrowser.tsx +90 -0
  68. package/src/calendar/CalendarModel.ts +142 -0
  69. package/src/calendar/CalendarSidebar.tsx +81 -0
  70. package/src/calendar/DayView.tsx +76 -0
  71. package/src/calendar/EventCard.tsx +51 -0
  72. package/src/calendar/MockCalendarProvider.ts +98 -0
  73. package/src/calendar/MonthView.tsx +77 -0
  74. package/src/calendar/WeekView.tsx +129 -0
  75. package/src/calendar/index.ts +18 -0
  76. package/src/calendar/types.ts +25 -0
  77. package/src/contacts/ContactAvatar.tsx +35 -0
  78. package/src/contacts/ContactBrowser.tsx +56 -0
  79. package/src/contacts/ContactCard.tsx +37 -0
  80. package/src/contacts/ContactDetail.tsx +63 -0
  81. package/src/contacts/ContactGroupSidebar.tsx +40 -0
  82. package/src/contacts/ContactList.tsx +32 -0
  83. package/src/contacts/ContactListModel.ts +120 -0
  84. package/src/contacts/MockContactProvider.ts +77 -0
  85. package/src/contacts/index.ts +17 -0
  86. package/src/contacts/types.ts +26 -0
  87. package/src/demos/CalendarBrowserDemo.tsx +15 -0
  88. package/src/demos/ContactBrowserDemo.tsx +15 -0
  89. package/src/demos/MediaBrowserDemo.tsx +15 -0
  90. package/src/file-browser/adapters/DocumentViewerAdapter.ts +371 -0
  91. package/src/file-browser/adapters/FileSystemBridge.ts +168 -0
  92. package/src/file-browser/adapters/GitBrowserAdapter.ts +546 -0
  93. package/src/file-browser/adapters/README.md +504 -0
  94. package/src/file-browser/adapters/index.ts +27 -0
  95. package/src/file-browser/adapters/types.ts +70 -0
  96. package/src/file-browser/architecture.md +645 -0
  97. package/src/file-browser/components/CreateItemDialog.tsx +71 -0
  98. package/src/file-browser/components/DeleteConfirmDialog.tsx +58 -0
  99. package/src/file-browser/components/FileBrowser.tsx +473 -0
  100. package/src/file-browser/components/FileBrowserContent.tsx +209 -0
  101. package/src/file-browser/components/FileBrowserHeader.tsx +151 -0
  102. package/src/file-browser/components/FileBrowserToolbar.tsx +145 -0
  103. package/src/file-browser/components/LeftPanel/LeftPanel.tsx +103 -0
  104. package/src/file-browser/components/LeftPanel/LeftPanelTabs.tsx +70 -0
  105. package/src/file-browser/components/LeftPanel/TreeNavigationView.tsx +256 -0
  106. package/src/file-browser/components/PreviewPane.tsx +146 -0
  107. package/src/file-browser/components/RightPanel/FilePreview.tsx +219 -0
  108. package/src/file-browser/components/RightPanel/RightPanel.tsx +186 -0
  109. package/src/file-browser/components/RightPanel/RightPanelToolbar.tsx +113 -0
  110. package/src/file-browser/components/UploadProgress.tsx +123 -0
  111. package/src/file-browser/components/ViewerHost.tsx +208 -0
  112. package/src/file-browser/components/mobile/MobileNavigation.tsx +227 -0
  113. package/src/file-browser/components/navigation/NavigationButtons.tsx +171 -0
  114. package/src/file-browser/components/shared/ErrorBoundary.tsx +116 -0
  115. package/src/file-browser/components/shared/FileBrowserItem.tsx +195 -0
  116. package/src/file-browser/components/shared/FileIcon.tsx +169 -0
  117. package/src/file-browser/components/toolbar/ViewModeToggle.tsx +200 -0
  118. package/src/file-browser/components/views/ListView/ListView.tsx +484 -0
  119. package/src/file-browser/components/views/ThumbnailView/ThumbnailView.tsx +323 -0
  120. package/src/file-browser/components/views/TreeView/TreeNode.tsx +186 -0
  121. package/src/file-browser/components/views/TreeView/TreeNodeList.tsx +191 -0
  122. package/src/file-browser/components/views/TreeView/TreeView.tsx +200 -0
  123. package/src/file-browser/components/views/TreemapView/TreemapView.tsx +339 -0
  124. package/src/file-browser/context/FileBrowserContext.tsx +13 -0
  125. package/src/file-browser/examples/BasicUsage.tsx +20 -0
  126. package/src/file-browser/index.ts +98 -0
  127. package/src/file-browser/models/FileBrowserModel.ts +623 -0
  128. package/src/file-browser/models/LeftPanelManagerModel.ts +105 -0
  129. package/src/file-browser/models/NavigationManagerModel.ts +312 -0
  130. package/src/file-browser/models/ResponsiveLayoutManagerModel.ts +437 -0
  131. package/src/file-browser/models/RightPanelManagerModel.ts +190 -0
  132. package/src/file-browser/models/SelectionManagerModel.ts +252 -0
  133. package/src/file-browser/models/ToolbarManagerModel.ts +144 -0
  134. package/src/file-browser/models/UploadModel.ts +147 -0
  135. package/src/file-browser/models/ViewModeManagerModel.ts +185 -0
  136. package/src/file-browser/models/ViewerHostModel.ts +44 -0
  137. package/src/file-browser/models/ui/ListViewUIModel.ts +265 -0
  138. package/src/file-browser/models/ui/PreviewUIModel.ts +297 -0
  139. package/src/file-browser/models/ui/ThumbnailViewUIModel.ts +254 -0
  140. package/src/file-browser/models/ui/TreeViewUIModel.ts +128 -0
  141. package/src/file-browser/models/ui/TreemapViewUIModel.ts +350 -0
  142. package/src/file-browser/providers/FileSystemListProvider.ts +552 -0
  143. package/src/file-browser/providers/FileSystemProvider.ts +401 -0
  144. package/src/file-browser/providers/FileSystemTreeProvider.ts +231 -0
  145. package/src/file-browser/providers/GitProvider.ts +337 -0
  146. package/src/file-browser/providers/GitRepositoryProvider.ts +376 -0
  147. package/src/file-browser/providers/IFileBrowserProvider.ts +56 -0
  148. package/src/file-browser/providers/MemoryProvider.ts +303 -0
  149. package/src/file-browser/providers/index.ts +4 -0
  150. package/src/file-browser/registry/ViewerRegistry.ts +551 -0
  151. package/src/file-browser/registry/types.ts +144 -0
  152. package/src/file-browser/scripts/performanceBenchmark.ts +553 -0
  153. package/src/file-browser/services/ThumbnailCacheService.ts +128 -0
  154. package/src/file-browser/tasks.md +537 -0
  155. package/src/file-browser/types/FileBrowserTypes.ts +126 -0
  156. package/src/file-browser/types/ProviderTypes.ts +155 -0
  157. package/src/file-browser/types/UITypes.ts +235 -0
  158. package/src/file-browser/types/ViewModeTypes.ts +150 -0
  159. package/src/file-browser/utils/gestures.ts +327 -0
  160. package/src/file-browser/utils/performance.ts +563 -0
  161. package/src/file-browser/viewers/ImageViewer.tsx +163 -0
  162. package/src/file-browser/viewers/ImageViewerModel.ts +79 -0
  163. package/src/file-browser/viewers/TextViewer.tsx +95 -0
  164. package/src/file-browser/viewers/UnsupportedFileViewer.tsx +57 -0
  165. package/src/file-browser/viewers/index.ts +61 -0
  166. package/src/git/BranchList.tsx +128 -0
  167. package/src/git/CommitGraph.tsx +239 -0
  168. package/src/git/CommitList.tsx +258 -0
  169. package/src/git/DiffViewer.tsx +219 -0
  170. package/src/git/index.ts +4 -0
  171. package/src/icons/iconMap.ts +146 -0
  172. package/src/icons/index.ts +9 -0
  173. package/src/index.ts +13 -0
  174. package/src/layout/README.md +307 -0
  175. package/src/layout/components/ExplorerLayout/ExplorerLayout.tsx +178 -0
  176. package/src/layout/examples/SimpleExample.tsx +60 -0
  177. package/src/layout/index.ts +6 -0
  178. package/src/lib/utils.ts +1 -0
  179. package/src/list/README.md +303 -0
  180. package/src/list/architecture.md +807 -0
  181. package/src/list/components/CalculatedGridView.tsx +252 -0
  182. package/src/list/components/DragPreview.tsx +102 -0
  183. package/src/list/components/ListContextMenu.tsx +274 -0
  184. package/src/list/components/ListItem.tsx +761 -0
  185. package/src/list/components/ListItems.tsx +919 -0
  186. package/src/list/components/MasonryView.tsx +241 -0
  187. package/src/list/components/SearchFilter.tsx +44 -0
  188. package/src/list/components/TreemapView.tsx +709 -0
  189. package/src/list/components/ViewSizeControls.tsx +205 -0
  190. package/src/list/components/ViewTypeSelector.tsx +312 -0
  191. package/src/list/components/VirtualizedDetailsView.tsx +231 -0
  192. package/src/list/components/VirtualizedGrid.tsx +164 -0
  193. package/src/list/components/VirtualizedList.tsx +154 -0
  194. package/src/list/components/VirtualizedMasonryView.tsx +344 -0
  195. package/src/list/components/shared/EmptyState.tsx +103 -0
  196. package/src/list/components/shared/ErrorBoundary.tsx +123 -0
  197. package/src/list/components/shared/ErrorDisplay.tsx +100 -0
  198. package/src/list/components/shared/ListLoader.tsx +146 -0
  199. package/src/list/components/shared/LoadingIndicator.tsx +80 -0
  200. package/src/list/index.ts +92 -0
  201. package/src/list/models/ListItemsModel.ts +1301 -0
  202. package/src/list/models/TreemapModel.ts +204 -0
  203. package/src/list/providers/ListItemsProvider.ts +313 -0
  204. package/src/list/providers/TestListProvider.ts +604 -0
  205. package/src/list/tasks.md +937 -0
  206. package/src/list/types/ListTypes.ts +178 -0
  207. package/src/list/utils/BenchmarkLogger.ts +243 -0
  208. package/src/list/utils/DragDropManager.ts +320 -0
  209. package/src/list/utils/GridLayoutCalculator.ts +290 -0
  210. package/src/list/utils/ListAccessibility.ts +367 -0
  211. package/src/list/utils/ListKeyboard.ts +414 -0
  212. package/src/list/utils/MasonryLayoutCalculator.ts +302 -0
  213. package/src/list/utils/MasonryLayoutEngine.ts +401 -0
  214. package/src/list/utils/__tests__/MasonryLayoutEngine.test.ts +157 -0
  215. package/src/list/utils/__tests__/VirtualizedMasonryView.test.tsx +251 -0
  216. package/src/media/AlbumSidebar.tsx +48 -0
  217. package/src/media/MediaBrowser.tsx +92 -0
  218. package/src/media/MediaBrowserModel.ts +138 -0
  219. package/src/media/MediaGrid.tsx +50 -0
  220. package/src/media/MediaList.tsx +49 -0
  221. package/src/media/MediaPreview.tsx +63 -0
  222. package/src/media/MediaTimeline.tsx +38 -0
  223. package/src/media/MockMediaProvider.ts +70 -0
  224. package/src/media/index.ts +18 -0
  225. package/src/media/types.ts +21 -0
  226. package/src/styles/variables.css +60 -0
  227. package/src/tree/DEVELOPMENT_SUMMARY.md +170 -0
  228. package/src/tree/__tests__/TreeModel.test.ts +16 -0
  229. package/src/tree/architecture.md +530 -0
  230. package/src/tree/components/Tree.tsx +283 -0
  231. package/src/tree/components/TreeCheckbox.tsx +147 -0
  232. package/src/tree/components/TreeContextMenu.tsx +139 -0
  233. package/src/tree/components/TreeNodeList.tsx +329 -0
  234. package/src/tree/components/TreeTable.tsx +382 -0
  235. package/src/tree/index.ts +58 -0
  236. package/src/tree/models/TreeModel.ts +839 -0
  237. package/src/tree/providers/SimpleTreeProvider.ts +463 -0
  238. package/src/tree/providers/TestTreeProvider.ts +946 -0
  239. package/src/tree/providers/TreeProvider.ts +308 -0
  240. package/src/tree/tasks.md +2046 -0
  241. package/src/tree/types/TreeTypes.ts +279 -0
  242. package/src/tree/utils/SelectionTheme.ts +150 -0
  243. package/src/tree/utils/logger.ts +203 -0
  244. package/src/types-common.ts +21 -0
package/dist/list.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { AccessibilityConfig, BenchmarkReport, BenchmarkResult, CalculatedGridView$1 as CalculatedGridView, DETAILS_VIEW_TYPE$1 as DETAILS_VIEW_TYPE, EmptyState$1 as EmptyState, ErrorDisplay$1 as ErrorDisplay, FocusManager$1 as FocusManager, GRID_PRESETS$1 as GRID_PRESETS, GRID_VIEW_TYPE$1 as GRID_VIEW_TYPE, GridItemLayout, GridLayoutCalculator$1 as GridLayoutCalculator, GridLayoutConfig, GridLayoutResult, InlineLoading$1 as InlineLoading, ItemAccessibilityConfig, KeyboardNavigationConfig, KeyboardNavigationOptions, LIST_VIEW_TYPE$1 as LIST_VIEW_TYPE, ListContextMenu$1 as ListContextMenu, ListContextMenuItem, ListDragDropInfo, ListError, ListErrorBoundary$1 as ListErrorBoundary, ListItem$1 as ListItem, ListItemData, ListItemProps, ListItemRenderer, ListItems$1 as ListItems, ListItemsModel$1 as ListItemsModel, ListItemsProps, ListItemsProvider, ListKeyboardHandler$1 as ListKeyboardHandler, ListLoadOptions, ListLoadResult, ListLoader$1 as ListLoader, ListSelectionInfo, ListViewType, LoadError$1 as LoadError, LoadingIndicator$1 as LoadingIndicator, LoadingProgress$1 as LoadingProgress, MASONRY_HORIZONTAL_VIEW_TYPE$1 as MASONRY_HORIZONTAL_VIEW_TYPE, MASONRY_PRESETS$1 as MASONRY_PRESETS, MASONRY_VERTICAL_VIEW_TYPE$1 as MASONRY_VERTICAL_VIEW_TYPE, MasonryItemData, MasonryItemLayout, MasonryLayoutCalculator$1 as MasonryLayoutCalculator, MasonryLayoutConfig, MasonryLayoutResult, MasonryView$1 as MasonryView, NetworkError$1 as NetworkError, NoItems$1 as NoItems, NoSearchResults$1 as NoSearchResults, NoSelection$1 as NoSelection, SearchFilter$1 as SearchFilter, TREEMAP_VIEW_TYPE$1 as TREEMAP_VIEW_TYPE, TestListProvider$1 as TestListProvider, ThumbnailSize, TreemapModel$1 as TreemapModel, TreemapNodeData, TreemapScanProgress, TreemapView$1 as TreemapView, ViewSizeControls$1 as ViewSizeControls, ViewTypeSelector$1 as ViewTypeSelector, ViewTypeSelectorProps, VirtualizationConfig, VirtualizedGrid$1 as VirtualizedGrid, VirtualizedGridProps, VirtualizedList$1 as VirtualizedList, VirtualizedListProps, announceToScreenReader$1 as announceToScreenReader, benchmark$1 as benchmark, benchmarkLogger$1 as benchmarkLogger, createGridCalculator$1 as createGridCalculator, createLiveRegionAnnouncement$1 as createLiveRegionAnnouncement, createMasonryCalculator$1 as createMasonryCalculator, getItemAccessibilityProps$1 as getItemAccessibilityProps, getListAccessibilityProps$1 as getListAccessibilityProps, getNextFocusIndex$1 as getNextFocusIndex, useListKeyboard$1 as useListKeyboard } from "./index-Bryv_GCG.js";
2
+ export { AccessibilityConfig, BenchmarkReport, BenchmarkResult, CalculatedGridView, DETAILS_VIEW_TYPE, EmptyState, ErrorDisplay, FocusManager, GRID_PRESETS, GRID_VIEW_TYPE, GridItemLayout, GridLayoutCalculator, GridLayoutConfig, GridLayoutResult, InlineLoading, ItemAccessibilityConfig, KeyboardNavigationConfig, KeyboardNavigationOptions, LIST_VIEW_TYPE, ListContextMenu, ListContextMenuItem, ListDragDropInfo, ListError, ListErrorBoundary, ListItem, ListItemData, ListItemProps, ListItemRenderer, ListItems, ListItemsModel, ListItemsProps, ListItemsProvider, ListKeyboardHandler, ListLoadOptions, ListLoadResult, ListLoader, ListSelectionInfo, ListViewType, LoadError, LoadingIndicator, LoadingProgress, MASONRY_HORIZONTAL_VIEW_TYPE, MASONRY_PRESETS, MASONRY_VERTICAL_VIEW_TYPE, MasonryItemData, MasonryItemLayout, MasonryLayoutCalculator, MasonryLayoutConfig, MasonryLayoutResult, MasonryView, NetworkError, NoItems, NoSearchResults, NoSelection, SearchFilter, TREEMAP_VIEW_TYPE, TestListProvider, ThumbnailSize, TreemapModel, TreemapNodeData, TreemapScanProgress, TreemapView, ViewSizeControls, ViewTypeSelector, ViewTypeSelectorProps, VirtualizationConfig, VirtualizedGrid, VirtualizedGridProps, VirtualizedList, VirtualizedListProps, announceToScreenReader, benchmark, benchmarkLogger, createGridCalculator, createLiveRegionAnnouncement, createMasonryCalculator, getItemAccessibilityProps, getListAccessibilityProps, getNextFocusIndex, useListKeyboard };
package/dist/list.js ADDED
@@ -0,0 +1,5 @@
1
+ import "./iconMap-V4B8P-Uh.js";
2
+ import "./FileBrowserContext-B6jixa2j.js";
3
+ import { CalculatedGridView, DETAILS_VIEW_TYPE, EmptyState, ErrorDisplay, FocusManager, GRID_PRESETS, GRID_VIEW_TYPE, GridLayoutCalculator, InlineLoading, LIST_VIEW_TYPE, ListContextMenu, ListErrorBoundary, ListItem, ListItems, ListItemsModel, ListKeyboardHandler, ListLoader, LoadError, LoadingIndicator, LoadingProgress, MASONRY_HORIZONTAL_VIEW_TYPE, MASONRY_PRESETS, MASONRY_VERTICAL_VIEW_TYPE, MasonryLayoutCalculator, MasonryView, NetworkError, NoItems, NoSearchResults, NoSelection, SearchFilter, TREEMAP_VIEW_TYPE, TestListProvider, TreemapModel, TreemapView, ViewSizeControls, ViewTypeSelector, VirtualizedGrid, VirtualizedList, announceToScreenReader, benchmark, benchmarkLogger, createGridCalculator, createLiveRegionAnnouncement, createMasonryCalculator, getItemAccessibilityProps, getListAccessibilityProps, getNextFocusIndex, useListKeyboard } from "./list-CxfT6hix.js";
4
+
5
+ export { CalculatedGridView, DETAILS_VIEW_TYPE, EmptyState, ErrorDisplay, FocusManager, GRID_PRESETS, GRID_VIEW_TYPE, GridLayoutCalculator, InlineLoading, LIST_VIEW_TYPE, ListContextMenu, ListErrorBoundary, ListItem, ListItems, ListItemsModel, ListKeyboardHandler, ListLoader, LoadError, LoadingIndicator, LoadingProgress, MASONRY_HORIZONTAL_VIEW_TYPE, MASONRY_PRESETS, MASONRY_VERTICAL_VIEW_TYPE, MasonryLayoutCalculator, MasonryView, NetworkError, NoItems, NoSearchResults, NoSelection, SearchFilter, TREEMAP_VIEW_TYPE, TestListProvider, TreemapModel, TreemapView, ViewSizeControls, ViewTypeSelector, VirtualizedGrid, VirtualizedList, announceToScreenReader, benchmark, benchmarkLogger, createGridCalculator, createLiveRegionAnnouncement, createMasonryCalculator, getItemAccessibilityProps, getListAccessibilityProps, getNextFocusIndex, useListKeyboard };
@@ -0,0 +1,557 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { observer } from "mobx-react-lite";
3
+ import { ChevronLeft, ChevronRight, Clock, Download, FolderOpen, Grid3X3, Image, List, Loader2, Music, Play, Search, X } from "lucide-react";
4
+ import { BrowserError } from "@anymux/ui/components/browser-error";
5
+ import { makeAutoObservable, runInAction } from "mobx";
6
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+
8
+ //#region src/media/MediaBrowserModel.ts
9
+ var MediaBrowserModel = class {
10
+ constructor(provider) {
11
+ this.provider = provider;
12
+ this.items = [];
13
+ this.selectedItems = new Set();
14
+ this.viewMode = "grid";
15
+ this.currentAlbum = null;
16
+ this.loading = false;
17
+ this.error = null;
18
+ this.searchQuery = "";
19
+ this.sortBy = "date";
20
+ this.filterByType = null;
21
+ this.previewItem = null;
22
+ makeAutoObservable(this);
23
+ }
24
+ get filteredItems() {
25
+ let result = this.items;
26
+ if (this.searchQuery) {
27
+ const q = this.searchQuery.toLowerCase();
28
+ result = result.filter((i) => i.title.toLowerCase().includes(q));
29
+ }
30
+ if (this.filterByType) result = result.filter((i) => i.mediaType === this.filterByType);
31
+ return this.sortItems(result);
32
+ }
33
+ get groupedByDate() {
34
+ const groups = new Map();
35
+ for (const item of this.filteredItems) {
36
+ const key = item.createdAt.toLocaleDateString();
37
+ const group = groups.get(key) ?? [];
38
+ group.push(item);
39
+ groups.set(key, group);
40
+ }
41
+ return groups;
42
+ }
43
+ get groupedByAlbum() {
44
+ const groups = new Map();
45
+ for (const item of this.filteredItems) {
46
+ const key = item.album ?? "Uncategorized";
47
+ const group = groups.get(key) ?? [];
48
+ group.push(item);
49
+ groups.set(key, group);
50
+ }
51
+ return groups;
52
+ }
53
+ async loadItems() {
54
+ this.loading = true;
55
+ this.error = null;
56
+ try {
57
+ const items = this.currentAlbum ? await this.provider.getByAlbum(this.currentAlbum) : await this.provider.listItems();
58
+ runInAction(() => {
59
+ this.items = items;
60
+ });
61
+ } catch (err) {
62
+ runInAction(() => {
63
+ this.error = err?.message || "Failed to load media";
64
+ });
65
+ } finally {
66
+ runInAction(() => {
67
+ this.loading = false;
68
+ });
69
+ }
70
+ }
71
+ selectItem(id) {
72
+ this.selectedItems.clear();
73
+ this.selectedItems.add(id);
74
+ }
75
+ toggleSelect(id) {
76
+ if (this.selectedItems.has(id)) this.selectedItems.delete(id);
77
+ else this.selectedItems.add(id);
78
+ }
79
+ setViewMode(mode) {
80
+ this.viewMode = mode;
81
+ }
82
+ setAlbum(album) {
83
+ this.currentAlbum = album;
84
+ this.loadItems();
85
+ }
86
+ async search(query) {
87
+ this.searchQuery = query;
88
+ if (query) {
89
+ this.loading = true;
90
+ this.error = null;
91
+ try {
92
+ const items = await this.provider.search(query);
93
+ runInAction(() => {
94
+ this.items = items;
95
+ });
96
+ } catch (err) {
97
+ runInAction(() => {
98
+ this.error = err?.message || "Search failed";
99
+ });
100
+ } finally {
101
+ runInAction(() => {
102
+ this.loading = false;
103
+ });
104
+ }
105
+ } else this.loadItems();
106
+ }
107
+ setSort(sortBy) {
108
+ this.sortBy = sortBy;
109
+ }
110
+ setFilter(type) {
111
+ this.filterByType = type;
112
+ }
113
+ openPreview(item) {
114
+ this.previewItem = item;
115
+ }
116
+ closePreview() {
117
+ this.previewItem = null;
118
+ }
119
+ sortItems(items) {
120
+ return [...items].sort((a, b) => {
121
+ switch (this.sortBy) {
122
+ case "date": return b.createdAt.getTime() - a.createdAt.getTime();
123
+ case "name": return a.title.localeCompare(b.title);
124
+ case "size": return (b.width ?? 0) * (b.height ?? 0) - (a.width ?? 0) * (a.height ?? 0);
125
+ default: return 0;
126
+ }
127
+ });
128
+ }
129
+ };
130
+
131
+ //#endregion
132
+ //#region src/media/MediaGrid.tsx
133
+ const MediaThumbnail = ({ item, onClick, selected }) => /* @__PURE__ */ jsxs("button", {
134
+ onClick,
135
+ className: `relative aspect-square rounded-lg overflow-hidden cursor-pointer group border-2 transition-all ${selected ? "border-blue-500 ring-2 ring-blue-200" : "border-transparent hover:border-gray-300"}`,
136
+ children: [
137
+ item.thumbnail || item.mediaType === "photo" ? /* @__PURE__ */ jsx("img", {
138
+ src: item.thumbnail ?? item.url,
139
+ alt: item.title,
140
+ className: "w-full h-full object-cover"
141
+ }) : /* @__PURE__ */ jsx("div", {
142
+ className: "w-full h-full bg-gray-100 flex items-center justify-center",
143
+ children: item.mediaType === "video" ? /* @__PURE__ */ jsx(Play, {
144
+ size: 32,
145
+ className: "text-gray-400"
146
+ }) : /* @__PURE__ */ jsx(Music, {
147
+ size: 32,
148
+ className: "text-gray-400"
149
+ })
150
+ }),
151
+ item.mediaType === "video" && /* @__PURE__ */ jsx("div", {
152
+ className: "absolute bottom-1 right-1 bg-black/70 text-white text-xs px-1.5 py-0.5 rounded",
153
+ children: item.duration ? `${Math.floor(item.duration / 60)}:${String(item.duration % 60).padStart(2, "0")}` : "Video"
154
+ }),
155
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-colors" })
156
+ ]
157
+ });
158
+ const MediaGrid = observer(({ model, className = "" }) => /* @__PURE__ */ jsx("div", {
159
+ className: `grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 gap-1 p-2 ${className}`,
160
+ children: model.filteredItems.map((item) => /* @__PURE__ */ jsx(MediaThumbnail, {
161
+ item,
162
+ selected: model.selectedItems.has(item.id),
163
+ onClick: () => model.openPreview(item)
164
+ }, item.id))
165
+ }));
166
+
167
+ //#endregion
168
+ //#region src/media/MediaList.tsx
169
+ const mediaIcon = (item) => {
170
+ switch (item.mediaType) {
171
+ case "photo": return /* @__PURE__ */ jsx(Image, {
172
+ size: 16,
173
+ className: "text-green-500"
174
+ });
175
+ case "video": return /* @__PURE__ */ jsx(Play, {
176
+ size: 16,
177
+ className: "text-blue-500"
178
+ });
179
+ case "audio": return /* @__PURE__ */ jsx(Music, {
180
+ size: 16,
181
+ className: "text-purple-500"
182
+ });
183
+ }
184
+ };
185
+ const MediaList = observer(({ model, className = "" }) => /* @__PURE__ */ jsx("div", {
186
+ className: `divide-y divide-gray-100 ${className}`,
187
+ children: model.filteredItems.map((item) => /* @__PURE__ */ jsxs("button", {
188
+ onClick: () => model.openPreview(item),
189
+ className: `flex items-center gap-3 px-4 py-3 w-full text-left hover:bg-gray-50 transition-colors ${model.selectedItems.has(item.id) ? "bg-blue-50" : ""}`,
190
+ children: [
191
+ /* @__PURE__ */ jsx("div", {
192
+ className: "w-12 h-12 rounded-lg overflow-hidden flex-shrink-0 bg-gray-100 flex items-center justify-center",
193
+ children: item.thumbnail ? /* @__PURE__ */ jsx("img", {
194
+ src: item.thumbnail,
195
+ alt: item.title,
196
+ className: "w-full h-full object-cover"
197
+ }) : mediaIcon(item)
198
+ }),
199
+ /* @__PURE__ */ jsxs("div", {
200
+ className: "flex-1 min-w-0",
201
+ children: [/* @__PURE__ */ jsx("p", {
202
+ className: "text-sm font-medium text-gray-900 truncate",
203
+ title: item.title,
204
+ children: item.title
205
+ }), /* @__PURE__ */ jsxs("p", {
206
+ className: "text-xs text-gray-500",
207
+ children: [
208
+ item.mediaType,
209
+ " ",
210
+ item.album && `· ${item.album}`,
211
+ " · ",
212
+ item.createdAt.toLocaleDateString()
213
+ ]
214
+ })]
215
+ }),
216
+ /* @__PURE__ */ jsx("div", {
217
+ className: "flex items-center gap-2",
218
+ children: mediaIcon(item)
219
+ })
220
+ ]
221
+ }, item.id))
222
+ }));
223
+
224
+ //#endregion
225
+ //#region src/media/MediaTimeline.tsx
226
+ const TimelineThumbnail = ({ item, onClick }) => /* @__PURE__ */ jsxs("button", {
227
+ onClick,
228
+ className: "relative aspect-square rounded-lg overflow-hidden cursor-pointer group",
229
+ children: [item.thumbnail || item.mediaType === "photo" ? /* @__PURE__ */ jsx("img", {
230
+ src: item.thumbnail ?? item.url,
231
+ alt: item.title,
232
+ className: "w-full h-full object-cover"
233
+ }) : /* @__PURE__ */ jsx("div", {
234
+ className: "w-full h-full bg-gray-100 flex items-center justify-center",
235
+ children: item.mediaType === "video" ? /* @__PURE__ */ jsx(Play, {
236
+ size: 24,
237
+ className: "text-gray-400"
238
+ }) : /* @__PURE__ */ jsx(Music, {
239
+ size: 24,
240
+ className: "text-gray-400"
241
+ })
242
+ }), /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-colors" })]
243
+ });
244
+ const MediaTimeline = observer(({ model, className = "" }) => /* @__PURE__ */ jsx("div", {
245
+ className: `space-y-6 p-4 ${className}`,
246
+ children: Array.from(model.groupedByDate.entries()).map(([date, items]) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", {
247
+ className: "text-sm font-semibold text-gray-700 mb-2 sticky top-0 bg-white/90 backdrop-blur-sm py-1",
248
+ children: date
249
+ }), /* @__PURE__ */ jsx("div", {
250
+ className: "grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-1",
251
+ children: items.map((item) => /* @__PURE__ */ jsx(TimelineThumbnail, {
252
+ item,
253
+ onClick: () => model.openPreview(item)
254
+ }, item.id))
255
+ })] }, date))
256
+ }));
257
+
258
+ //#endregion
259
+ //#region src/media/MediaPreview.tsx
260
+ const MediaPreview = observer(({ model, className = "" }) => {
261
+ const item = model.previewItem;
262
+ if (!item) return null;
263
+ const items = model.filteredItems;
264
+ const idx = items.findIndex((i) => i.id === item.id);
265
+ const goPrev = () => {
266
+ if (idx > 0) model.openPreview(items[idx - 1]);
267
+ };
268
+ const goNext = () => {
269
+ if (idx < items.length - 1) model.openPreview(items[idx + 1]);
270
+ };
271
+ return /* @__PURE__ */ jsxs("div", {
272
+ className: `fixed inset-0 z-50 bg-black/90 flex items-center justify-center ${className}`,
273
+ children: [
274
+ /* @__PURE__ */ jsx("button", {
275
+ onClick: () => model.closePreview(),
276
+ className: "absolute top-4 right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10",
277
+ children: /* @__PURE__ */ jsx(X, { size: 24 })
278
+ }),
279
+ /* @__PURE__ */ jsx("button", {
280
+ onClick: goPrev,
281
+ disabled: idx <= 0,
282
+ className: "absolute left-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 disabled:opacity-30",
283
+ children: /* @__PURE__ */ jsx(ChevronLeft, { size: 32 })
284
+ }),
285
+ /* @__PURE__ */ jsxs("div", {
286
+ className: "max-w-[90vw] max-h-[90vh] flex flex-col items-center",
287
+ children: [
288
+ item.mediaType === "photo" && /* @__PURE__ */ jsx("img", {
289
+ src: item.url,
290
+ alt: item.title,
291
+ className: "max-w-full max-h-[80vh] object-contain rounded-lg"
292
+ }),
293
+ item.mediaType === "video" && /* @__PURE__ */ jsx("video", {
294
+ src: item.url,
295
+ controls: true,
296
+ className: "max-w-full max-h-[80vh] rounded-lg"
297
+ }),
298
+ item.mediaType === "audio" && /* @__PURE__ */ jsxs("div", {
299
+ className: "bg-gray-900 rounded-xl p-8 flex flex-col items-center gap-4",
300
+ children: [/* @__PURE__ */ jsx("div", {
301
+ className: "w-48 h-48 bg-gray-800 rounded-xl flex items-center justify-center text-6xl",
302
+ children: "🎵"
303
+ }), /* @__PURE__ */ jsx("audio", {
304
+ src: item.url,
305
+ controls: true,
306
+ className: "w-80"
307
+ })]
308
+ }),
309
+ /* @__PURE__ */ jsxs("div", {
310
+ className: "mt-4 text-center",
311
+ children: [/* @__PURE__ */ jsx("p", {
312
+ className: "text-white font-medium",
313
+ children: item.title
314
+ }), /* @__PURE__ */ jsx("p", {
315
+ className: "text-white/60 text-sm",
316
+ children: item.createdAt.toLocaleDateString()
317
+ })]
318
+ })
319
+ ]
320
+ }),
321
+ /* @__PURE__ */ jsx("button", {
322
+ onClick: goNext,
323
+ disabled: idx >= items.length - 1,
324
+ className: "absolute right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 disabled:opacity-30",
325
+ children: /* @__PURE__ */ jsx(ChevronRight, { size: 32 })
326
+ }),
327
+ /* @__PURE__ */ jsx("a", {
328
+ href: item.url,
329
+ download: true,
330
+ className: "absolute bottom-4 right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10",
331
+ children: /* @__PURE__ */ jsx(Download, { size: 20 })
332
+ })
333
+ ]
334
+ });
335
+ });
336
+
337
+ //#endregion
338
+ //#region src/media/AlbumSidebar.tsx
339
+ const AlbumSidebar = observer(({ model, provider, className = "" }) => {
340
+ const [albums, setAlbums] = useState([]);
341
+ useEffect(() => {
342
+ provider.getAlbums().then(setAlbums);
343
+ }, [provider]);
344
+ return /* @__PURE__ */ jsx("div", {
345
+ className: `w-56 border-r border-gray-200 bg-gray-50 overflow-y-auto ${className}`,
346
+ children: /* @__PURE__ */ jsxs("div", {
347
+ className: "p-3",
348
+ children: [
349
+ /* @__PURE__ */ jsx("h3", {
350
+ className: "text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2",
351
+ children: "Albums"
352
+ }),
353
+ /* @__PURE__ */ jsxs("button", {
354
+ onClick: () => model.setAlbum(null),
355
+ className: `flex items-center gap-2 w-full px-3 py-2 rounded-lg text-sm transition-colors ${model.currentAlbum === null ? "bg-blue-100 text-blue-700" : "text-gray-700 hover:bg-gray-100"}`,
356
+ children: [/* @__PURE__ */ jsx(Image, { size: 16 }), /* @__PURE__ */ jsx("span", { children: "All Media" })]
357
+ }),
358
+ albums.map((album) => /* @__PURE__ */ jsxs("button", {
359
+ onClick: () => model.setAlbum(album),
360
+ className: `flex items-center gap-2 w-full px-3 py-2 rounded-lg text-sm transition-colors ${model.currentAlbum === album ? "bg-blue-100 text-blue-700" : "text-gray-700 hover:bg-gray-100"}`,
361
+ children: [/* @__PURE__ */ jsx(FolderOpen, { size: 16 }), /* @__PURE__ */ jsx("span", {
362
+ className: "truncate",
363
+ title: album,
364
+ children: album
365
+ })]
366
+ }, album))
367
+ ]
368
+ })
369
+ });
370
+ });
371
+
372
+ //#endregion
373
+ //#region src/media/MediaBrowser.tsx
374
+ const MediaBrowser = observer(({ model, provider, className = "", showSidebar = true }) => {
375
+ useEffect(() => {
376
+ model.loadItems();
377
+ }, [model]);
378
+ return /* @__PURE__ */ jsxs("div", {
379
+ className: `flex h-full bg-white rounded-xl border border-gray-200 overflow-hidden ${className}`,
380
+ children: [
381
+ showSidebar && /* @__PURE__ */ jsx(AlbumSidebar, {
382
+ model,
383
+ provider
384
+ }),
385
+ /* @__PURE__ */ jsxs("div", {
386
+ className: "flex-1 flex flex-col min-w-0",
387
+ children: [/* @__PURE__ */ jsxs("div", {
388
+ className: "flex items-center gap-2 px-4 py-2 border-b border-gray-200",
389
+ children: [
390
+ /* @__PURE__ */ jsxs("div", {
391
+ className: "relative flex-1 max-w-xs",
392
+ children: [/* @__PURE__ */ jsx(Search, {
393
+ size: 16,
394
+ className: "absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"
395
+ }), /* @__PURE__ */ jsx("input", {
396
+ type: "text",
397
+ placeholder: "Search media...",
398
+ value: model.searchQuery,
399
+ onChange: (e) => model.search(e.target.value),
400
+ className: "w-full pl-9 pr-3 py-1.5 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
401
+ })]
402
+ }),
403
+ /* @__PURE__ */ jsx("div", {
404
+ className: "flex items-center border border-gray-200 rounded-lg overflow-hidden",
405
+ children: [
406
+ ["grid", Grid3X3],
407
+ ["list", List],
408
+ ["timeline", Clock]
409
+ ].map(([mode, Icon]) => /* @__PURE__ */ jsx("button", {
410
+ onClick: () => model.setViewMode(mode),
411
+ className: `p-1.5 ${model.viewMode === mode ? "bg-blue-50 text-blue-600" : "text-gray-500 hover:bg-gray-50"}`,
412
+ children: /* @__PURE__ */ jsx(Icon, { size: 16 })
413
+ }, mode))
414
+ }),
415
+ /* @__PURE__ */ jsxs("select", {
416
+ value: model.filterByType ?? "",
417
+ onChange: (e) => model.setFilter(e.target.value || null),
418
+ className: "text-sm border border-gray-200 rounded-lg px-2 py-1.5",
419
+ children: [
420
+ /* @__PURE__ */ jsx("option", {
421
+ value: "",
422
+ children: "All types"
423
+ }),
424
+ /* @__PURE__ */ jsx("option", {
425
+ value: "photo",
426
+ children: "Photos"
427
+ }),
428
+ /* @__PURE__ */ jsx("option", {
429
+ value: "video",
430
+ children: "Videos"
431
+ }),
432
+ /* @__PURE__ */ jsx("option", {
433
+ value: "audio",
434
+ children: "Audio"
435
+ })
436
+ ]
437
+ })
438
+ ]
439
+ }), /* @__PURE__ */ jsx("div", {
440
+ className: "flex-1 overflow-y-auto",
441
+ children: model.loading ? /* @__PURE__ */ jsx("div", {
442
+ className: "flex items-center justify-center h-64",
443
+ children: /* @__PURE__ */ jsx(Loader2, {
444
+ size: 24,
445
+ className: "animate-spin text-gray-400"
446
+ })
447
+ }) : model.error ? /* @__PURE__ */ jsx(BrowserError, {
448
+ error: model.error,
449
+ context: "Media",
450
+ onRetry: () => model.loadItems()
451
+ }) : model.filteredItems.length === 0 ? /* @__PURE__ */ jsx("div", {
452
+ className: "flex items-center justify-center h-64 text-gray-400 text-sm",
453
+ children: "No media found"
454
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [
455
+ model.viewMode === "grid" && /* @__PURE__ */ jsx(MediaGrid, { model }),
456
+ model.viewMode === "list" && /* @__PURE__ */ jsx(MediaList, { model }),
457
+ model.viewMode === "timeline" && /* @__PURE__ */ jsx(MediaTimeline, { model })
458
+ ] })
459
+ })]
460
+ }),
461
+ /* @__PURE__ */ jsx(MediaPreview, { model })
462
+ ]
463
+ });
464
+ });
465
+
466
+ //#endregion
467
+ //#region src/media/MockMediaProvider.ts
468
+ const ALBUMS = [
469
+ "Vacation 2024",
470
+ "Family",
471
+ "Nature",
472
+ "City Lights",
473
+ "Concerts"
474
+ ];
475
+ const MEDIA_TYPES = [
476
+ "photo",
477
+ "video",
478
+ "audio"
479
+ ];
480
+ function generateMediaItems(count = 60) {
481
+ const items = [];
482
+ const now = Date.now();
483
+ for (let i = 0; i < count; i++) {
484
+ const mediaType = MEDIA_TYPES[i % 3];
485
+ const date = new Date(now - i * 864e5 * Math.random() * 30);
486
+ items.push({
487
+ id: `media-${i}`,
488
+ type: "media",
489
+ title: `${mediaType === "photo" ? "IMG" : mediaType === "video" ? "VID" : "AUD"}_${String(i).padStart(4, "0")}`,
490
+ mediaType,
491
+ url: `https://picsum.photos/seed/${i}/800/600`,
492
+ thumbnail: `https://picsum.photos/seed/${i}/200/200`,
493
+ mimeType: mediaType === "photo" ? "image/jpeg" : mediaType === "video" ? "video/mp4" : "audio/mpeg",
494
+ width: mediaType !== "audio" ? 800 + i % 5 * 100 : void 0,
495
+ height: mediaType !== "audio" ? 600 + i % 3 * 100 : void 0,
496
+ duration: mediaType !== "photo" ? 30 + i * 5 : void 0,
497
+ album: ALBUMS[i % ALBUMS.length],
498
+ artist: mediaType === "audio" ? `Artist ${i % 10}` : void 0,
499
+ createdAt: date,
500
+ updatedAt: date,
501
+ tags: [`tag${i % 5}`]
502
+ });
503
+ }
504
+ return items;
505
+ }
506
+ var MockMediaProvider = class {
507
+ constructor() {
508
+ this.items = generateMediaItems();
509
+ }
510
+ async listItems() {
511
+ return this.items;
512
+ }
513
+ async getItem(id) {
514
+ return this.items.find((i) => i.id === id) ?? null;
515
+ }
516
+ async createItem(item) {
517
+ const now = new Date();
518
+ const created = {
519
+ ...item,
520
+ id: `media-${Date.now()}`,
521
+ createdAt: now,
522
+ updatedAt: now
523
+ };
524
+ this.items.push(created);
525
+ return created;
526
+ }
527
+ async updateItem(id, updates) {
528
+ const idx = this.items.findIndex((i) => i.id === id);
529
+ if (idx === -1) throw new Error("Not found");
530
+ this.items[idx] = {
531
+ ...this.items[idx],
532
+ ...updates,
533
+ updatedAt: new Date()
534
+ };
535
+ return this.items[idx];
536
+ }
537
+ async deleteItem(id) {
538
+ this.items = this.items.filter((i) => i.id !== id);
539
+ }
540
+ async search(query) {
541
+ const q = query.toLowerCase();
542
+ return this.items.filter((i) => i.title.toLowerCase().includes(q));
543
+ }
544
+ async getAlbums() {
545
+ return ALBUMS;
546
+ }
547
+ async getByAlbum(album) {
548
+ return this.items.filter((i) => i.album === album);
549
+ }
550
+ async getByDateRange(start, end) {
551
+ return this.items.filter((i) => i.createdAt >= start && i.createdAt <= end);
552
+ }
553
+ };
554
+
555
+ //#endregion
556
+ export { AlbumSidebar, MediaBrowser, MediaBrowserModel, MediaGrid, MediaList, MediaPreview, MediaTimeline, MockMediaProvider };
557
+ //# sourceMappingURL=media-DZ292aKK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-DZ292aKK.js","names":["provider: IMediaProvider","err: any","id: string","mode: MediaViewMode","album: string | null","query: string","sortBy: MediaSortBy","type: MediaType | null","item: MediaItem","items: MediaItem[]","item: MediaItem","MEDIA_TYPES: MediaType[]","items: MediaItem[]","id: string","item: Omit<MediaItem, 'id' | 'createdAt' | 'updatedAt'>","created: MediaItem","updates: Partial<MediaItem>","query: string","album: string","start: Date","end: Date"],"sources":["../src/media/MediaBrowserModel.ts","../src/media/MediaGrid.tsx","../src/media/MediaList.tsx","../src/media/MediaTimeline.tsx","../src/media/MediaPreview.tsx","../src/media/AlbumSidebar.tsx","../src/media/MediaBrowser.tsx","../src/media/MockMediaProvider.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx';\nimport type { IMediaProvider, MediaItem, MediaType } from './types';\n\nexport type MediaViewMode = 'grid' | 'list' | 'timeline';\nexport type MediaSortBy = 'date' | 'name' | 'size';\n\nexport class MediaBrowserModel {\n items: MediaItem[] = [];\n selectedItems = new Set<string>();\n viewMode: MediaViewMode = 'grid';\n currentAlbum: string | null = null;\n loading = false;\n error: string | null = null;\n searchQuery = '';\n sortBy: MediaSortBy = 'date';\n filterByType: MediaType | null = null;\n previewItem: MediaItem | null = null;\n\n constructor(private provider: IMediaProvider) {\n makeAutoObservable(this);\n }\n\n get filteredItems(): MediaItem[] {\n let result = this.items;\n if (this.searchQuery) {\n const q = this.searchQuery.toLowerCase();\n result = result.filter(i => i.title.toLowerCase().includes(q));\n }\n if (this.filterByType) {\n result = result.filter(i => i.mediaType === this.filterByType);\n }\n return this.sortItems(result);\n }\n\n get groupedByDate(): Map<string, MediaItem[]> {\n const groups = new Map<string, MediaItem[]>();\n for (const item of this.filteredItems) {\n const key = item.createdAt.toLocaleDateString();\n const group = groups.get(key) ?? [];\n group.push(item);\n groups.set(key, group);\n }\n return groups;\n }\n\n get groupedByAlbum(): Map<string, MediaItem[]> {\n const groups = new Map<string, MediaItem[]>();\n for (const item of this.filteredItems) {\n const key = item.album ?? 'Uncategorized';\n const group = groups.get(key) ?? [];\n group.push(item);\n groups.set(key, group);\n }\n return groups;\n }\n\n async loadItems() {\n this.loading = true;\n this.error = null;\n try {\n const items = this.currentAlbum\n ? await this.provider.getByAlbum(this.currentAlbum)\n : await this.provider.listItems();\n runInAction(() => { this.items = items; });\n } catch (err: any) {\n runInAction(() => { this.error = err?.message || 'Failed to load media'; });\n } finally {\n runInAction(() => { this.loading = false; });\n }\n }\n\n selectItem(id: string) {\n this.selectedItems.clear();\n this.selectedItems.add(id);\n }\n\n toggleSelect(id: string) {\n if (this.selectedItems.has(id)) {\n this.selectedItems.delete(id);\n } else {\n this.selectedItems.add(id);\n }\n }\n\n setViewMode(mode: MediaViewMode) {\n this.viewMode = mode;\n }\n\n setAlbum(album: string | null) {\n this.currentAlbum = album;\n this.loadItems();\n }\n\n async search(query: string) {\n this.searchQuery = query;\n if (query) {\n this.loading = true;\n this.error = null;\n try {\n const items = await this.provider.search(query);\n runInAction(() => { this.items = items; });\n } catch (err: any) {\n runInAction(() => { this.error = err?.message || 'Search failed'; });\n } finally {\n runInAction(() => { this.loading = false; });\n }\n } else {\n this.loadItems();\n }\n }\n\n setSort(sortBy: MediaSortBy) {\n this.sortBy = sortBy;\n }\n\n setFilter(type: MediaType | null) {\n this.filterByType = type;\n }\n\n openPreview(item: MediaItem) {\n this.previewItem = item;\n }\n\n closePreview() {\n this.previewItem = null;\n }\n\n private sortItems(items: MediaItem[]): MediaItem[] {\n return [...items].sort((a, b) => {\n switch (this.sortBy) {\n case 'date': return b.createdAt.getTime() - a.createdAt.getTime();\n case 'name': return a.title.localeCompare(b.title);\n case 'size': return (b.width ?? 0) * (b.height ?? 0) - (a.width ?? 0) * (a.height ?? 0);\n default: return 0;\n }\n });\n }\n}\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { Play, Music } from 'lucide-react';\nimport type { MediaBrowserModel } from './MediaBrowserModel';\nimport type { MediaItem } from './types';\n\nexport interface MediaGridProps {\n model: MediaBrowserModel;\n className?: string;\n}\n\nconst MediaThumbnail = ({ item, onClick, selected }: { item: MediaItem; onClick: () => void; selected: boolean }) => (\n <button\n onClick={onClick}\n className={`relative aspect-square rounded-lg overflow-hidden cursor-pointer group border-2 transition-all ${\n selected ? 'border-blue-500 ring-2 ring-blue-200' : 'border-transparent hover:border-gray-300'\n }`}\n >\n {item.thumbnail || item.mediaType === 'photo' ? (\n <img\n src={item.thumbnail ?? item.url}\n alt={item.title}\n className=\"w-full h-full object-cover\"\n />\n ) : (\n <div className=\"w-full h-full bg-gray-100 flex items-center justify-center\">\n {item.mediaType === 'video' ? <Play size={32} className=\"text-gray-400\" /> : <Music size={32} className=\"text-gray-400\" />}\n </div>\n )}\n {item.mediaType === 'video' && (\n <div className=\"absolute bottom-1 right-1 bg-black/70 text-white text-xs px-1.5 py-0.5 rounded\">\n {item.duration ? `${Math.floor(item.duration / 60)}:${String(item.duration % 60).padStart(2, '0')}` : 'Video'}\n </div>\n )}\n <div className=\"absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-colors\" />\n </button>\n);\n\nexport const MediaGrid = observer<MediaGridProps>(({ model, className = '' }) => (\n <div className={`grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 gap-1 p-2 ${className}`}>\n {model.filteredItems.map(item => (\n <MediaThumbnail\n key={item.id}\n item={item}\n selected={model.selectedItems.has(item.id)}\n onClick={() => model.openPreview(item)}\n />\n ))}\n </div>\n));\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { Image, Play, Music } from 'lucide-react';\nimport type { MediaBrowserModel } from './MediaBrowserModel';\nimport type { MediaItem } from './types';\n\nexport interface MediaListProps {\n model: MediaBrowserModel;\n className?: string;\n}\n\nconst mediaIcon = (item: MediaItem) => {\n switch (item.mediaType) {\n case 'photo': return <Image size={16} className=\"text-green-500\" />;\n case 'video': return <Play size={16} className=\"text-blue-500\" />;\n case 'audio': return <Music size={16} className=\"text-purple-500\" />;\n }\n};\n\nexport const MediaList = observer<MediaListProps>(({ model, className = '' }) => (\n <div className={`divide-y divide-gray-100 ${className}`}>\n {model.filteredItems.map(item => (\n <button\n key={item.id}\n onClick={() => model.openPreview(item)}\n className={`flex items-center gap-3 px-4 py-3 w-full text-left hover:bg-gray-50 transition-colors ${\n model.selectedItems.has(item.id) ? 'bg-blue-50' : ''\n }`}\n >\n <div className=\"w-12 h-12 rounded-lg overflow-hidden flex-shrink-0 bg-gray-100 flex items-center justify-center\">\n {item.thumbnail ? (\n <img src={item.thumbnail} alt={item.title} className=\"w-full h-full object-cover\" />\n ) : (\n mediaIcon(item)\n )}\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-gray-900 truncate\" title={item.title}>{item.title}</p>\n <p className=\"text-xs text-gray-500\">\n {item.mediaType} {item.album && `· ${item.album}`} · {item.createdAt.toLocaleDateString()}\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n {mediaIcon(item)}\n </div>\n </button>\n ))}\n </div>\n));\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { Play, Music } from 'lucide-react';\nimport type { MediaBrowserModel } from './MediaBrowserModel';\nimport type { MediaItem } from './types';\n\nexport interface MediaTimelineProps {\n model: MediaBrowserModel;\n className?: string;\n}\n\nconst TimelineThumbnail = ({ item, onClick }: { item: MediaItem; onClick: () => void }) => (\n <button onClick={onClick} className=\"relative aspect-square rounded-lg overflow-hidden cursor-pointer group\">\n {item.thumbnail || item.mediaType === 'photo' ? (\n <img src={item.thumbnail ?? item.url} alt={item.title} className=\"w-full h-full object-cover\" />\n ) : (\n <div className=\"w-full h-full bg-gray-100 flex items-center justify-center\">\n {item.mediaType === 'video' ? <Play size={24} className=\"text-gray-400\" /> : <Music size={24} className=\"text-gray-400\" />}\n </div>\n )}\n <div className=\"absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-colors\" />\n </button>\n);\n\nexport const MediaTimeline = observer<MediaTimelineProps>(({ model, className = '' }) => (\n <div className={`space-y-6 p-4 ${className}`}>\n {Array.from(model.groupedByDate.entries()).map(([date, items]) => (\n <div key={date}>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2 sticky top-0 bg-white/90 backdrop-blur-sm py-1\">{date}</h3>\n <div className=\"grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-1\">\n {items.map(item => (\n <TimelineThumbnail key={item.id} item={item} onClick={() => model.openPreview(item)} />\n ))}\n </div>\n </div>\n ))}\n </div>\n));\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { X, ChevronLeft, ChevronRight, Download } from 'lucide-react';\nimport type { MediaBrowserModel } from './MediaBrowserModel';\n\nexport interface MediaPreviewProps {\n model: MediaBrowserModel;\n className?: string;\n}\n\nexport const MediaPreview = observer<MediaPreviewProps>(({ model, className = '' }) => {\n const item = model.previewItem;\n if (!item) return null;\n\n const items = model.filteredItems;\n const idx = items.findIndex(i => i.id === item.id);\n\n const goPrev = () => {\n if (idx > 0) model.openPreview(items[idx - 1]);\n };\n const goNext = () => {\n if (idx < items.length - 1) model.openPreview(items[idx + 1]);\n };\n\n return (\n <div className={`fixed inset-0 z-50 bg-black/90 flex items-center justify-center ${className}`}>\n <button onClick={() => model.closePreview()} className=\"absolute top-4 right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10\">\n <X size={24} />\n </button>\n\n <button onClick={goPrev} disabled={idx <= 0} className=\"absolute left-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 disabled:opacity-30\">\n <ChevronLeft size={32} />\n </button>\n\n <div className=\"max-w-[90vw] max-h-[90vh] flex flex-col items-center\">\n {item.mediaType === 'photo' && (\n <img src={item.url} alt={item.title} className=\"max-w-full max-h-[80vh] object-contain rounded-lg\" />\n )}\n {item.mediaType === 'video' && (\n <video src={item.url} controls className=\"max-w-full max-h-[80vh] rounded-lg\" />\n )}\n {item.mediaType === 'audio' && (\n <div className=\"bg-gray-900 rounded-xl p-8 flex flex-col items-center gap-4\">\n <div className=\"w-48 h-48 bg-gray-800 rounded-xl flex items-center justify-center text-6xl\">🎵</div>\n <audio src={item.url} controls className=\"w-80\" />\n </div>\n )}\n <div className=\"mt-4 text-center\">\n <p className=\"text-white font-medium\">{item.title}</p>\n <p className=\"text-white/60 text-sm\">{item.createdAt.toLocaleDateString()}</p>\n </div>\n </div>\n\n <button onClick={goNext} disabled={idx >= items.length - 1} className=\"absolute right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 disabled:opacity-30\">\n <ChevronRight size={32} />\n </button>\n\n <a href={item.url} download className=\"absolute bottom-4 right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10\">\n <Download size={20} />\n </a>\n </div>\n );\n});\n","import React, { useEffect, useState } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { FolderOpen, Image } from 'lucide-react';\nimport type { MediaBrowserModel } from './MediaBrowserModel';\nimport type { IMediaProvider } from './types';\n\nexport interface AlbumSidebarProps {\n model: MediaBrowserModel;\n provider: IMediaProvider;\n className?: string;\n}\n\nexport const AlbumSidebar = observer<AlbumSidebarProps>(({ model, provider, className = '' }) => {\n const [albums, setAlbums] = useState<string[]>([]);\n\n useEffect(() => {\n provider.getAlbums().then(setAlbums);\n }, [provider]);\n\n return (\n <div className={`w-56 border-r border-gray-200 bg-gray-50 overflow-y-auto ${className}`}>\n <div className=\"p-3\">\n <h3 className=\"text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2\">Albums</h3>\n <button\n onClick={() => model.setAlbum(null)}\n className={`flex items-center gap-2 w-full px-3 py-2 rounded-lg text-sm transition-colors ${\n model.currentAlbum === null ? 'bg-blue-100 text-blue-700' : 'text-gray-700 hover:bg-gray-100'\n }`}\n >\n <Image size={16} />\n <span>All Media</span>\n </button>\n {albums.map(album => (\n <button\n key={album}\n onClick={() => model.setAlbum(album)}\n className={`flex items-center gap-2 w-full px-3 py-2 rounded-lg text-sm transition-colors ${\n model.currentAlbum === album ? 'bg-blue-100 text-blue-700' : 'text-gray-700 hover:bg-gray-100'\n }`}\n >\n <FolderOpen size={16} />\n <span className=\"truncate\" title={album}>{album}</span>\n </button>\n ))}\n </div>\n </div>\n );\n});\n","import React, { useEffect } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { Grid3X3, List, Clock, Search, Loader2 } from 'lucide-react';\nimport { BrowserError } from '@anymux/ui/components/browser-error';\nimport type { MediaBrowserModel } from './MediaBrowserModel';\nimport type { IMediaProvider } from './types';\nimport { MediaGrid } from './MediaGrid';\nimport { MediaList } from './MediaList';\nimport { MediaTimeline } from './MediaTimeline';\nimport { MediaPreview } from './MediaPreview';\nimport { AlbumSidebar } from './AlbumSidebar';\n\nexport interface MediaBrowserProps {\n model: MediaBrowserModel;\n provider: IMediaProvider;\n className?: string;\n showSidebar?: boolean;\n}\n\nexport const MediaBrowser = observer<MediaBrowserProps>(({ model, provider, className = '', showSidebar = true }) => {\n useEffect(() => { model.loadItems(); }, [model]);\n\n return (\n <div className={`flex h-full bg-white rounded-xl border border-gray-200 overflow-hidden ${className}`}>\n {showSidebar && <AlbumSidebar model={model} provider={provider} />}\n\n <div className=\"flex-1 flex flex-col min-w-0\">\n {/* Toolbar */}\n <div className=\"flex items-center gap-2 px-4 py-2 border-b border-gray-200\">\n <div className=\"relative flex-1 max-w-xs\">\n <Search size={16} className=\"absolute left-3 top-1/2 -translate-y-1/2 text-gray-400\" />\n <input\n type=\"text\"\n placeholder=\"Search media...\"\n value={model.searchQuery}\n onChange={e => model.search(e.target.value)}\n className=\"w-full pl-9 pr-3 py-1.5 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n </div>\n\n <div className=\"flex items-center border border-gray-200 rounded-lg overflow-hidden\">\n {([['grid', Grid3X3], ['list', List], ['timeline', Clock]] as const).map(([mode, Icon]) => (\n <button\n key={mode}\n onClick={() => model.setViewMode(mode)}\n className={`p-1.5 ${model.viewMode === mode ? 'bg-blue-50 text-blue-600' : 'text-gray-500 hover:bg-gray-50'}`}\n >\n <Icon size={16} />\n </button>\n ))}\n </div>\n\n <select\n value={model.filterByType ?? ''}\n onChange={e => model.setFilter(e.target.value as 'photo' | 'video' | 'audio' || null)}\n className=\"text-sm border border-gray-200 rounded-lg px-2 py-1.5\"\n >\n <option value=\"\">All types</option>\n <option value=\"photo\">Photos</option>\n <option value=\"video\">Videos</option>\n <option value=\"audio\">Audio</option>\n </select>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-y-auto\">\n {model.loading ? (\n <div className=\"flex items-center justify-center h-64\">\n <Loader2 size={24} className=\"animate-spin text-gray-400\" />\n </div>\n ) : model.error ? (\n <BrowserError\n error={model.error}\n context=\"Media\"\n onRetry={() => model.loadItems()}\n />\n ) : model.filteredItems.length === 0 ? (\n <div className=\"flex items-center justify-center h-64 text-gray-400 text-sm\">No media found</div>\n ) : (\n <>\n {model.viewMode === 'grid' && <MediaGrid model={model} />}\n {model.viewMode === 'list' && <MediaList model={model} />}\n {model.viewMode === 'timeline' && <MediaTimeline model={model} />}\n </>\n )}\n </div>\n </div>\n\n <MediaPreview model={model} />\n </div>\n );\n});\n","import type { IMediaProvider, MediaItem, MediaType } from './types';\n\nconst ALBUMS = ['Vacation 2024', 'Family', 'Nature', 'City Lights', 'Concerts'];\nconst MEDIA_TYPES: MediaType[] = ['photo', 'video', 'audio'];\n\nfunction generateMediaItems(count = 60): MediaItem[] {\n const items: MediaItem[] = [];\n const now = Date.now();\n for (let i = 0; i < count; i++) {\n const mediaType = MEDIA_TYPES[i % 3];\n const date = new Date(now - i * 86400000 * Math.random() * 30);\n items.push({\n id: `media-${i}`,\n type: 'media',\n title: `${mediaType === 'photo' ? 'IMG' : mediaType === 'video' ? 'VID' : 'AUD'}_${String(i).padStart(4, '0')}`,\n mediaType,\n url: `https://picsum.photos/seed/${i}/800/600`,\n thumbnail: `https://picsum.photos/seed/${i}/200/200`,\n mimeType: mediaType === 'photo' ? 'image/jpeg' : mediaType === 'video' ? 'video/mp4' : 'audio/mpeg',\n width: mediaType !== 'audio' ? 800 + (i % 5) * 100 : undefined,\n height: mediaType !== 'audio' ? 600 + (i % 3) * 100 : undefined,\n duration: mediaType !== 'photo' ? 30 + i * 5 : undefined,\n album: ALBUMS[i % ALBUMS.length],\n artist: mediaType === 'audio' ? `Artist ${i % 10}` : undefined,\n createdAt: date,\n updatedAt: date,\n tags: [`tag${i % 5}`],\n });\n }\n return items;\n}\n\nexport class MockMediaProvider implements IMediaProvider {\n private items = generateMediaItems();\n\n async listItems() { return this.items; }\n\n async getItem(id: string) { return this.items.find(i => i.id === id) ?? null; }\n\n async createItem(item: Omit<MediaItem, 'id' | 'createdAt' | 'updatedAt'>) {\n const now = new Date();\n const created: MediaItem = { ...item, id: `media-${Date.now()}`, createdAt: now, updatedAt: now } as MediaItem;\n this.items.push(created);\n return created;\n }\n\n async updateItem(id: string, updates: Partial<MediaItem>) {\n const idx = this.items.findIndex(i => i.id === id);\n if (idx === -1) throw new Error('Not found');\n this.items[idx] = { ...this.items[idx], ...updates, updatedAt: new Date() };\n return this.items[idx];\n }\n\n async deleteItem(id: string) {\n this.items = this.items.filter(i => i.id !== id);\n }\n\n async search(query: string) {\n const q = query.toLowerCase();\n return this.items.filter(i => i.title.toLowerCase().includes(q));\n }\n\n async getAlbums() { return ALBUMS; }\n\n async getByAlbum(album: string) { return this.items.filter(i => i.album === album); }\n\n async getByDateRange(start: Date, end: Date) {\n return this.items.filter(i => i.createdAt >= start && i.createdAt <= end);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { IObjectProvider, ObjectMetadata, ObjectType } from "./types-common-CB3kRek8.js";
2
+ import { AlbumSidebar$1 as AlbumSidebar, AlbumSidebarProps, IMediaProvider, MediaBrowser$1 as MediaBrowser, MediaBrowserModel$1 as MediaBrowserModel, MediaBrowserProps, MediaGrid$1 as MediaGrid, MediaGridProps, MediaItem, MediaList$1 as MediaList, MediaListProps, MediaPreview$1 as MediaPreview, MediaPreviewProps, MediaSortBy, MediaTimeline$1 as MediaTimeline, MediaTimelineProps, MediaType, MediaViewMode, MockMediaProvider$1 as MockMediaProvider } from "./index-CuQIjSXs.js";
3
+ export { AlbumSidebar, AlbumSidebarProps, IMediaProvider, IObjectProvider, MediaBrowser, MediaBrowserModel, MediaBrowserProps, MediaGrid, MediaGridProps, MediaItem, MediaList, MediaListProps, MediaPreview, MediaPreviewProps, MediaSortBy, MediaTimeline, MediaTimelineProps, MediaType, MediaViewMode, MockMediaProvider, ObjectMetadata, ObjectType };
package/dist/media.js ADDED
@@ -0,0 +1,3 @@
1
+ import { AlbumSidebar, MediaBrowser, MediaBrowserModel, MediaGrid, MediaList, MediaPreview, MediaTimeline, MockMediaProvider } from "./media-DZ292aKK.js";
2
+
3
+ export { AlbumSidebar, MediaBrowser, MediaBrowserModel, MediaGrid, MediaList, MediaPreview, MediaTimeline, MockMediaProvider };