Allow selecting BMS package without drag-and-drop on mobile devices
dtinth opened this issue · 9 comments
Background
Users on mobile devices (Android) cannot drag BMS packages into Bemuse window, so we should allow users to pick a file on their machine.
Requested by
Task
-
Your PR should change these files,
CustomBMS.jsx
,CustomBMS.scss
andCustomSongsIO.js
. -
Add an option to select a file to the Load Custom BMS modal.
💁♂️ How to reach this modal: Launch Bemuse > Enter Game > Keyboard Mode. Click on Play Custom BMS at the bottom left (desktop) or in the hamburger menu at the top left (mobile)
-
Upon clicking the option, the user will be asked to pick a zip, rar or 7z file. Once a file is selected, it should act as if the file has been dropped into the drop zone.
💁♂️ If you need a zip file for testing, try this one. https://www.dropbox.com/s/hwxjo1l5ibj8bef/BMS_Shuin-422.zip
-
All automated checks should pass.
-
Your solution should work on iOS and Android.
-
Please include a screenshot in your PR to confirm that it is working.
Hacktoberfest
If you would like to work on this task, please write a comment stating your intent. We will then assign the issue to you. To ensure continuity, the issue will be unassigned after 3 days of inactivity — so please keep us updated.
Hey! I would like to work on this issue.
Hey! I seem to have hit a dead end while trying to solve this without changing the existing code.
I tried to add an input:file
element inside the dropzone div that triggers the handleDrop
function when a file is uploaded,
the handleDrop
itself has function calls that need the event to be a dragEvent
and have a dataTransfer
object. I've been trying to create an event with a dataTransfer
object to send the data but after some stumbling, I feel I have found some conclusive evidence that it won't work.
source
It is not possible to create a useful DataTransfer object from script, since DataTransfer objects have a processing and security model that is coordinated by the browser during drag-and-drops.
Therefore synthetic objects wont work because of safety constraints.
@aj-ya Hello, thank you, you are right! Seems like the CustomSongsIO
code has been hard-coded to only accept drop events. This has been a mistake in my assumption, my apologies for the confusion.
What I would recommend trying:
-
Create a new function in
CustomSongsIO.js
based onhandleCustomSongFolderDrop
.- Maybe name it
handleCustomSongFileSelect
. - Then use it in
CustomBMS.jsx
.
- Maybe name it
-
Instead of a
new DndResources(event)
, create an instance ofnew CustomSongResources(…)
directly, e.g.new CustomSongResources({ getFiles: async () => [{ name: file.name, file }] })
You can also change CustomBMS.scss
.
Thanks for the suggestions,will work on that.
Hey! I've been working according to your suggestion,but I cant seem to figure out why my createIO async function doesn't fulfill.
code looks like this.
export function handleCustomSongFileSelect(selectedfile) {
console.log('before')
return createIO(async ({ store, customSongLoader }) => {
console.log('async')
const resources = new CustomSongResources({
getFiles: async () => [ { name: selectedfile.name, file: selectedfile } ],
})
console.log('after')
const initialLog = ['Examining selected items...']
return loadCustomSong(resources, initialLog, { store, customSongLoader })
})
}`
the console prints out only the 'before' .
.
I tried checking the impure docs, but I'm out of ideas. any suggestions?
@aj-ya Sure, happy to help! You cannot call a function directly — its body won’t run. To make it run, you will have to “connect” it to the UI using connectIO
here:
bemuse/bemuse/src/app/ui/CustomBMS.jsx
Lines 24 to 29 in 900f917
Add this:
onFileSelect: () => (event) =>
CustomSongsIO.handleCustomSongFileSelect(event),
Then in the component code, call this.props.onFileSelect
and the IO function inside should be run. Let me know if you need any further help. Thanks again!
Hey! I think I've successfully fixed the issue, please take a look at the PR and the code too.
Also thanks for all the suggestions.