fix: dart:io import in matrix_sdk_database
- removes `Directory` field in high-level `MatrixSdkDatabase` - migrates `Directory fileStoragePath` to `Uri fileStorageLocation` - makes file operations in `MatrixSdkDatabase` conditional on `dart.libraries.js_util` - implements a tiny stub of the file operations used in `MatrixSdkDatabase` It seems like the Flutter tool can compile despite these imports. Sadly the Dart standalone dart2js compiler doesn't reach there. While refactorying the code, I decided it's likely cleaner to have a `Uri` as storage location provider than using some fake directory or String as relacement. The advantage of a `Uri` at this place is the explicit `Uri.directory` constructor available to ensure type and encoding safe directory locations supporting both Windows and *nix. Additionally, admitted, that's an edge-case, one could even easily extend the use of a `Uri` based descriptor to support future storage location accesses (e.g. IPFS or custom schemes for e.g. local web browser based file system APIs). Using a `Uri`, one would only need to override the three methods making use of the `fileStorageLocation` property to handle different Uri schemes too. Signed-off-by: The one with the braid <info@braid.business>
This commit is contained in:
parent
b7bc6c3b79
commit
4ba6e25689
|
|
@ -0,0 +1,37 @@
|
|||
// This is a stub implementation of all filesystem related calls done
|
||||
// by the matrix SDK database. This fake implementation ensures we can compile
|
||||
// using dart2js.
|
||||
|
||||
import 'dart:typed_data';
|
||||
|
||||
class File extends FileSystemEntry {
|
||||
const File(super.path);
|
||||
|
||||
Future<Uint8List> readAsBytes() async => Uint8List(0);
|
||||
|
||||
Future<void> writeAsBytes(Uint8List data) async => Future.value();
|
||||
}
|
||||
|
||||
class Directory extends FileSystemEntry {
|
||||
const Directory(super.path);
|
||||
|
||||
Stream<FileSystemEntry> list() async* {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class FileSystemEntry {
|
||||
final String path;
|
||||
|
||||
const FileSystemEntry(this.path);
|
||||
|
||||
Future<void> delete() => Future.value();
|
||||
|
||||
Future<FileStat> stat() async => FileStat();
|
||||
|
||||
Future<bool> exists() async => false;
|
||||
}
|
||||
|
||||
class FileStat {
|
||||
final modified = DateTime.fromMillisecondsSinceEpoch(0);
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
export 'dart:io';
|
||||
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
|
||||
|
|
@ -100,11 +99,28 @@ class MatrixSdkDatabase extends DatabaseApi {
|
|||
late Box<String> _seenDeviceIdsBox;
|
||||
|
||||
late Box<String> _seenDeviceKeysBox;
|
||||
|
||||
@override
|
||||
bool get supportsFileStoring => fileStoragePath != null;
|
||||
bool get supportsFileStoring => fileStorageLocation != null;
|
||||
@override
|
||||
final int maxFileSize;
|
||||
final Directory? fileStoragePath;
|
||||
|
||||
// there was a field of type `dart:io:Directory` here. This one broke the
|
||||
// dart js standalone compiler. Migration via URI as file system identifier.
|
||||
@Deprecated(
|
||||
'Breaks support for web standalone. Use [fileStorageLocation] instead.')
|
||||
Object? get fileStoragePath => fileStorageLocation?.toFilePath();
|
||||
|
||||
/// A [Uri] defining the file storage location.
|
||||
///
|
||||
/// Unless you support custom Uri schemes, this should usually be a
|
||||
/// [Uri.directory] identifier.
|
||||
///
|
||||
/// Using a [Uri] as type here enables users to technically extend the API to
|
||||
/// support file storage on non-io platforms as well - or to use non-File
|
||||
/// based storage mechanisms on io.
|
||||
final Uri? fileStorageLocation;
|
||||
|
||||
final Duration? deleteFilesAfterDuration;
|
||||
|
||||
static const String _clientBoxName = 'box_client';
|
||||
|
|
@ -168,9 +184,11 @@ class MatrixSdkDatabase extends DatabaseApi {
|
|||
this.idbFactory,
|
||||
this.sqfliteFactory,
|
||||
this.maxFileSize = 0,
|
||||
this.fileStoragePath,
|
||||
// TODO : remove deprecated member migration on next major release
|
||||
dynamic fileStoragePath,
|
||||
Uri? fileStorageLocation,
|
||||
this.deleteFilesAfterDuration,
|
||||
});
|
||||
}) : fileStorageLocation = fileStorageLocation ?? fileStoragePath?.path;
|
||||
|
||||
Future<void> open() async {
|
||||
_collection = await BoxCollection.open(
|
||||
|
|
@ -311,13 +329,15 @@ class MatrixSdkDatabase extends DatabaseApi {
|
|||
|
||||
@override
|
||||
Future<void> deleteOldFiles(int savedAt) async {
|
||||
final dir = fileStoragePath;
|
||||
if (_kIsWeb) return;
|
||||
final path = fileStorageLocation?.toFilePath();
|
||||
final deleteFilesAfterDuration = this.deleteFilesAfterDuration;
|
||||
if (!supportsFileStoring ||
|
||||
dir == null ||
|
||||
path == null ||
|
||||
deleteFilesAfterDuration == null) {
|
||||
return;
|
||||
}
|
||||
final dir = Directory(path);
|
||||
final entities = await dir.list().toList();
|
||||
for (final file in entities) {
|
||||
if (file is! File) continue;
|
||||
|
|
@ -453,11 +473,11 @@ class MatrixSdkDatabase extends DatabaseApi {
|
|||
|
||||
@override
|
||||
Future<Uint8List?> getFile(Uri mxcUri) async {
|
||||
final fileStoragePath = this.fileStoragePath;
|
||||
if (!supportsFileStoring || fileStoragePath == null) return null;
|
||||
if (_kIsWeb) return null;
|
||||
final path = fileStorageLocation?.toFilePath();
|
||||
if (!supportsFileStoring || path == null) return null;
|
||||
|
||||
final file =
|
||||
File('${fileStoragePath.path}/${mxcUri.toString().split('/').last}');
|
||||
final file = File('$path/${mxcUri.toString().split('/').last}');
|
||||
|
||||
if (await file.exists()) return await file.readAsBytes();
|
||||
return null;
|
||||
|
|
@ -1138,11 +1158,11 @@ class MatrixSdkDatabase extends DatabaseApi {
|
|||
|
||||
@override
|
||||
Future<void> storeFile(Uri mxcUri, Uint8List bytes, int time) async {
|
||||
final fileStoragePath = this.fileStoragePath;
|
||||
if (!supportsFileStoring || fileStoragePath == null) return;
|
||||
if (_kIsWeb) return;
|
||||
final path = fileStorageLocation?.toFilePath();
|
||||
if (!supportsFileStoring || path == null) return;
|
||||
|
||||
final file =
|
||||
File('${fileStoragePath.path}/${mxcUri.toString().split('/').last}');
|
||||
final file = File('$path/${mxcUri.toString().split('/').last}');
|
||||
|
||||
if (await file.exists()) return;
|
||||
await file.writeAsBytes(bytes);
|
||||
|
|
|
|||
Loading…
Reference in New Issue