Skip to content

Commit a8dca79

Browse files
authored
Merge pull request #9 from SuperFlyTV/rjmunro/drag-and-drop
Allow drag and drop onto home page
2 parents e90efed + ebaa70c commit a8dca79

2 files changed

Lines changed: 107 additions & 7 deletions

File tree

client/src/scss/styles.scss

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,26 @@ body {
108108
align-items: center;
109109
height: 100vh;
110110

111+
transition: background-color 0.2s ease;
112+
113+
&.dragging {
114+
background-color: rgba(50, 150, 255, 0.1);
115+
outline: 3px dashed rgba(50, 150, 255, 0.6);
116+
outline-offset: -10px;
117+
}
118+
111119
.initial-hero-content {
112120
text-align: center;
113121
color: #fff;
122+
pointer-events: none; // Allow drag events to bubble through
114123
}
115124
a {
116125
color: #bbf;
117126
text-decoration: underline;
127+
pointer-events: all; // Re-enable pointer events for links
128+
}
129+
button {
130+
pointer-events: all; // Re-enable pointer events for buttons
118131
}
119132
}
120133

client/src/views/InitialView.jsx

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,84 @@ import ografLogoUrl from '../assets/ograf_logo_colour_draft.svg'
66
import { serviceWorkerHandler } from '../ServiceWorkerHandler'
77

88
export function InitialView({ onGraphicsFolder }) {
9+
const [isDragging, setIsDragging] = React.useState(false)
10+
const [error, setError] = React.useState(null)
11+
12+
const handleFolderSelect = React.useCallback(
13+
async (dirHandle) => {
14+
try {
15+
fileHandler.dirHandle = dirHandle
16+
onGraphicsFolder({
17+
graphicsList: await fileHandler.listGraphics(),
18+
graphicsFolderName: fileHandler.dirHandle.name,
19+
})
20+
} catch (err) {
21+
console.error(err)
22+
setError(err.message)
23+
}
24+
},
25+
[onGraphicsFolder]
26+
)
27+
28+
const handleDragOver = React.useCallback((e) => {
29+
e.preventDefault()
30+
e.stopPropagation()
31+
setIsDragging(true)
32+
}, [])
33+
34+
const handleDragEnter = React.useCallback((e) => {
35+
e.preventDefault()
36+
e.stopPropagation()
37+
setIsDragging(true)
38+
}, [])
39+
40+
const handleDragLeave = React.useCallback((e) => {
41+
e.preventDefault()
42+
e.stopPropagation()
43+
setIsDragging(false)
44+
}, [])
45+
46+
const handleDrop = React.useCallback(
47+
async (e) => {
48+
e.preventDefault()
49+
e.stopPropagation()
50+
setIsDragging(false)
51+
setError(null)
52+
53+
try {
54+
// Get the first item from the drop
55+
const items = e.dataTransfer.items
56+
if (items && items.length > 0) {
57+
const item = items[0]
58+
59+
// Check if the browser supports getAsFileSystemHandle
60+
if (item.getAsFileSystemHandle) {
61+
const handle = await item.getAsFileSystemHandle()
62+
if (handle.kind === 'directory') {
63+
await handleFolderSelect(handle)
64+
} else {
65+
setError('Please drop a folder, not a file')
66+
}
67+
} else {
68+
setError('Drag and drop folders is not supported in this browser. Please use the button instead.')
69+
}
70+
}
71+
} catch (err) {
72+
console.error(err)
73+
setError(err.message || 'Failed to process dropped folder')
74+
}
75+
},
76+
[handleFolderSelect]
77+
)
78+
979
return (
10-
<div className="initial-hero">
80+
<div
81+
className={`initial-hero ${isDragging ? 'dragging' : ''}`}
82+
onDragOver={handleDragOver}
83+
onDragEnter={handleDragEnter}
84+
onDragLeave={handleDragLeave}
85+
onDrop={handleDrop}
86+
>
1187
<div className="initial-hero-content">
1288
<div>
1389
<h1>
@@ -38,19 +114,30 @@ export function InitialView({ onGraphicsFolder }) {
38114
</i>
39115
</p>
40116

41-
<p>Start the DevTool by selecting a folder that contains Ograf Graphics in any of its subfolders.</p>
117+
<p>
118+
Start the DevTool by selecting a folder that contains Ograf Graphics in any of its subfolders.
119+
</p>
120+
<p>
121+
<strong>Drag and drop a folder here</strong> or click the button below:
122+
</p>
123+
{error && (
124+
<div className="alert alert-danger" role="alert">
125+
{error}
126+
</div>
127+
)}
42128
<p>
43129
<Button
44130
onClick={() => {
131+
setError(null)
45132
fileHandler
46133
.init()
47134
.then(async () => {
48-
onGraphicsFolder({
49-
graphicsList: await fileHandler.listGraphics(),
50-
graphicsFolderName: fileHandler.dirHandle.name,
51-
})
135+
await handleFolderSelect(fileHandler.dirHandle)
136+
})
137+
.catch((err) => {
138+
console.error(err)
139+
setError(err.message)
52140
})
53-
.catch(console.error)
54141
}}
55142
>
56143
Select local folder

0 commit comments

Comments
 (0)