A framework for building convergent cross-platform Nextcloud clients using Flutter.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

115 lines
2.9 KiB

part of '../neon.dart';
class RequestManager {
RequestManager([
this.cache,
]);
final Cache? cache;
Future wrapNextcloud<T, R>(
final String clientID,
final String k,
final BehaviorSubject<Result<T>> subject,
final Future<R> Function() call,
final T Function(R) unwrap, {
final bool disableTimeout = false,
}) async {
if (subject.valueOrNull?.data != null) {
subject.add(
Result(
subject.value.data,
null,
loading: true,
cached: true,
),
);
} else {
subject.add(Result.loading());
}
final key = '$clientID-$k';
if (cache != null && await cache!.has(key)) {
try {
subject.add(
Result(
unwrap(deserializeNextcloud<R>(json.decode((await cache!.get(key))!))),
null,
loading: true,
cached: true,
),
);
} catch (e, s) {
debugPrint(e.toString());
debugPrint(s.toString());
}
}
try {
final response = await (disableTimeout ? call() : timeout(call));
await cache?.set(key, json.encode(serializeNextcloud<R>(response)));
subject.add(Result.success(unwrap(response)));
} catch (e, s) {
debugPrint(e.toString());
debugPrint(s.toString());
if (cache != null && await cache!.has(key)) {
try {
subject.add(
Result(
unwrap(deserializeNextcloud<R>(json.decode((await cache!.get(key))!))),
null,
loading: false,
cached: true,
),
);
return;
} catch (e, s) {
debugPrint(e.toString());
debugPrint(s.toString());
}
}
subject.add(Result.error(e));
}
}
static Future<T> timeout<T>(
final Future<T> Function() call,
) =>
call().timeout(const Duration(seconds: 30));
}
class Cache {
Cache(this._platform);
final NeonPlatform _platform;
Database? _database;
Future init() async {
if (_database != null) {
return;
}
_database = await openDatabase(
p.join(
await _platform.getApplicationCachePath(),
'cache.db',
),
version: 1,
onCreate: (final db, final version) async {
await db.execute('CREATE TABLE cache (id INTEGER PRIMARY KEY, key TEXT, value TEXT, UNIQUE(key))');
},
);
}
Future<bool> has(final String key) async =>
Sqflite.firstIntValue(await _database!.rawQuery('SELECT COUNT(*) FROM cache WHERE key = ?', [key])) == 1;
Future<String?> get(final String key) async =>
(await _database!.rawQuery('SELECT value FROM cache WHERE key = ?', [key]))[0]['value'] as String?;
Future set(final String key, final String value) async => _database!.rawQuery(
'INSERT INTO cache (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value',
[key, value],
);
}