Implementing showOpenDialog's web callback (#2608)
* Implementing the open file dialog in web - Adding a new function to make loading files from a dialog box easier in both web and electron * Canceled should always be false onchange is only triggered when the file picker has a file path. If the user cancels, this function is never called. * Changing from `function ()` to `() => {` * Adding a try around processing the history import * Moving the try-catch to a smaller section * Adding a listener to when the file picker is closed * Fixing the grammar on my comment * Refactoring playlist imports to use readFileFromDialog * Refactoring handleFreetubeImportFile to use readFileFromDialog * Refactoring handleYoutubeCsvImportFile to use readFileFromDialog * Refactoring handleYoutubeImportFile to use readFileFromDialog * Refactoring importOpmlYoutubeSubscriptions to use readFileFromDialog * Refactoring importNewPipeSubscriptions to use readFileFromDialog * Added a check to prevent resolve from being called multiple times * Moving the call to removeEventListener to prevent this event from being triggered twice * Adding extensions to the web file picker * Hiding `Check for legacy subscriptions` in web * Adding comments for better readability * Correcting my vue syntax
This commit is contained in:
parent
7822f7423e
commit
1512178489
File diff suppressed because it is too large
Load Diff
|
@ -12,6 +12,7 @@
|
|||
@click="showImportSubscriptionsPrompt = true"
|
||||
/>
|
||||
<ft-button
|
||||
v-if="usingElectron"
|
||||
:label="$t('Settings.Data Settings.Check for Legacy Subscriptions')"
|
||||
@click="checkForLegacySubscriptions"
|
||||
/>
|
||||
|
|
|
@ -395,9 +395,66 @@ const actions = {
|
|||
return (await invokeIRC(context, IpcChannels.GET_SYSTEM_LOCALE, webCbk)) || 'en-US'
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object} response the response from `showOpenDialog`
|
||||
* @param {Number} index which file to read (defaults to the first in the response)
|
||||
* @returns the text contents of the selected file
|
||||
*/
|
||||
async readFileFromDialog(context, { response, index = 0 }) {
|
||||
return await new Promise((resolve, reject) => {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
// if this is Electron, use fs
|
||||
fs.readFile(response.filePaths[index], (err, data) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
resolve(new TextDecoder('utf-8').decode(data))
|
||||
})
|
||||
} else {
|
||||
// if this is web, use FileReader
|
||||
try {
|
||||
const reader = new FileReader()
|
||||
reader.onload = function (file) {
|
||||
resolve(file.currentTarget.result)
|
||||
}
|
||||
reader.readAsText(response.files[index])
|
||||
} catch (exception) {
|
||||
reject(exception)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
async showOpenDialog (context, options) {
|
||||
// TODO: implement showOpenDialog web compatible callback
|
||||
const webCbk = () => null
|
||||
const webCbk = () => {
|
||||
return new Promise((resolve) => {
|
||||
const fileInput = document.createElement('input')
|
||||
fileInput.setAttribute('type', 'file')
|
||||
if (options?.filters[0]?.extensions !== undefined) {
|
||||
// this will map the given extensions from the options to the accept attribute of the input
|
||||
fileInput.setAttribute('accept', options.filters[0].extensions.map((extension) => { return `.${extension}` }).join(', '))
|
||||
}
|
||||
fileInput.onchange = () => {
|
||||
const files = Array.from(fileInput.files)
|
||||
resolve({ canceled: false, files })
|
||||
delete fileInput.onchange
|
||||
}
|
||||
const listenForEnd = () => {
|
||||
window.removeEventListener('focus', listenForEnd)
|
||||
// 1 second timeout on the response from the file picker to prevent awaiting forever
|
||||
setTimeout(() => {
|
||||
if (fileInput.files.length === 0 && typeof fileInput.onchange === 'function') {
|
||||
// if there are no files and the onchange has not been triggered, the file-picker was canceled
|
||||
resolve({ canceled: true })
|
||||
delete fileInput.onchange
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
window.addEventListener('focus', listenForEnd)
|
||||
fileInput.click()
|
||||
})
|
||||
}
|
||||
return await invokeIRC(context, IpcChannels.SHOW_OPEN_DIALOG, webCbk, options)
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in New Issue