Skip to content

Commit

Permalink
Merge pull request #81 from Onestop-Agrotech/0.5.0
Browse files Browse the repository at this point in the history
0.5.0
  • Loading branch information
Rahul-Vijay authored Sep 27, 2020
2 parents 4d8176d + b270a14 commit 8dd441e
Show file tree
Hide file tree
Showing 26 changed files with 1,213 additions and 910 deletions.
4 changes: 3 additions & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ android {

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.onestop.seva"
applicationId "com.theonestop.seva"
minSdkVersion 21
targetSdkVersion 29
versionCode flutterVersionCode.toInteger()
Expand Down Expand Up @@ -82,4 +82,6 @@ dependencies {
// For SMS USER CONSENT API
implementation 'com.google.android.gms:play-services-auth:18.1.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:17.4.0'
// For IN APP UPDATES
implementation 'com.google.android.play:core:1.8.0'
}
2 changes: 1 addition & 1 deletion android/app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mvp">
package="com.theonestop.seva">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
Expand Down
4 changes: 2 additions & 2 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mvp">
package="com.theonestop.seva">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
Expand All @@ -15,7 +15,7 @@
android:value="@string/google_maps_api_key" />

<activity
android:name=".MainActivity"
android:name="com.theonestop.seva.MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package com.example.mvp
package com.theonestop.seva

import android.app.Activity
import android.content.*
import android.os.Build
import android.os.Bundle
import android.os.PersistableBundle
import androidx.annotation.NonNull
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
Expand All @@ -19,21 +16,34 @@ import com.google.android.gms.auth.api.credentials.HintRequest
import com.google.android.gms.auth.api.phone.SmsRetriever
import com.google.android.gms.common.api.CommonStatusCodes

// FOR IN APP UPDATES
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
import com.google.android.play.core.install.model.AppUpdateType
import com.google.android.play.core.install.model.UpdateAvailability

// Utilities
import android.util.Log

class MainActivity: FlutterActivity() {

private val CHANNEL = "sms_user_api"
private lateinit var channel: MethodChannel

// For In App Updates
private val UPDATECHANNEL = "update_app"
private lateinit var updateChannel: MethodChannel

// For request hint code
private val CREDENTIAL_PICKER_REQUEST = 1 // Set to an unused request code
// For getting back the SMS
private val SMS_CONSENT_REQUEST = 2
// For in app update call back
private val IN_APP_UPDATE = 3

// Flutter Method Channel API
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
// SMS USER CONSENT
channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
channel.setMethodCallHandler{
call, result ->
Expand All @@ -46,10 +56,50 @@ class MainActivity: FlutterActivity() {
SmsRetriever.getClient(context).startSmsUserConsent(senderPhoneNumber /* or null */)
registerReceiver(smsVerificationReceiver, IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION))
}
"unregisterReceiver" -> unregisterReceiver(smsVerificationReceiver)

}

}
// IN APP UPDATES
updateChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, UPDATECHANNEL)
updateChannel.setMethodCallHandler {
call, result ->
when(call.method){
"checkForUpdate" -> {
doUpdate()
}

}
}
}

// check for update, if exists then update
private fun doUpdate(){
// Creates instance of the manager.
val appUpdateManager = AppUpdateManagerFactory.create(context)

// Returns an intent object that you use to check for an update.
val appUpdateInfoTask = appUpdateManager.appUpdateInfo

// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
// check if update type - IMMEDIATE can be allowed
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)
) {
// Request the update.
appUpdateManager.startUpdateFlowForResult(
// Pass the intent that is returned by 'getAppUpdateInfo()'.
appUpdateInfo,
// Or 'AppUpdateType.FLEXIBLE' for flexible updates.
AppUpdateType.IMMEDIATE,
// The current activity making the update request.
this,
// Include a request code to later monitor this update request.
IN_APP_UPDATE)
}
}
}

