Skip to content

Commit

Permalink
Feature/null safety (#16)
Browse files Browse the repository at this point in the history
* Delete android plugin file.

* Package update.

* Dart 2.0 migration.

* test case update

* Add build runner code.

* Add generated test in git ignore.

* Add generated test in git ignore

* Make platform data optional.

* Update test cases

* Try to fix travis ci -1

* Rename files.

* Delete old files.

* Bump the version to 1.0.5

* Version bump 2.0.0

* Apply proper casing on App dialog file.

* Make os variable required.

* Init manUpData with blank state.

* Update test cases

* Add os param optional and fallback to operating system.

Co-authored-by: sparmar <sparmar@nextfaze.com>
  • Loading branch information
it-sam and sparmar authored May 14, 2021
1 parent 531dbb5 commit 1b2f98e
Show file tree
Hide file tree
Showing 20 changed files with 499 additions and 315 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ios/Runner/GeneratedPluginRegistrant.*
android/local.properties
.vscode
coverage
test/mandatory_update_test.mocks.dart

# Flutter/Dart/Pub related
**/doc/api/
Expand Down
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ before_script:
- ./.flutter/bin/flutter doctor

script:
- ./.flutter/bin/flutter pub get
- ./.flutter/bin/flutter pub run build_runner build
- ./.flutter/bin/flutter analyze
- ./.flutter/bin/flutter test --coverage
after_success:
Expand Down
32 changes: 31 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,44 @@
# manUp

## [2.0.1]

Minor code changes.
Making some variables required.
Continue renaming some more files.

## [2.0.0]

Migrate to null safety.
**Breaking changes** Renaming some files.

## [1.0.4]

Make get setting method visible

## [1.0.3]

Add support for desktop platforms

## [1.0.2]

pub spec upgrade

Stop throwing reading file exception.

## [1.0.1]

Add capability to store and retrieve man up config.

## [1.0.0]

### First major release
Added Delegate support with `ManupDelegate`

Added Delegate support with `ManUpDelegate`

Added Helper Widget with `ManUpWidget`

Check `README` file for full details.

## [0.0.3]

First manup release
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ service.close();

### Using the Service with Delegate

Implement `ManupDelegate` or use `ManupDelegateMixin` mixin which has default implementation.
Implement `ManUpDelegate` or use `ManUpDelegateMixin` mixin which has default implementation.

- `manUpConfigUpdateStarting()` : will be called before starting to validate
- `manupStatusChanged(ManUpStatus status)` : will be called every time status changes
- `manUpStatusChanged(ManUpStatus status)` : will be called every time status changes
- `manUpUpdateAvailable()` : will be called when ManUpStatus changes to supported
- `manUpUpdateRequired()` : will be called when ManUpStatus changes to unsupported
- `manUpMaintenanceMode()`: will be called when ManUpStatus changes to disabled
Expand All @@ -70,7 +70,7 @@ class ManUpExample extends StatefulWidget {
}
class _ManUpExampleState extends State<ManUpExample>
with ManupDelegate, ManupDelegateMixin, DialogMixin {
with ManUpDelegate, ManUpDelegateMixin, DialogMixin {
ManUpService service;
@override
void initState() {
Expand All @@ -89,7 +89,7 @@ class _ManUpExampleState extends State<ManUpExample>
@override
void manUpStatusChanged(ManUpStatus status) {
// handle status or show default dialog
showManupDialog(status, service.getMessage(forStatus: status),
showManUpDialog(status, service.getMessage(forStatus: status),
service.configData.updateUrl);
}
Expand All @@ -102,7 +102,9 @@ class _ManUpExampleState extends State<ManUpExample>
```

### Using the Service with Helper Widget
Wrap your widget with `ManUpWidget` to automaticaly handle every thing.

Wrap your widget with `ManUpWidget` to automatically handle every thing.

```dart
@override
Widget build(BuildContext context) {
Expand All @@ -116,7 +118,8 @@ Wrap your widget with `ManUpWidget` to automaticaly handle every thing.
);
}
```

### Exception Handling

`validate` will throw a `ManUpException` if the lookup failed for any reason. Most likely, this will be caused
by the device being offline and unable to retreive the metadata. It is up to you how you want to handle this in your app. Some apps, where a supported version is critical, should probably not run unless the version was validated successfully. However, for other apps, there's probably no problem and the app should continue running.
by the device being offline and unable to retrieve the metadata. It is up to you how you want to handle this in your app. Some apps, where a supported version is critical, should probably not run unless the version was validated successfully. However, for other apps, there's probably no problem and the app should continue running.

This file was deleted.

14 changes: 7 additions & 7 deletions lib/manup.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import 'package:url_launcher/url_launcher.dart';

part 'src/exception.dart';
part 'src/metadata.dart';
part 'src/manup_status.dart';
part 'src/manup_service.dart';
part 'src/man_up_status.dart';
part 'src/man_up_service.dart';
part 'src/package_info_provider.dart';
part 'src/manup_delegate.dart';
part 'src/ui/manup_app_dialog.dart';
part 'src/ui/manup_widget.dart';
part 'src/mixin/manup_delegate_mixin.dart';
part 'src/mixin/manup_dialog_mixin.dart';
part 'src/man_up_delegate.dart';
part 'src/ui/man_up_app_dialog.dart';
part 'src/ui/man_up_widget.dart';
part 'src/mixin/man_up_delegate_mixin.dart';
part 'src/mixin/man_up_dialog_mixin.dart';
part 'src/config_storage.dart';
8 changes: 5 additions & 3 deletions lib/src/config_storage.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
part of manup;

class ConfigStorage {
static const String _manupFile = "manup_config.json";
const ConfigStorage();
static const String _manUpFile = "man_up_config.json";
//
Future<bool> storeFile({String filename = _manupFile, String fileData}) {
Future<bool> storeFile(
{String filename = _manUpFile, required String fileData}) {
return getApplicationDocumentsDirectory().then((directory) {
final File file = File('${directory.path}/$filename');
return file.writeAsString(fileData).then((_) => Future.value(true));
});
}

Future<String> readfile({String filename = _manupFile}) {
Future<String> readFile({String filename = _manUpFile}) async {
return getApplicationDocumentsDirectory().then((directory) {
final File file = File('${directory.path}/$filename');
return file.exists().then((isExist) =>
Expand Down
2 changes: 1 addition & 1 deletion lib/src/exception.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
part of manup;

class ManUpException implements Exception {
final String msg;
final String? msg;
const ManUpException([this.msg]);

@override
Expand Down
6 changes: 3 additions & 3 deletions lib/src/manup_delegate.dart → lib/src/man_up_delegate.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
part of manup;

/// `ManupDelegate` class has required methods.
/// Default implemetation is in `ManupDelegateMixin` file.
abstract class ManupDelegate {
/// `ManUpDelegate` class has required methods.
/// Default implementation is in `ManUpDelegateMixin` file.
abstract class ManUpDelegate {
void manUpStatusChanged(ManUpStatus status);
void manUpConfigUpdateStarting();
void manUpUpdateRequired();
Expand Down
92 changes: 46 additions & 46 deletions lib/src/manup_service.dart → lib/src/man_up_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,50 @@ part of manup;
class ManUpService {
final String url;
final PackageInfoProvider packageInfoProvider;
@visibleForTesting
ConfigStorage fileStorage = ConfigStorage();

String os;
Metadata _manupData;
final ConfigStorage fileStorage;

final String os;
Metadata _manUpData = Metadata();
// read platform data
PlatformData get configData => this.getPlatformData(os, _manupData);
ManupDelegate delegate;
PlatformData? get configData => this.getPlatformData(os, _manUpData);
ManUpDelegate? delegate;

http.Client _client;
final http.Client _client;

///
ManUpService(
this.url, {
this.packageInfoProvider = const DefaultPackageInfoProvider(),
this.os,
http.Client http,
}) : _client = http;
String? os,
required http.Client http,
ConfigStorage storage = const ConfigStorage(),
}) : _client = http,
fileStorage = storage,
this.os = os ?? Platform.operatingSystem;

Future<ManUpStatus> validate() async {
delegate?.manUpConfigUpdateStarting?.call();
delegate?.manUpConfigUpdateStarting();
try {
ManUpStatus status = await _validate();
this._handleManUpStatus(status);
return status;
} catch (e) {
throw e;
} finally {
_storeManupFile();
await _storeManUpFile();
}
}

Future<ManUpStatus> _validate() async {
PackageInfo info = await this.packageInfoProvider.getInfo();
_manupData = await this.getMetadata();

PlatformData platformData = configData;
final metadata = await this.getMetadata();
_manUpData = metadata;
PlatformData? platformData = configData;
//
if (platformData == null) {
return ManUpStatus.unsupported;
}
if (!platformData.enabled) {
return ManUpStatus.disabled;
}
Expand All @@ -61,13 +68,10 @@ class ManUpService {
}
}

T setting<T>({String key}) => _manupData?.setting(key: key) ?? null;
T? setting<T>({String? key}) => _manUpData.setting<T>(key: key) ?? null;

@visibleForTesting
PlatformData getPlatformData(String os, Metadata data) {
if (data == null) {
throw ManUpException('No data, validate must be called first.');
}
PlatformData? getPlatformData(String os, Metadata data) {
if (os == 'ios') {
return data.ios;
} else if (os == 'android') {
Expand All @@ -87,75 +91,71 @@ class ManUpService {
try {
final uri = Uri.parse(this.url);
var data = await _client.get(uri);
Map<String, dynamic> json = jsonDecode(data.body);
Map<String, dynamic>? json = jsonDecode(data.body);
return Metadata(data: json);
} catch (exception) {
try {
var metadata = await _readManupFile();
var metadata = await _readManUpFile();
return metadata;
} catch (e) {
throw ManUpException(exception.toString());
}
}
}

// manup status validation
_handleManUpStatus(ManUpStatus status) {
this.delegate?.manUpStatusChanged?.call(status);
// manUp status validation
void _handleManUpStatus(ManUpStatus status) {
this.delegate?.manUpStatusChanged(status);
switch (status) {
case ManUpStatus.supported:
this.delegate?.manUpUpdateAvailable?.call();
this.delegate?.manUpUpdateAvailable();
break;
case ManUpStatus.unsupported:
this.delegate?.manUpUpdateRequired?.call();
this.delegate?.manUpUpdateRequired();
break;
case ManUpStatus.disabled:
this.delegate?.manUpMaintenanceMode?.call();
this.delegate?.manUpMaintenanceMode();
break;
default:
break;
}
}

String getMessage({ManUpStatus forStatus}) {
String getMessage({required ManUpStatus forStatus}) {
switch (forStatus) {
case ManUpStatus.supported:
return _manupData?.supportedMessage;
return _manUpData.supportedMessage;
case ManUpStatus.unsupported:
return _manupData?.unsupportedMessage;
break;
return _manUpData.unsupportedMessage;
case ManUpStatus.disabled:
return _manupData?.disabledMessage;
break;
default:
return _manUpData.disabledMessage;
case ManUpStatus.latest:
return "";
}
}

/// manup file storage
void _storeManupFile() async {
/// manUp file storage
Future<void> _storeManUpFile() async {
try {
if (_manupData == null || _manupData._data == null) {
if (_manUpData._data == null) {
return;
}
String json = jsonEncode(_manupData._data);
fileStorage.storeFile(fileData: json);
String json = jsonEncode(_manUpData._data);
await fileStorage.storeFile(fileData: json);
} catch (e) {
print("cannot store file. $e");
}
}

Future<Metadata> _readManupFile() async {
var data = await fileStorage.readfile();
Map<String, dynamic> json = jsonDecode(data);
Future<Metadata> _readManUpFile() async {
var data = await fileStorage.readFile();
Map<String, dynamic>? json = jsonDecode(data);
return Metadata(data: json);
}

//call this on dispose.
void close() {
_client?.close();
_client = null;
fileStorage = null;
_client.close();
this.delegate = null;
}
}
File renamed without changes.
Loading

0 comments on commit 1b2f98e

Please sign in to comment.