mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-18 17:16:00 +00:00
Rename RestoreFiles to GoldenRetriever
This commit is contained in:
parent
f87fe03466
commit
172575fb79
13 changed files with 268 additions and 247 deletions
|
|
@ -26,7 +26,7 @@ const Dashboard = require('uppy/lib/plugins/Dashboard')
|
|||
const Webcam = require('uppy/lib/plugins/Webcam')
|
||||
const GoogleDrive = require('uppy/lib/plugins/GoogleDrive')
|
||||
const Tus10 = require('uppy/lib/plugins/Tus10')
|
||||
|
||||
|
||||
const uppy = Uppy({ autoProceed: false })
|
||||
.use(Dashboard, { trigger: '#select-files' })
|
||||
.use(Webcam, { target: Dashboard })
|
||||
|
|
@ -106,7 +106,7 @@ If you like, you can also use a pre-built bundle, for example from [unpkg CDN](h
|
|||
- `ProgressBar` — minimal progress bar that fills itself when upload progresses
|
||||
- `StatusBar` — more detailed progress, pause/resume/cancel buttons, percentage, speed, uploaded/total sizes (included by default with `Dashboard`)
|
||||
- `Informer` — send notifications like “smile” before taking a selfie or “upload failed” when all is lost (also included by default with `Dashboard`)
|
||||
- `RestoreFiles` — restores files after a browser crash, like it’s nothing
|
||||
- `GoldenRetriever` — restores files after a browser crash, like it’s nothing
|
||||
- `ReduxDevTools` — for your emerging [time traveling](https://github.com/gaearon/redux-devtools) needs
|
||||
- `GoogleDrive` — select files from [Google Drive](https://www.google.com/drive/)
|
||||
- `Dropbox` — select files from [Dropbox](https://www.dropbox.com/)
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
const Uppy = require('../../src/core/Core.js')
|
||||
const Uppy = require('../../src/core')
|
||||
const Dashboard = require('../../src/plugins/Dashboard')
|
||||
// const GoogleDrive = require('../../src/plugins/GoogleDrive')
|
||||
const Dropbox = require('../../src/plugins/Dropbox')
|
||||
const Instagram = require('../../src/plugins/Instagram')
|
||||
// const Webcam = require('../../src/plugins/Webcam')
|
||||
const Tus10 = require('../../src/plugins/Tus10')
|
||||
// const Multipart = require('../../src/plugins/Multipart')
|
||||
// const XHRUpload = require('../../src/plugins/XHRUpload')
|
||||
// const FileInput = require('../../src/plugins/FileInput')
|
||||
const MetaData = require('../../src/plugins/MetaData')
|
||||
// const Informer = require('../../src/plugins/Informer')
|
||||
// const StatusBar = require('../../src/plugins/StatusBar')
|
||||
// const DragDrop = require('../../src/plugins/DragDrop')
|
||||
// const RestoreFiles = require('../../src/plugins/RestoreFiles')
|
||||
// const GoldenRetriever = require('../../src/plugins/GoldenRetriever')
|
||||
|
||||
const PROTOCOL = location.protocol === 'https:' ? 'https' : 'http'
|
||||
const TUS_ENDPOINT = PROTOCOL + '://master.tus.io/files/'
|
||||
|
|
@ -68,7 +68,7 @@ const uppy = Uppy({
|
|||
{ id: 'caption', name: 'Caption', value: 'none', placeholder: 'describe what the image is about' }
|
||||
]
|
||||
})
|
||||
// .use(RestoreFiles, {serviceWorker: true})
|
||||
// .use(GoldenRetriever, {serviceWorker: true})
|
||||
.run()
|
||||
|
||||
uppy.on('core:success', (fileList) => {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
const Uppy = require('uppy/lib/core')
|
||||
const Dashboard = require('uppy/lib/plugins/Dashboard')
|
||||
const RestoreFiles = require('uppy/lib/plugins/RestoreFiles')
|
||||
const GoldenRetriever = require('uppy/lib/plugins/GoldenRetriever')
|
||||
|
||||
// Initialise two Uppy instances with the RestoreFiles plugin,
|
||||
// Initialise two Uppy instances with the GoldenRetriever plugin,
|
||||
// but with different `id`s.
|
||||
const a = Uppy({
|
||||
id: 'a',
|
||||
|
|
@ -13,7 +13,7 @@ const a = Uppy({
|
|||
inline: true,
|
||||
maxWidth: 400
|
||||
})
|
||||
.use(RestoreFiles, { serviceWorker: false })
|
||||
.use(GoldenRetriever, { serviceWorker: false })
|
||||
.run()
|
||||
|
||||
const b = Uppy({
|
||||
|
|
@ -25,7 +25,7 @@ const b = Uppy({
|
|||
inline: true,
|
||||
maxWidth: 400
|
||||
})
|
||||
.use(RestoreFiles, { serviceWorker: false })
|
||||
.use(GoldenRetriever, { serviceWorker: false })
|
||||
.run()
|
||||
|
||||
window.a = a
|
||||
|
|
|
|||
19
src/index.js
19
src/index.js
|
|
@ -30,7 +30,7 @@ const Transloadit = require('./plugins/Transloadit')
|
|||
const AwsS3 = require('./plugins/AwsS3')
|
||||
|
||||
// Other?
|
||||
const RestoreFiles = require('./plugins/RestoreFiles')
|
||||
const GoldenRetriever = require('./plugins/GoldenRetriever')
|
||||
const ReduxDevTools = require('./plugins/ReduxDevTools')
|
||||
const ReduxStore = require('./plugins/Redux')
|
||||
|
||||
|
|
@ -53,7 +53,22 @@ module.exports = {
|
|||
Dashboard,
|
||||
MetaData,
|
||||
Webcam,
|
||||
RestoreFiles,
|
||||
GoldenRetriever,
|
||||
ReduxDevTools,
|
||||
ReduxStore
|
||||
}
|
||||
|
||||
Object.defineProperty(module.exports, 'RestoreFiles', {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: () => {
|
||||
console.warn('Uppy.RestoreFiles is deprecated and will be removed in v0.22. Use Uppy.GoldenRetriever instead.')
|
||||
Object.defineProperty(module.exports, 'RestoreFiles', {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: GoldenRetriever
|
||||
})
|
||||
return GoldenRetriever
|
||||
}
|
||||
})
|
||||
|
|
|
|||
234
src/plugins/GoldenRetriever/index.js
Normal file
234
src/plugins/GoldenRetriever/index.js
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
const Plugin = require('../Plugin')
|
||||
const ServiceWorkerStore = require('./ServiceWorkerStore')
|
||||
const IndexedDBStore = require('./IndexedDBStore')
|
||||
const MetaDataStore = require('./MetaDataStore')
|
||||
|
||||
/**
|
||||
* The Golden Retriever plugin — restores selected files and resumes uploads
|
||||
* after a closed tab or a browser crash!
|
||||
*
|
||||
* Uses localStorage, IndexedDB and ServiceWorker to do its magic, read more:
|
||||
* https://uppy.io/blog/2017/07/golden-retriever/
|
||||
*/
|
||||
module.exports = class GoldenRetriever extends Plugin {
|
||||
constructor (core, opts) {
|
||||
super(core, opts)
|
||||
this.type = 'debugger'
|
||||
this.id = 'GoldenRetriever'
|
||||
this.title = 'Restore Files'
|
||||
|
||||
const defaultOptions = {
|
||||
expires: 24 * 60 * 60 * 1000, // 24 hours
|
||||
serviceWorker: false
|
||||
}
|
||||
|
||||
this.opts = Object.assign({}, defaultOptions, opts)
|
||||
|
||||
this.MetaDataStore = new MetaDataStore({
|
||||
expires: this.opts.expires,
|
||||
storeName: core.getID()
|
||||
})
|
||||
this.ServiceWorkerStore = null
|
||||
if (this.opts.serviceWorker) {
|
||||
this.ServiceWorkerStore = new ServiceWorkerStore({ storeName: core.getID() })
|
||||
}
|
||||
this.IndexedDBStore = new IndexedDBStore(Object.assign(
|
||||
{ expires: this.opts.expires },
|
||||
opts.indexedDB || {},
|
||||
{ storeName: core.getID() }))
|
||||
|
||||
this.saveFilesStateToLocalStorage = this.saveFilesStateToLocalStorage.bind(this)
|
||||
this.loadFilesStateFromLocalStorage = this.loadFilesStateFromLocalStorage.bind(this)
|
||||
this.loadFileBlobsFromServiceWorker = this.loadFileBlobsFromServiceWorker.bind(this)
|
||||
this.loadFileBlobsFromIndexedDB = this.loadFileBlobsFromIndexedDB.bind(this)
|
||||
this.onBlobsLoaded = this.onBlobsLoaded.bind(this)
|
||||
}
|
||||
|
||||
loadFilesStateFromLocalStorage () {
|
||||
const savedState = this.MetaDataStore.load()
|
||||
|
||||
if (savedState) {
|
||||
this.core.log('Recovered some state from Local Storage')
|
||||
this.core.setState(savedState)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file objects that are currently waiting: they've been selected,
|
||||
* but aren't yet being uploaded.
|
||||
*/
|
||||
getWaitingFiles () {
|
||||
const waitingFiles = {}
|
||||
|
||||
const allFiles = this.core.state.files
|
||||
Object.keys(allFiles).forEach((fileID) => {
|
||||
const file = this.core.getFile(fileID)
|
||||
if (!file.progress || !file.progress.uploadStarted) {
|
||||
waitingFiles[fileID] = file
|
||||
}
|
||||
})
|
||||
|
||||
return waitingFiles
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file objects that are currently being uploaded. If a file has finished
|
||||
* uploading, but the other files in the same batch have not, the finished
|
||||
* file is also returned.
|
||||
*/
|
||||
getUploadingFiles () {
|
||||
const uploadingFiles = {}
|
||||
|
||||
const { currentUploads } = this.core.state
|
||||
if (currentUploads) {
|
||||
const uploadIDs = Object.keys(currentUploads)
|
||||
uploadIDs.forEach((uploadID) => {
|
||||
const filesInUpload = currentUploads[uploadID].fileIDs
|
||||
filesInUpload.forEach((fileID) => {
|
||||
uploadingFiles[fileID] = this.core.getFile(fileID)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return uploadingFiles
|
||||
}
|
||||
|
||||
saveFilesStateToLocalStorage () {
|
||||
const filesToSave = Object.assign(
|
||||
this.getWaitingFiles(),
|
||||
this.getUploadingFiles()
|
||||
)
|
||||
|
||||
this.MetaDataStore.save({
|
||||
currentUploads: this.core.state.currentUploads,
|
||||
files: filesToSave
|
||||
})
|
||||
}
|
||||
|
||||
loadFileBlobsFromServiceWorker () {
|
||||
this.ServiceWorkerStore.list().then((blobs) => {
|
||||
const numberOfFilesRecovered = Object.keys(blobs).length
|
||||
const numberOfFilesTryingToRecover = Object.keys(this.core.state.files).length
|
||||
if (numberOfFilesRecovered === numberOfFilesTryingToRecover) {
|
||||
this.core.log(`Successfully recovered ${numberOfFilesRecovered} blobs from Service Worker!`)
|
||||
this.core.info(`Successfully recovered ${numberOfFilesRecovered} files`, 'success', 3000)
|
||||
this.onBlobsLoaded(blobs)
|
||||
} else {
|
||||
this.core.log('Failed to recover blobs from Service Worker, trying IndexedDB now...')
|
||||
this.loadFileBlobsFromIndexedDB()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
loadFileBlobsFromIndexedDB () {
|
||||
this.IndexedDBStore.list().then((blobs) => {
|
||||
const numberOfFilesRecovered = Object.keys(blobs).length
|
||||
|
||||
if (numberOfFilesRecovered > 0) {
|
||||
this.core.log(`Successfully recovered ${numberOfFilesRecovered} blobs from Indexed DB!`)
|
||||
this.core.info(`Successfully recovered ${numberOfFilesRecovered} files`, 'success', 3000)
|
||||
return this.onBlobsLoaded(blobs)
|
||||
}
|
||||
this.core.log('Couldn’t recover anything from IndexedDB :(')
|
||||
})
|
||||
}
|
||||
|
||||
onBlobsLoaded (blobs) {
|
||||
const obsoleteBlobs = []
|
||||
const updatedFiles = Object.assign({}, this.core.state.files)
|
||||
Object.keys(blobs).forEach((fileID) => {
|
||||
const originalFile = this.core.getFile(fileID)
|
||||
if (!originalFile) {
|
||||
obsoleteBlobs.push(fileID)
|
||||
return
|
||||
}
|
||||
|
||||
const cachedData = blobs[fileID]
|
||||
|
||||
const updatedFileData = {
|
||||
data: cachedData,
|
||||
isRestored: true
|
||||
}
|
||||
const updatedFile = Object.assign({}, originalFile, updatedFileData)
|
||||
updatedFiles[fileID] = updatedFile
|
||||
|
||||
this.core.generatePreview(updatedFile)
|
||||
})
|
||||
this.core.setState({
|
||||
files: updatedFiles
|
||||
})
|
||||
this.core.emit('core:restored')
|
||||
|
||||
if (obsoleteBlobs.length) {
|
||||
this.deleteBlobs(obsoleteBlobs).then(() => {
|
||||
this.core.log(`[GoldenRetriever] cleaned up ${obsoleteBlobs.length} old files`)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
deleteBlobs (fileIDs) {
|
||||
const promises = []
|
||||
fileIDs.forEach((id) => {
|
||||
if (this.ServiceWorkerStore) {
|
||||
promises.push(this.ServiceWorkerStore.delete(id))
|
||||
}
|
||||
if (this.IndexedDBStore) {
|
||||
promises.push(this.IndexedDBStore.delete(id))
|
||||
}
|
||||
})
|
||||
return Promise.all(promises)
|
||||
}
|
||||
|
||||
install () {
|
||||
this.loadFilesStateFromLocalStorage()
|
||||
|
||||
if (Object.keys(this.core.state.files).length > 0) {
|
||||
if (this.ServiceWorkerStore) {
|
||||
this.core.log('Attempting to load files from Service Worker...')
|
||||
this.loadFileBlobsFromServiceWorker()
|
||||
} else {
|
||||
this.core.log('Attempting to load files from Indexed DB...')
|
||||
this.loadFileBlobsFromIndexedDB()
|
||||
}
|
||||
}
|
||||
|
||||
this.core.on('core:file-added', (file) => {
|
||||
if (file.isRemote) return
|
||||
|
||||
if (this.ServiceWorkerStore) {
|
||||
this.ServiceWorkerStore.put(file).catch((err) => {
|
||||
this.core.log('Could not store file', 'error')
|
||||
this.core.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
this.IndexedDBStore.put(file).catch((err) => {
|
||||
this.core.log('Could not store file', 'error')
|
||||
this.core.log(err)
|
||||
})
|
||||
})
|
||||
|
||||
this.core.on('core:file-removed', (fileID) => {
|
||||
if (this.ServiceWorkerStore) this.ServiceWorkerStore.delete(fileID)
|
||||
this.IndexedDBStore.delete(fileID)
|
||||
})
|
||||
|
||||
this.core.on('core:success', (fileIDs) => {
|
||||
this.deleteBlobs(fileIDs).then(() => {
|
||||
this.core.log(`[GoldenRetriever] removed ${fileIDs.length} files that finished uploading`)
|
||||
})
|
||||
})
|
||||
|
||||
this.core.on('core:state-update', this.saveFilesStateToLocalStorage)
|
||||
|
||||
this.core.on('core:restored', () => {
|
||||
// start all uploads again when file blobs are restored
|
||||
const { currentUploads } = this.core.getState()
|
||||
if (currentUploads) {
|
||||
Object.keys(currentUploads).forEach((uploadId) => {
|
||||
this.core.restore(uploadId, currentUploads[uploadId])
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1,234 +1,5 @@
|
|||
const Plugin = require('../Plugin')
|
||||
const ServiceWorkerStore = require('./ServiceWorkerStore')
|
||||
const IndexedDBStore = require('./IndexedDBStore')
|
||||
const MetaDataStore = require('./MetaDataStore')
|
||||
const GoldenRetriever = require('../GoldenRetriever')
|
||||
|
||||
/**
|
||||
* Restore Files plugin — restores selected files and resumes uploads
|
||||
* after a closed tab or a browser crash!
|
||||
*
|
||||
* Uses localStorage, IndexedDB and ServiceWorker to do its magic, read more:
|
||||
* https://uppy.io/blog/2017/07/golden-retriever/
|
||||
*/
|
||||
module.exports = class RestoreFiles extends Plugin {
|
||||
constructor (core, opts) {
|
||||
super(core, opts)
|
||||
this.type = 'debugger'
|
||||
this.id = 'RestoreFiles'
|
||||
this.title = 'Restore Files'
|
||||
console.warn('Using `uppy/lib/plugins/RestoreFiles` is deprecated and will be removed in v0.22. Please use `uppy/lib/plugins/GoldenRetriever` instead.')
|
||||
|
||||
const defaultOptions = {
|
||||
expires: 24 * 60 * 60 * 1000, // 24 hours
|
||||
serviceWorker: false
|
||||
}
|
||||
|
||||
this.opts = Object.assign({}, defaultOptions, opts)
|
||||
|
||||
this.MetaDataStore = new MetaDataStore({
|
||||
expires: this.opts.expires,
|
||||
storeName: core.getID()
|
||||
})
|
||||
this.ServiceWorkerStore = null
|
||||
if (this.opts.serviceWorker) {
|
||||
this.ServiceWorkerStore = new ServiceWorkerStore({ storeName: core.getID() })
|
||||
}
|
||||
this.IndexedDBStore = new IndexedDBStore(Object.assign(
|
||||
{ expires: this.opts.expires },
|
||||
opts.indexedDB || {},
|
||||
{ storeName: core.getID() }))
|
||||
|
||||
this.saveFilesStateToLocalStorage = this.saveFilesStateToLocalStorage.bind(this)
|
||||
this.loadFilesStateFromLocalStorage = this.loadFilesStateFromLocalStorage.bind(this)
|
||||
this.loadFileBlobsFromServiceWorker = this.loadFileBlobsFromServiceWorker.bind(this)
|
||||
this.loadFileBlobsFromIndexedDB = this.loadFileBlobsFromIndexedDB.bind(this)
|
||||
this.onBlobsLoaded = this.onBlobsLoaded.bind(this)
|
||||
}
|
||||
|
||||
loadFilesStateFromLocalStorage () {
|
||||
const savedState = this.MetaDataStore.load()
|
||||
|
||||
if (savedState) {
|
||||
this.core.log('Recovered some state from Local Storage')
|
||||
this.core.setState(savedState)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file objects that are currently waiting: they've been selected,
|
||||
* but aren't yet being uploaded.
|
||||
*/
|
||||
getWaitingFiles () {
|
||||
const waitingFiles = {}
|
||||
|
||||
const allFiles = this.core.state.files
|
||||
Object.keys(allFiles).forEach((fileID) => {
|
||||
const file = this.core.getFile(fileID)
|
||||
if (!file.progress || !file.progress.uploadStarted) {
|
||||
waitingFiles[fileID] = file
|
||||
}
|
||||
})
|
||||
|
||||
return waitingFiles
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file objects that are currently being uploaded. If a file has finished
|
||||
* uploading, but the other files in the same batch have not, the finished
|
||||
* file is also returned.
|
||||
*/
|
||||
getUploadingFiles () {
|
||||
const uploadingFiles = {}
|
||||
|
||||
const { currentUploads } = this.core.state
|
||||
if (currentUploads) {
|
||||
const uploadIDs = Object.keys(currentUploads)
|
||||
uploadIDs.forEach((uploadID) => {
|
||||
const filesInUpload = currentUploads[uploadID].fileIDs
|
||||
filesInUpload.forEach((fileID) => {
|
||||
uploadingFiles[fileID] = this.core.getFile(fileID)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return uploadingFiles
|
||||
}
|
||||
|
||||
saveFilesStateToLocalStorage () {
|
||||
const filesToSave = Object.assign(
|
||||
this.getWaitingFiles(),
|
||||
this.getUploadingFiles()
|
||||
)
|
||||
|
||||
this.MetaDataStore.save({
|
||||
currentUploads: this.core.state.currentUploads,
|
||||
files: filesToSave
|
||||
})
|
||||
}
|
||||
|
||||
loadFileBlobsFromServiceWorker () {
|
||||
this.ServiceWorkerStore.list().then((blobs) => {
|
||||
const numberOfFilesRecovered = Object.keys(blobs).length
|
||||
const numberOfFilesTryingToRecover = Object.keys(this.core.state.files).length
|
||||
if (numberOfFilesRecovered === numberOfFilesTryingToRecover) {
|
||||
this.core.log(`Successfully recovered ${numberOfFilesRecovered} blobs from Service Worker!`)
|
||||
this.core.info(`Successfully recovered ${numberOfFilesRecovered} files`, 'success', 3000)
|
||||
this.onBlobsLoaded(blobs)
|
||||
} else {
|
||||
this.core.log('Failed to recover blobs from Service Worker, trying IndexedDB now...')
|
||||
this.loadFileBlobsFromIndexedDB()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
loadFileBlobsFromIndexedDB () {
|
||||
this.IndexedDBStore.list().then((blobs) => {
|
||||
const numberOfFilesRecovered = Object.keys(blobs).length
|
||||
|
||||
if (numberOfFilesRecovered > 0) {
|
||||
this.core.log(`Successfully recovered ${numberOfFilesRecovered} blobs from Indexed DB!`)
|
||||
this.core.info(`Successfully recovered ${numberOfFilesRecovered} files`, 'success', 3000)
|
||||
return this.onBlobsLoaded(blobs)
|
||||
}
|
||||
this.core.log('Couldn’t recover anything from IndexedDB :(')
|
||||
})
|
||||
}
|
||||
|
||||
onBlobsLoaded (blobs) {
|
||||
const obsoleteBlobs = []
|
||||
const updatedFiles = Object.assign({}, this.core.state.files)
|
||||
Object.keys(blobs).forEach((fileID) => {
|
||||
const originalFile = this.core.getFile(fileID)
|
||||
if (!originalFile) {
|
||||
obsoleteBlobs.push(fileID)
|
||||
return
|
||||
}
|
||||
|
||||
const cachedData = blobs[fileID]
|
||||
|
||||
const updatedFileData = {
|
||||
data: cachedData,
|
||||
isRestored: true
|
||||
}
|
||||
const updatedFile = Object.assign({}, originalFile, updatedFileData)
|
||||
updatedFiles[fileID] = updatedFile
|
||||
|
||||
this.core.generatePreview(updatedFile)
|
||||
})
|
||||
this.core.setState({
|
||||
files: updatedFiles
|
||||
})
|
||||
this.core.emit('core:restored')
|
||||
|
||||
if (obsoleteBlobs.length) {
|
||||
this.deleteBlobs(obsoleteBlobs).then(() => {
|
||||
this.core.log(`RestoreFiles: cleaned up ${obsoleteBlobs.length} old files`)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
deleteBlobs (fileIDs) {
|
||||
const promises = []
|
||||
fileIDs.forEach((id) => {
|
||||
if (this.ServiceWorkerStore) {
|
||||
promises.push(this.ServiceWorkerStore.delete(id))
|
||||
}
|
||||
if (this.IndexedDBStore) {
|
||||
promises.push(this.IndexedDBStore.delete(id))
|
||||
}
|
||||
})
|
||||
return Promise.all(promises)
|
||||
}
|
||||
|
||||
install () {
|
||||
this.loadFilesStateFromLocalStorage()
|
||||
|
||||
if (Object.keys(this.core.state.files).length > 0) {
|
||||
if (this.ServiceWorkerStore) {
|
||||
this.core.log('Attempting to load files from Service Worker...')
|
||||
this.loadFileBlobsFromServiceWorker()
|
||||
} else {
|
||||
this.core.log('Attempting to load files from Indexed DB...')
|
||||
this.loadFileBlobsFromIndexedDB()
|
||||
}
|
||||
}
|
||||
|
||||
this.core.on('core:file-added', (file) => {
|
||||
if (file.isRemote) return
|
||||
|
||||
if (this.ServiceWorkerStore) {
|
||||
this.ServiceWorkerStore.put(file).catch((err) => {
|
||||
this.core.log('Could not store file', 'error')
|
||||
this.core.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
this.IndexedDBStore.put(file).catch((err) => {
|
||||
this.core.log('Could not store file', 'error')
|
||||
this.core.log(err)
|
||||
})
|
||||
})
|
||||
|
||||
this.core.on('core:file-removed', (fileID) => {
|
||||
if (this.ServiceWorkerStore) this.ServiceWorkerStore.delete(fileID)
|
||||
this.IndexedDBStore.delete(fileID)
|
||||
})
|
||||
|
||||
this.core.on('core:success', (fileIDs) => {
|
||||
this.deleteBlobs(fileIDs).then(() => {
|
||||
this.core.log(`RestoreFiles: removed ${fileIDs.length} files that finished uploading`)
|
||||
})
|
||||
})
|
||||
|
||||
this.core.on('core:state-update', this.saveFilesStateToLocalStorage)
|
||||
|
||||
this.core.on('core:restored', () => {
|
||||
// start all uploads again when file blobs are restored
|
||||
const { currentUploads } = this.core.getState()
|
||||
if (currentUploads) {
|
||||
Object.keys(currentUploads).forEach((uploadId) => {
|
||||
this.core.restore(uploadId, currentUploads[uploadId])
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
module.exports = GoldenRetriever
|
||||
|
|
|
|||
|
|
@ -5,22 +5,23 @@ permalink: docs/golden-retriever/
|
|||
order: 40
|
||||
---
|
||||
|
||||
Golden Retriever plugin, also known and used as `RestoreFiles`, saves selected files in your browser cache (Local Storage for metadata, then Service Worker for all blobs + IndexedDB for small blobs), so that if the browser crashes, Uppy can restore everything and continue uploading like nothing happened. Read more about it [on the blog](https://uppy.io/blog/2017/07/golden-retriever/).
|
||||
Golden Retriever plugin saves selected files in your browser cache (Local Storage for metadata, then Service Worker for all blobs + IndexedDB for small blobs), so that if the browser crashes, Uppy can restore everything and continue uploading like nothing happened. Read more about it [on the blog](https://uppy.io/blog/2017/07/golden-retriever/).
|
||||
|
||||
1\. Bundle your own service worker `sw.js` file with Uppy Golden Retriever’s service worker. If you’re using Browserify, just bundle it separately, for Webpack there is a plugin [serviceworker-webpack-plugin](https://github.com/oliviertassinari/serviceworker-webpack-plugin).
|
||||
|
||||
```js
|
||||
// sw.js
|
||||
|
||||
require('uppy/lib/RestoreFiles/ServiceWorker.js')
|
||||
require('uppy/lib/plugins/GoldenRetriever/ServiceWorker.js')
|
||||
```
|
||||
|
||||
2\. Register it in your app entry point:
|
||||
|
||||
```js
|
||||
// you app.js entry point
|
||||
const GoldenRetriever = require('uppy/lib/plugins/GoldenRetriever')
|
||||
|
||||
uppy.use(RestoreFiles, {serviceWorker: true})
|
||||
uppy.use(GoldenRetriever, {serviceWorker: true})
|
||||
uppy.run()
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue