@gallop.software/studio 1.5.10 → 2.0.1
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/app/api/studio/[...path]/route.ts +1 -0
- package/app/layout.tsx +23 -0
- package/app/page.tsx +90 -0
- package/bin/studio.mjs +110 -0
- package/dist/handlers/index.js +77 -55
- package/dist/handlers/index.js.map +1 -1
- package/dist/handlers/index.mjs +128 -106
- package/dist/handlers/index.mjs.map +1 -1
- package/dist/index.d.mts +14 -10
- package/dist/index.d.ts +14 -10
- package/dist/index.js +2 -177
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4 -179
- package/dist/index.mjs.map +1 -1
- package/next.config.mjs +22 -0
- package/package.json +18 -10
- package/src/components/AddNewModal.tsx +402 -0
- package/src/components/ErrorModal.tsx +89 -0
- package/src/components/R2SetupModal.tsx +400 -0
- package/src/components/StudioBreadcrumb.tsx +115 -0
- package/src/components/StudioButton.tsx +200 -0
- package/src/components/StudioContext.tsx +219 -0
- package/src/components/StudioDetailView.tsx +714 -0
- package/src/components/StudioFileGrid.tsx +704 -0
- package/src/components/StudioFileList.tsx +743 -0
- package/src/components/StudioFolderPicker.tsx +342 -0
- package/src/components/StudioModal.tsx +473 -0
- package/src/components/StudioPreview.tsx +399 -0
- package/src/components/StudioSettings.tsx +536 -0
- package/src/components/StudioToolbar.tsx +1448 -0
- package/src/components/StudioUI.tsx +731 -0
- package/src/components/styles/common.ts +236 -0
- package/src/components/tokens.ts +78 -0
- package/src/components/useStudioActions.tsx +497 -0
- package/src/config/index.ts +7 -0
- package/src/config/workspace.ts +52 -0
- package/src/handlers/favicon.ts +152 -0
- package/src/handlers/files.ts +784 -0
- package/src/handlers/images.ts +949 -0
- package/src/handlers/import.ts +190 -0
- package/src/handlers/index.ts +168 -0
- package/src/handlers/list.ts +627 -0
- package/src/handlers/scan.ts +311 -0
- package/src/handlers/utils/cdn.ts +234 -0
- package/src/handlers/utils/files.ts +64 -0
- package/src/handlers/utils/index.ts +4 -0
- package/src/handlers/utils/meta.ts +102 -0
- package/src/handlers/utils/thumbnails.ts +98 -0
- package/src/hooks/useFileList.ts +143 -0
- package/src/index.tsx +36 -0
- package/src/lib/api.ts +176 -0
- package/src/types.ts +119 -0
- package/dist/StudioUI-GJK45R3T.js +0 -6500
- package/dist/StudioUI-GJK45R3T.js.map +0 -1
- package/dist/StudioUI-QZ54STXE.mjs +0 -6500
- package/dist/StudioUI-QZ54STXE.mjs.map +0 -1
- package/dist/chunk-N6JYTJCB.js +0 -68
- package/dist/chunk-N6JYTJCB.js.map +0 -1
- package/dist/chunk-RHI3UROE.mjs +0 -68
- package/dist/chunk-RHI3UROE.mjs.map +0 -1
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext } from 'react'
|
|
4
|
+
import type { FileItem, LeanMeta } from '../types'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Error message type for centralized error handling
|
|
8
|
+
*/
|
|
9
|
+
export interface ErrorMessage {
|
|
10
|
+
title: string
|
|
11
|
+
message: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Progress state for action modals
|
|
16
|
+
*/
|
|
17
|
+
export interface ProgressState {
|
|
18
|
+
current: number
|
|
19
|
+
total: number
|
|
20
|
+
percent: number
|
|
21
|
+
status: 'processing' | 'complete' | 'error' | 'stopped' | 'cleanup'
|
|
22
|
+
currentFile?: string
|
|
23
|
+
message?: string
|
|
24
|
+
processed?: number
|
|
25
|
+
alreadyProcessed?: number
|
|
26
|
+
orphansRemoved?: number
|
|
27
|
+
orphanedFiles?: string[]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Action state for shared action handlers
|
|
32
|
+
*/
|
|
33
|
+
export interface ActionState {
|
|
34
|
+
// Progress modal
|
|
35
|
+
showProgress: boolean
|
|
36
|
+
progressTitle: string
|
|
37
|
+
progressState: ProgressState
|
|
38
|
+
|
|
39
|
+
// Confirmation modals
|
|
40
|
+
showDeleteConfirm: boolean
|
|
41
|
+
showMoveModal: boolean
|
|
42
|
+
showSyncConfirm: boolean
|
|
43
|
+
showProcessConfirm: boolean
|
|
44
|
+
|
|
45
|
+
// Action-specific state
|
|
46
|
+
actionPaths: string[] // Paths being acted upon
|
|
47
|
+
syncImageCount: number
|
|
48
|
+
syncHasRemote: boolean
|
|
49
|
+
syncHasLocal: boolean
|
|
50
|
+
processMode: 'generate' | 'remove' // Mode for process modal
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Studio state interface
|
|
55
|
+
* State is managed by StudioUI and provided to all child components
|
|
56
|
+
*/
|
|
57
|
+
export interface StudioState {
|
|
58
|
+
isOpen: boolean
|
|
59
|
+
openStudio: () => void
|
|
60
|
+
closeStudio: () => void
|
|
61
|
+
toggleStudio: () => void
|
|
62
|
+
|
|
63
|
+
// Navigation
|
|
64
|
+
currentPath: string
|
|
65
|
+
setCurrentPath: (path: string) => void
|
|
66
|
+
navigateUp: () => void
|
|
67
|
+
|
|
68
|
+
// Selection
|
|
69
|
+
selectedItems: Set<string>
|
|
70
|
+
toggleSelection: (path: string) => void
|
|
71
|
+
selectRange: (fromPath: string, toPath: string, allItems: FileItem[]) => void
|
|
72
|
+
selectAll: (items: FileItem[]) => void
|
|
73
|
+
clearSelection: () => void
|
|
74
|
+
lastSelectedPath: string | null
|
|
75
|
+
|
|
76
|
+
// View
|
|
77
|
+
viewMode: 'grid' | 'list'
|
|
78
|
+
setViewMode: (mode: 'grid' | 'list') => void
|
|
79
|
+
|
|
80
|
+
// Focused item (for detail view)
|
|
81
|
+
focusedItem: FileItem | null
|
|
82
|
+
setFocusedItem: (item: FileItem | null) => void
|
|
83
|
+
|
|
84
|
+
// Meta
|
|
85
|
+
meta: LeanMeta | null
|
|
86
|
+
setMeta: (meta: LeanMeta) => void
|
|
87
|
+
|
|
88
|
+
// Loading
|
|
89
|
+
isLoading: boolean
|
|
90
|
+
setIsLoading: (loading: boolean) => void
|
|
91
|
+
|
|
92
|
+
// Refresh trigger
|
|
93
|
+
refreshKey: number
|
|
94
|
+
triggerRefresh: () => void
|
|
95
|
+
|
|
96
|
+
// Scan trigger
|
|
97
|
+
scanRequested: boolean
|
|
98
|
+
triggerScan: () => void
|
|
99
|
+
clearScanRequest: () => void
|
|
100
|
+
|
|
101
|
+
// Search
|
|
102
|
+
searchQuery: string
|
|
103
|
+
setSearchQuery: (query: string) => void
|
|
104
|
+
|
|
105
|
+
// Error handling
|
|
106
|
+
error: ErrorMessage | null
|
|
107
|
+
showError: (title: string, message: string) => void
|
|
108
|
+
clearError: () => void
|
|
109
|
+
|
|
110
|
+
// File items (for toolbar to check cloud status)
|
|
111
|
+
fileItems: FileItem[]
|
|
112
|
+
setFileItems: (items: FileItem[]) => void
|
|
113
|
+
|
|
114
|
+
// Shared action state
|
|
115
|
+
actionState: ActionState
|
|
116
|
+
|
|
117
|
+
// Shared action handlers (initiate confirmation)
|
|
118
|
+
requestDelete: (paths: string[]) => void
|
|
119
|
+
requestMove: (paths: string[]) => void
|
|
120
|
+
requestSync: (paths: string[], fileItems: FileItem[]) => void
|
|
121
|
+
requestProcess: (paths: string[]) => void
|
|
122
|
+
setProcessMode: (mode: 'generate' | 'remove') => void
|
|
123
|
+
|
|
124
|
+
// Action confirmations (execute action)
|
|
125
|
+
confirmDelete: () => Promise<void>
|
|
126
|
+
confirmMove: (destination: string) => Promise<void>
|
|
127
|
+
confirmSync: () => Promise<void>
|
|
128
|
+
confirmProcess: () => Promise<void>
|
|
129
|
+
|
|
130
|
+
// Cancel/close actions
|
|
131
|
+
cancelAction: () => void
|
|
132
|
+
closeProgress: () => void
|
|
133
|
+
|
|
134
|
+
// Stop processing
|
|
135
|
+
stopProcessing: () => void
|
|
136
|
+
abortController: AbortController | null
|
|
137
|
+
|
|
138
|
+
// Delete orphans (from scan)
|
|
139
|
+
deleteOrphans: () => Promise<void>
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const defaultActionState: ActionState = {
|
|
143
|
+
showProgress: false,
|
|
144
|
+
progressTitle: '',
|
|
145
|
+
progressState: { current: 0, total: 0, percent: 0, status: 'processing' },
|
|
146
|
+
showDeleteConfirm: false,
|
|
147
|
+
showMoveModal: false,
|
|
148
|
+
showSyncConfirm: false,
|
|
149
|
+
showProcessConfirm: false,
|
|
150
|
+
actionPaths: [],
|
|
151
|
+
syncImageCount: 0,
|
|
152
|
+
syncHasRemote: false,
|
|
153
|
+
syncHasLocal: false,
|
|
154
|
+
processMode: 'generate',
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const defaultState: StudioState = {
|
|
158
|
+
isOpen: false,
|
|
159
|
+
openStudio: () => {},
|
|
160
|
+
closeStudio: () => {},
|
|
161
|
+
toggleStudio: () => {},
|
|
162
|
+
currentPath: 'public',
|
|
163
|
+
setCurrentPath: () => {},
|
|
164
|
+
navigateUp: () => {},
|
|
165
|
+
selectedItems: new Set(),
|
|
166
|
+
toggleSelection: () => {},
|
|
167
|
+
selectRange: () => {},
|
|
168
|
+
selectAll: () => {},
|
|
169
|
+
clearSelection: () => {},
|
|
170
|
+
lastSelectedPath: null,
|
|
171
|
+
viewMode: 'grid',
|
|
172
|
+
setViewMode: () => {},
|
|
173
|
+
focusedItem: null,
|
|
174
|
+
setFocusedItem: () => {},
|
|
175
|
+
meta: null,
|
|
176
|
+
setMeta: () => {},
|
|
177
|
+
isLoading: false,
|
|
178
|
+
setIsLoading: () => {},
|
|
179
|
+
refreshKey: 0,
|
|
180
|
+
triggerRefresh: () => {},
|
|
181
|
+
scanRequested: false,
|
|
182
|
+
triggerScan: () => {},
|
|
183
|
+
clearScanRequest: () => {},
|
|
184
|
+
searchQuery: '',
|
|
185
|
+
setSearchQuery: () => {},
|
|
186
|
+
error: null,
|
|
187
|
+
showError: () => {},
|
|
188
|
+
clearError: () => {},
|
|
189
|
+
fileItems: [],
|
|
190
|
+
setFileItems: () => {},
|
|
191
|
+
|
|
192
|
+
// Shared action state
|
|
193
|
+
actionState: defaultActionState,
|
|
194
|
+
|
|
195
|
+
// Shared action handlers
|
|
196
|
+
requestDelete: () => {},
|
|
197
|
+
requestMove: () => {},
|
|
198
|
+
requestSync: () => {},
|
|
199
|
+
requestProcess: () => {},
|
|
200
|
+
setProcessMode: () => {},
|
|
201
|
+
confirmDelete: async () => {},
|
|
202
|
+
confirmMove: async () => {},
|
|
203
|
+
confirmSync: async () => {},
|
|
204
|
+
confirmProcess: async () => {},
|
|
205
|
+
cancelAction: () => {},
|
|
206
|
+
closeProgress: () => {},
|
|
207
|
+
stopProcessing: () => {},
|
|
208
|
+
abortController: null,
|
|
209
|
+
deleteOrphans: async () => {},
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export const StudioContext = createContext<StudioState>(defaultState)
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Hook to access Studio state from child components
|
|
216
|
+
*/
|
|
217
|
+
export function useStudio() {
|
|
218
|
+
return useContext(StudioContext)
|
|
219
|
+
}
|