private val smsVerificationReceiver = object : BroadcastReceiver(){
Expand Down Expand Up @@ -124,6 +174,11 @@ class MainActivity: FlutterActivity() {
} else {
// Consent denied. User can type OTC manually.
}
IN_APP_UPDATE ->
if(resultCode != Activity.RESULT_OK){
// update has failed
Log.d("update", "Android failed to update")
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion android/app/src/profile/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mvp">
package="com.theonestop.seva">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'com.android.tools.build:gradle:3.6.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.3'
}
Expand Down
49 changes: 49 additions & 0 deletions lib/bloc/productsapi_bloc.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:meta/meta.dart';
import 'package:mvp/domain/product_repository.dart';
import 'package:mvp/models/storeProducts.dart';

part 'productsapi_event.dart';
part 'productsapi_state.dart';

class ProductsapiBloc extends Bloc<ProductsapiEvent, ProductsapiState> {
final ProductRepositoryImpl _productRepository;

ProductsapiBloc(this._productRepository) : super(ProductsapiInitial());

@override
Stream<ProductsapiState> mapEventToState(
ProductsapiEvent event,
) async* {
if (event is GetVegetables) {
try {
yield ProductsapiLoading();
final products = await _productRepository.fetchVegetables();
yield ProductsapiLoaded(products);
} catch (err) {
print(err);
yield ProductsapiError(err.toString());
}
} else if (event is GetFruits) {
try {
yield ProductsapiLoading();
final products = await _productRepository.fetchFruits();
yield ProductsapiLoaded(products);
} catch (err) {
print(err);
yield ProductsapiError(err.toString());
}
} else if (event is GetDailyEssentials) {
try {
yield ProductsapiLoading();
final products = await _productRepository.fetchDailyEssentials();
yield ProductsapiLoaded(products);
} catch (err) {
print(err);
yield ProductsapiError(err.toString());
}
}
}
}
10 changes: 10 additions & 0 deletions lib/bloc/productsapi_event.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
part of 'productsapi_bloc.dart';

@immutable
abstract class ProductsapiEvent {}

class GetVegetables extends ProductsapiEvent {}

class GetFruits extends ProductsapiEvent {}

class GetDailyEssentials extends ProductsapiEvent {}
20 changes: 20 additions & 0 deletions lib/bloc/productsapi_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
part of 'productsapi_bloc.dart';

@immutable
abstract class ProductsapiState {}

class ProductsapiInitial extends ProductsapiState {}

class ProductsapiLoading extends ProductsapiState {}

class ProductsapiLoaded extends ProductsapiState {
final List<StoreProduct> products;

ProductsapiLoaded(this.products);
}

class ProductsapiError extends ProductsapiState {
final String msg;

ProductsapiError(this.msg);
}
23 changes: 23 additions & 0 deletions lib/domain/exceptions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class AppException implements Exception {
final _message;

AppException([this._message]);

String toString() {
return "$_message";
}
}

class FetchDataException extends AppException {
// communication error
FetchDataException([String message]) : super(message);
}

class UnauthorisedException extends AppException {
// Unauthorised
UnauthorisedException([message]) : super(message);
}

class InternalServerError extends AppException {
InternalServerError([message]) : super("Internal Server Error");
}
78 changes: 78 additions & 0 deletions lib/domain/product_repository.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import 'dart:io';

import 'package:mvp/classes/storage_sharedPrefs.dart';
import 'package:mvp/constants/apiCalls.dart';
import 'package:mvp/domain/exceptions.dart';
import 'package:mvp/models/storeProducts.dart';
import 'package:http/http.dart' as http;

abstract class ProductRepository {
Future<List<StoreProduct>> fetchVegetables();
Future<List<StoreProduct>> fetchFruits();
Future<List<StoreProduct>> fetchDailyEssentials();
}

class ProductRepositoryImpl implements ProductRepository {
@override
Future<List<StoreProduct>> fetchVegetables() async {
var responseJson;
try {
StorageSharedPrefs p = new StorageSharedPrefs();
String token = await p.getToken();
String hub = await p.gethub();
Map<String, String> requestHeaders = {'x-auth-token': token};
String url = APIService.getCategorywiseProducts(hub, "vegetable");
final response = await http.get(url, headers: requestHeaders);
responseJson = _returnResponse(response);
return responseJson;
} on SocketException {
throw FetchDataException('No Internet connection');
}
}

Future<List<StoreProduct>> fetchFruits() async {
var responseJson;
try {
StorageSharedPrefs p = new StorageSharedPrefs();
String token = await p.getToken();
String hub = await p.gethub();
Map<String, String> requestHeaders = {'x-auth-token': token};
String url = APIService.getCategorywiseProducts(hub, "fruit");
final response = await http.get(url, headers: requestHeaders);
responseJson = _returnResponse(response);
return responseJson;
} on SocketException {
throw FetchDataException('No Internet connection');
}
}

Future<List<StoreProduct>> fetchDailyEssentials() async {
var responseJson;
try {
StorageSharedPrefs p = new StorageSharedPrefs();
String token = await p.getToken();
String hub = await p.gethub();
Map<String, String> requestHeaders = {'x-auth-token': token};
String url = APIService.getCategorywiseProducts(hub, "dailyEssential");
final response = await http.get(url, headers: requestHeaders);
responseJson = _returnResponse(response);
return responseJson;
} on SocketException {
throw FetchDataException('No Internet connection');
}
}

List<StoreProduct> _returnResponse(http.Response response) {
switch (response.statusCode) {
case 200:
return jsonToCateogrywiseProductModel(response.body);
case 401:
throw UnauthorisedException(response.statusCode.toString());
case 500:
throw InternalServerError();
default:
throw FetchDataException(
'Error occured while Communication with Server with StatusCode : ${response.statusCode}');
}
}
}
Loading

0 comments on commit 8dd441e

Please sign in to comment.