Skip to content

Instantly share code, notes, and snippets.

@GAM3RG33K
Created December 14, 2021 12:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GAM3RG33K/02194a670c2d63bf7bb418b4ed05bf58 to your computer and use it in GitHub Desktop.
Save GAM3RG33K/02194a670c2d63bf7bb418b4ed05bf58 to your computer and use it in GitHub Desktop.
[Basic] Manage Data to Sync when Offline
import 'package:async/async.dart';
import 'package:dartz/dartz.dart';
/// Pub Packages if not already install
///
/// # Utility Extensions to existing dart classes & methods
/// dartz: ^0.10.1
///
/// # Asynchronous Operation Utilities
/// async: ^2.8.1
class RequestType {
static const get = RequestType._internal(0);
static const post = RequestType._internal(1);
static const update = RequestType._internal(2);
static const delete = RequestType._internal(3);
final int _value;
const RequestType._internal(this._value);
@override
String toString() {
return 'RequestType(value:$_value, tag:$tag, name: $name)';
}
String get tag {
switch (_value) {
case 0:
return 'get';
case 1:
return 'post';
case 2:
return 'update';
case 3:
return 'delete';
default:
throw UnimplementedError('Unknown request type: $this');
}
}
String get name {
switch (_value) {
case 0:
return 'Get';
case 1:
return 'Post';
case 2:
return 'Update';
case 3:
return 'Delete';
default:
throw UnimplementedError('Unknown request type: $this');
}
}
factory RequestType.fromTag(String tag) {
const _types = [
get,
post,
update,
delete,
];
final _validTypes = _types.where((card) {
return card.tag.toLowerCase().contains(tag.toLowerCase());
}).toList();
final _type = _validTypes.first;
return _type;
}
}
class SyncPoint {
final RequestType requestType;
final String url;
final String? parameters;
final Map<String, String>? headers;
// final void Function(dynamic results)? onSuccess;
// final void Function(Error error)? onError;
// final void Function()? onCancel;
SyncPoint({
required this.requestType,
required this.url,
this.parameters,
this.headers,
// this.onSuccess,
// this.onError,
// this.onCancel,
});
@override
String toString() {
return 'SyncPoint{requestType: $requestType, url: $url, parameters: $parameters, headers: $headers}';
}
CancelableOperation<Either<Error, dynamic>>? _cancellable;
Future<void> performSync() async {
final Future<Either<Error, dynamic>> _future;
switch (requestType) {
case RequestType.get:
_future = performGetNetworkRequest(
url: url,
parameters: parameters,
headers: headers,
);
break;
case RequestType.post:
_future = performPostNetworkRequest(
url: url,
parameters: parameters,
headers: headers,
);
break;
case RequestType.update:
_future = performUpdateNetworkRequest(
url: url,
parameters: parameters,
headers: headers,
);
break;
case RequestType.delete:
_future = performDeleteNetworkRequest(
url: url,
parameters: parameters,
headers: headers,
);
break;
default:
throw UnimplementedError(
'No method implemented for $this',
);
}
if (_cancellable?.isCanceled ?? false) {
print('SyncPoint: Retrying already cancelled request for $this');
}
_cancellable = CancelableOperation.fromFuture(_future, onCancel: () {
print('SyncPoint: Cancelled request for $this');
});
final Either<Error, dynamic>? response =
await _cancellable?.valueOrCancellation();
response?.fold(
(error) => print('SyncPoint: Error: $error for $this'),
(result) => print('SyncPoint: Success: $result for $this'),
);
}
Future<Either<Error, dynamic>> performGetNetworkRequest({
required String url,
String? parameters,
Map<String, String>? headers,
}) async {
throw UnimplementedError();
}
Future<Either<Error, dynamic>> performPostNetworkRequest({
required String url,
String? parameters,
Map<String, String>? headers,
}) async {
throw UnimplementedError();
}
Future<Either<Error, dynamic>> performUpdateNetworkRequest({
required String url,
String? parameters,
Map<String, String>? headers,
}) async {
throw UnimplementedError();
}
Future<Either<Error, dynamic>> performDeleteNetworkRequest({
required String url,
String? parameters,
Map<String, String>? headers,
}) async {
throw UnimplementedError();
}
Future<void> cancel() async {
_cancellable?.cancel();
}
}
class DataSyncPoint {
final String syncID;
final DateTime syncTimeStamp;
final SyncPoint networkSync;
final bool synced;
DataSyncPoint({
required this.networkSync,
String? id,
DateTime? timeStamp,
this.synced = false,
}) : syncTimeStamp = timeStamp ?? DateTime.now(),
syncID = id ?? (timeStamp ?? DateTime.now()).toIso8601String();
Future<void> cancel() => networkSync.cancel();
DataSyncPoint copyWith({
SyncPoint? networkSync,
String? id,
DateTime? timeStamp,
bool? synced,
}) {
return DataSyncPoint(
networkSync: networkSync ?? this.networkSync,
id: id ?? syncID,
timeStamp: timeStamp ?? syncTimeStamp,
synced: synced ?? this.synced,
);
}
}
class OfflineSyncManager {
static final OfflineSyncManager _instance = OfflineSyncManager._();
factory OfflineSyncManager() {
return _instance;
}
OfflineSyncManager._();
}
final offlineSyncManager = OfflineSyncManager();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment