Skip to content

Commit

Permalink
Merge pull request #65 from nimblehq/release/0.5.0
Browse files Browse the repository at this point in the history
Release 0.5.0 (6)
  • Loading branch information
manh-t authored Mar 31, 2022
2 parents c0f6fe7 + 7793f09 commit bc112cf
Show file tree
Hide file tree
Showing 14 changed files with 280 additions and 126 deletions.
10 changes: 8 additions & 2 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# These users will be requested for review when someone opens a pull request.
* @sleepylee @luongvo @manh-t @markgravity @doannimble
# Team Lead
* @manh-t

# Team Members
* @doannimble @luongvo @markgravity

# Engineering Leads
CODEOWNERS @nimblehq/engineering-leads
38 changes: 38 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: CI
on:
# Trigger the workflow on push or pull request,
# but push action is only for the feature branch
pull_request:
types: [ opened, synchronize, edited, reopened ]
push:
branches-ignore:
- develop
- 'release/**'
jobs:
lint_and_test:
name: Static code analyze & Unit test
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/[email protected]

# Setup the flutter environment.
- uses: subosito/flutter-action@v1
with:
channel: 'stable' # 'dev', 'alpha', default to: 'stable'
flutter-version: '2.10.3'

- name: Get flutter dependencies.
run: flutter pub get

- name: Run code generator
run: flutter packages pub run build_runner build --delete-conflicting-outputs

- name: Check for any formatting issues in the code.
run: flutter format --set-exit-if-changed .

- name: Statically analyze the Dart code for any errors.
run: flutter analyze .

- name: Run widget tests, unit tests.
run: flutter test --machine --coverage
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ prepare-dev:
fi
python3 -m pip install pipenv
python3 -m venv $(VENV_NAME)
$(PYTHON) -m pip install enquiries

init: prepare-dev
$(PYTHON) ./scripts/setup.py --project_path $(PWD) --package_name "$(PACKAGE_NAME)" --project_name "$(PROJECT_NAME)" --app_name "$(APP_NAME)" --app_version "$(APP_VERSION)" --build_number "$(BUILD_NUMBER)"
Expand Down
29 changes: 29 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml

linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
6 changes: 6 additions & 0 deletions build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
targets:
$default:
builders:
json_serializable:
options:
field_rename: "snake"
3 changes: 2 additions & 1 deletion integration_test/my_home_page_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

