feat: display file backup status in file context menu (#2044) (skip e2e)

* feat: show file backup status in context menu

* feat: show backup status in list cell

* feat: mapping cache

* feat: add to linking menu + date format

* fix: types
This commit is contained in:
Mo
2022-11-22 19:58:48 -06:00
committed by GitHub
parent 096d82f7af
commit 7c2e832065
22 changed files with 196 additions and 55 deletions

View File

@@ -2,7 +2,13 @@ import { ContentType, Uuid } from '@standardnotes/common'
import { EncryptionProviderInterface } from '@standardnotes/encryption'
import { PayloadEmitSource, FileItem, CreateEncryptedBackupFileContextPayload } from '@standardnotes/models'
import { ClientDisplayableError } from '@standardnotes/responses'
import { FilesApiInterface, FileBackupMetadataFile, FileBackupsDevice, FileBackupsMapping } from '@standardnotes/files'
import {
FilesApiInterface,
FileBackupMetadataFile,
FileBackupsDevice,
FileBackupsMapping,
FileBackupRecord,
} from '@standardnotes/files'
import { InternalEventBusInterface } from '../Internal/InternalEventBusInterface'
import { ItemManagerInterface } from '../Item/ItemManagerInterface'
import { AbstractService } from '../Service/AbstractService'
@@ -11,6 +17,7 @@ import { StatusServiceInterface } from '../Status/StatusServiceInterface'
export class FilesBackupService extends AbstractService {
private itemsObserverDisposer: () => void
private pendingFiles = new Set<Uuid>()
private mappingCache?: FileBackupsMapping['files']
constructor(
private items: ItemManagerInterface,
@@ -75,8 +82,30 @@ export class FilesBackupService extends AbstractService {
return this.device.openFilesBackupsLocation()
}
private async getBackupsMapping(): Promise<FileBackupsMapping['files']> {
return (await this.device.getFilesBackupsMappingFile()).files
private async getBackupsMappingFromDisk(): Promise<FileBackupsMapping['files']> {
const result = (await this.device.getFilesBackupsMappingFile()).files
this.mappingCache = result
return result
}
private invalidateMappingCache(): void {
this.mappingCache = undefined
}
private async getBackupsMappingFromCache(): Promise<FileBackupsMapping['files']> {
return this.mappingCache ?? (await this.getBackupsMappingFromDisk())
}
public async getFileBackupInfo(file: FileItem): Promise<FileBackupRecord | undefined> {
const mapping = await this.getBackupsMappingFromCache()
const record = mapping[file.uuid]
return record
}
public async openFileBackup(record: FileBackupRecord): Promise<void> {
await this.device.openFileBackup(record)
}
private async handleChangedFiles(files: FileItem[]): Promise<void> {
@@ -88,7 +117,7 @@ export class FilesBackupService extends AbstractService {
return
}
const mapping = await this.getBackupsMapping()
const mapping = await this.getBackupsMappingFromDisk()
for (const file of files) {
if (this.pendingFiles.has(file.uuid)) {
@@ -105,6 +134,8 @@ export class FilesBackupService extends AbstractService {
this.pendingFiles.delete(file.uuid)
}
}
this.invalidateMappingCache()
}
private async performBackupOperation(file: FileItem): Promise<'success' | 'failed' | 'aborted'> {