mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 11:18:54 +01:00
internal/ui: more precise detection of directory on browsers
Updates #1868
This commit is contained in:
parent
e03cb0d4df
commit
84e32c2e4e
@ -96,7 +96,8 @@ type userInterfaceImpl struct {
|
|||||||
|
|
||||||
keyboardLayoutMap js.Value
|
keyboardLayoutMap js.Value
|
||||||
|
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
|
dropFileM sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -640,14 +641,44 @@ func setCanvasEventHandlers(v js.Value) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
files := data.Get("files")
|
go theUI.appendDroppedFiles(data)
|
||||||
for i := 0; i < files.Length(); i++ {
|
|
||||||
theUI.inputState.DroppedFiles = append(theUI.inputState.DroppedFiles, &file{v: files.Index(i)})
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *userInterfaceImpl) appendDroppedFiles(data js.Value) {
|
||||||
|
u.dropFileM.Lock()
|
||||||
|
defer u.dropFileM.Unlock()
|
||||||
|
|
||||||
|
chFile := make(chan js.Value, 1)
|
||||||
|
cbFile := js.FuncOf(func(this js.Value, args []js.Value) any {
|
||||||
|
chFile <- args[0]
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
defer cbFile.Release()
|
||||||
|
|
||||||
|
items := data.Get("items")
|
||||||
|
for i := 0; i < items.Length(); i++ {
|
||||||
|
entry := items.Index(i).Call("webkitGetAsEntry")
|
||||||
|
var f fs.File
|
||||||
|
switch {
|
||||||
|
case entry.Get("isFile").Bool():
|
||||||
|
entry.Call("file", cbFile)
|
||||||
|
jsFile := <-chFile
|
||||||
|
f = &file{
|
||||||
|
v: jsFile,
|
||||||
|
}
|
||||||
|
case entry.Get("isDirectory").Bool():
|
||||||
|
f = &dir{
|
||||||
|
entry: entry,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
u.inputState.DroppedFiles = append(u.inputState.DroppedFiles, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (u *userInterfaceImpl) forceUpdateOnMinimumFPSMode() {
|
func (u *userInterfaceImpl) forceUpdateOnMinimumFPSMode() {
|
||||||
if u.fpsMode != FPSModeVsyncOffMinimum {
|
if u.fpsMode != FPSModeVsyncOffMinimum {
|
||||||
return
|
return
|
||||||
@ -780,9 +811,7 @@ func (f *file) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type fileInfo struct {
|
type fileInfo struct {
|
||||||
v js.Value
|
v js.Value
|
||||||
isDir bool
|
|
||||||
isDirOnce sync.Once
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fileInfo) Name() string {
|
func (f *fileInfo) Name() string {
|
||||||
@ -802,31 +831,53 @@ func (f *fileInfo) ModTime() time.Time {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *fileInfo) IsDir() bool {
|
func (f *fileInfo) IsDir() bool {
|
||||||
f.isDirOnce.Do(func() {
|
return false
|
||||||
ch := make(chan struct{})
|
|
||||||
|
|
||||||
cbThen := js.FuncOf(func(this js.Value, args []js.Value) any {
|
|
||||||
close(ch)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
defer cbThen.Release()
|
|
||||||
|
|
||||||
cbCatch := js.FuncOf(func(this js.Value, args []js.Value) any {
|
|
||||||
// This is not a reliable way to check whether the file is a directory or not.
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/File
|
|
||||||
// TODO: Should the file system API be used?
|
|
||||||
f.isDir = true
|
|
||||||
close(ch)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
defer cbCatch.Release()
|
|
||||||
|
|
||||||
f.v.Call("arrayBuffer").Call("then", cbThen).Call("catch", cbCatch)
|
|
||||||
<-ch
|
|
||||||
})
|
|
||||||
return f.isDir
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fileInfo) Sys() any {
|
func (f *fileInfo) Sys() any {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type dir struct {
|
||||||
|
entry js.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dir) Stat() (fs.FileInfo, error) {
|
||||||
|
return &dirInfo{entry: d.entry}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dir) Read(buf []byte) (int, error) {
|
||||||
|
return 0, fmt.Errorf("%s is a directory", d.entry.Get("name").String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dir) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type dirInfo struct {
|
||||||
|
entry js.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dirInfo) Name() string {
|
||||||
|
return d.entry.Get("name").String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dirInfo) Size() int64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dirInfo) Mode() fs.FileMode {
|
||||||
|
return 0400 | fs.ModeDir
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dirInfo) ModTime() time.Time {
|
||||||
|
return time.Time{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dirInfo) IsDir() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dirInfo) Sys() any {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user