testWidgets('My Home Page widget', (WidgetTester tester) async {
await tester.pumpWidget(TestUtil.pumpWidgetWithShellApp(MyHomePage()));
await tester
.pumpWidget(TestUtil.pumpWidgetWithShellApp(const MyHomePage()));
await tester.pumpAndSettle();

expect(find.widgetWithText(AppBar, 'Flutter templates testing'),
Expand Down
44 changes: 25 additions & 19 deletions lib/api/exception/network_exceptions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,45 +50,51 @@ class NetworkExceptions with _$NetworkExceptions {
if (error is DioError) {
switch (error.type) {
case DioErrorType.cancel:
networkExceptions = NetworkExceptions.requestCancelled();
networkExceptions = const NetworkExceptions.requestCancelled();
break;
case DioErrorType.connectTimeout:
networkExceptions = NetworkExceptions.requestTimeout();
networkExceptions = const NetworkExceptions.requestTimeout();
break;
case DioErrorType.other:
networkExceptions = NetworkExceptions.noInternetConnection();
networkExceptions =
const NetworkExceptions.noInternetConnection();
break;
case DioErrorType.receiveTimeout:
networkExceptions = NetworkExceptions.receiveTimeout();
networkExceptions = const NetworkExceptions.receiveTimeout();
break;
case DioErrorType.sendTimeout:
networkExceptions = NetworkExceptions.sendTimeout();
networkExceptions = const NetworkExceptions.sendTimeout();
break;
case DioErrorType.response:
switch (error.response?.statusCode) {
case 400:
networkExceptions = NetworkExceptions.badRequest();
networkExceptions = const NetworkExceptions.badRequest();
break;
case 401:
networkExceptions = NetworkExceptions.unauthorisedRequest();
networkExceptions =
const NetworkExceptions.unauthorisedRequest();
break;
case 403:
networkExceptions = NetworkExceptions.unauthorisedRequest();
networkExceptions =
const NetworkExceptions.unauthorisedRequest();
break;
case 404:
networkExceptions = NetworkExceptions.notFound("Not found");
networkExceptions =
const NetworkExceptions.notFound("Not found");
break;
case 409:
networkExceptions = NetworkExceptions.conflict();
networkExceptions = const NetworkExceptions.conflict();
break;
case 408:
networkExceptions = NetworkExceptions.requestTimeout();
networkExceptions = const NetworkExceptions.requestTimeout();
break;
case 500:
networkExceptions = NetworkExceptions.internalServerError();
networkExceptions =
const NetworkExceptions.internalServerError();
break;
case 503:
networkExceptions = NetworkExceptions.serviceUnavailable();
networkExceptions =
const NetworkExceptions.serviceUnavailable();
break;
default:
var responseCode = error.response?.statusCode;
Expand All @@ -99,21 +105,21 @@ class NetworkExceptions with _$NetworkExceptions {
break;
}
} else if (error is SocketException) {
networkExceptions = NetworkExceptions.noInternetConnection();
networkExceptions = const NetworkExceptions.noInternetConnection();
} else {
networkExceptions = NetworkExceptions.unexpectedError();
networkExceptions = const NetworkExceptions.unexpectedError();
}
return networkExceptions;
} on FormatException catch (_) {
return NetworkExceptions.formatException();
return const NetworkExceptions.formatException();
} catch (_) {
return NetworkExceptions.unexpectedError();
return const NetworkExceptions.unexpectedError();
}
} else {
if (error.toString().contains("is not a subtype of")) {
return NetworkExceptions.unableToProcess();
return const NetworkExceptions.unableToProcess();
} else {
return NetworkExceptions.unexpectedError();
return const NetworkExceptions.unexpectedError();
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/di/interceptor/app_interceptor.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:dio/dio.dart';

class AppInterceptor extends Interceptor {
bool _requireAuthenticate;
final bool _requireAuthenticate;

AppInterceptor(this._requireAuthenticate);

Expand Down
10 changes: 4 additions & 6 deletions lib/di/provider/dio_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@ import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_templates/di/interceptor/app_interceptor.dart';

const String HEADER_CONTENT_TYPE = 'Content-Type';
const String DEFAULT_CONTENT_TYPE = 'application/json; charset=utf-8';
const String headerContentType = 'Content-Type';
const String defaultContentType = 'application/json; charset=utf-8';

class DioProvider {
Dio? _dio;

Dio getDio() {
if (_dio == null) {
_dio = _createDio();
}
_dio ??= _createDio();
return _dio!;
}

Expand All @@ -32,7 +30,7 @@ class DioProvider {
return dio
..options.connectTimeout = 3000
..options.receiveTimeout = 5000
..options.headers = {HEADER_CONTENT_TYPE: DEFAULT_CONTENT_TYPE}
..options.headers = {headerContentType: defaultContentType}
..interceptors.addAll(interceptors);
}
}
19 changes: 12 additions & 7 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import 'package:package_info_plus/package_info_plus.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterConfig.loadEnvVariables();
runApp(MyApp());
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
// TODO: implement Routes then remove `home: MyHomePage()` and use initialRoute instead.
final String initialRoute;

MyApp({this.initialRoute = '/'});
const MyApp({
Key? key,
this.initialRoute = '/',
}) : super(key: key);

@override
Widget build(BuildContext context) {
Expand All @@ -24,14 +27,16 @@ class MyApp extends StatelessWidget {
brightness: Brightness.light,
fontFamily: Assets.fonts.neuzeit,
),
home: MyHomePage(),
home: const MyHomePage(),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
);
}
}

class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
Expand All @@ -41,25 +46,25 @@ class MyHomePage extends StatelessWidget {
builder: (context, snapshot) {
return snapshot.hasData
? Text(snapshot.data?.appName ?? "")
: SizedBox.shrink();
: const SizedBox.shrink();
}),
),
body: Center(
child: Column(
children: [
SizedBox(height: 24),
const SizedBox(height: 24),
FractionallySizedBox(
widthFactor: 0.5,
child: Image.asset(
Assets.images.nimbleLogo.path,
fit: BoxFit.fitWidth,
),
),
SizedBox(height: 24),
const SizedBox(height: 24),
Text(AppLocalizations.of(context)!.hello),
Text(
FlutterConfig.get('SECRET'),
style: TextStyle(color: Colors.black, fontSize: 24),
style: const TextStyle(color: Colors.black, fontSize: 24),
)
],
),
Expand Down
Loading

0 comments on commit bc112cf

Please sign in to comment.