Skip to content

Commit

Permalink
feat: Implement scanning in F-Droid build variant (#1702)
Browse files Browse the repository at this point in the history
  • Loading branch information
ShridharGoel authored and iamareebjamal committed Jun 28, 2019
1 parent 2086062 commit 777be9f
Show file tree
Hide file tree
Showing 11 changed files with 377 additions and 4 deletions.
3 changes: 3 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ dependencies {
//open-source licenses
playStoreImplementation "com.google.android.gms:play-services-oss-licenses:${versions.play_services}"

// QR Code Scanner
fdroidImplementation 'com.github.blikoon:QRCodeScanner:0.1.2'

//Testing
androidTestImplementation('androidx.test.espresso:espresso-core:3.2.0', {
exclude group: 'com.android.support', module: 'support-annotations'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package com.eventyay.organizer.common.di.module.android;

import com.eventyay.organizer.core.attendee.qrscan.ScanQRActivity;

import dagger.Module;
import dagger.android.ContributesAndroidInjector;

@Module
public abstract class FlavorModule {

@ContributesAndroidInjector(modules = BarcodeFragmentBuildersModule.class)
abstract ScanQRActivity contributeScanQRActivity();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.eventyay.organizer.core.attendee;

import androidx.annotation.NonNull;

import com.eventyay.organizer.data.attendee.Attendee;

public interface ScanQRView {

boolean hasCameraPermission();

void requestCameraPermission();

void showPermissionError(String error);

void onScannedAttendee(Attendee attendee);

void showBarcodePanel(boolean show);

void showMessage(@NonNull int stringRes);

void setTint(boolean matched);

void showProgress(boolean show);

void startScan();
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package com.eventyay.organizer.core.attendee;

import android.content.Context;
import android.widget.Toast;
import android.content.Intent;

import com.eventyay.organizer.R;
import com.eventyay.organizer.core.main.MainActivity;

public class ScanningDecider {

public void openScanQRActivity(Context context, long eventId) {
Toast.makeText(context, R.string.scanning_disabled_message, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context, com.eventyay.organizer.core.attendee.qrscan.ScanQRActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(MainActivity.EVENT_KEY, eventId);
context.startActivity(intent);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
package com.eventyay.organizer.core.attendee.qrscan;

import android.Manifest;
import android.Manifest.permission;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProviders;

import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.blikoon.qrcodescanner.QrCodeActivity;
import com.eventyay.organizer.R;
import com.eventyay.organizer.core.attendee.ScanQRView;
import com.eventyay.organizer.core.attendee.checkin.AttendeeCheckInFragment;
import com.eventyay.organizer.core.main.MainActivity;
import com.eventyay.organizer.data.attendee.Attendee;
import com.eventyay.organizer.ui.ViewUtils;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.ButterKnife;
import dagger.android.AndroidInjection;
import dagger.android.AndroidInjector;
import dagger.android.DispatchingAndroidInjector;
import dagger.android.HasActivityInjector;
import dagger.android.support.DaggerAppCompatActivity;
import io.reactivex.disposables.CompositeDisposable;
import timber.log.Timber;

import static com.eventyay.organizer.ui.ViewUtils.showView;

@SuppressWarnings("PMD.TooManyMethods")
public class ScanQRActivity extends DaggerAppCompatActivity implements ScanQRView, HasActivityInjector {

public static final int PERM_REQ_CODE = 123;
private static final int REQUEST_CODE_QR_SCAN = 101;

@BindView(R.id.barcodePanel)
TextView barcodePanel;

@BindView(R.id.progressBar)
ProgressBar progressBar;

@BindView(R.id.startScanningAgain)
Button startScanningAgain;

@Inject
ViewModelProvider.Factory viewModelFactory;

@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;

private ScanQRViewModel scanQRViewModel;

private final CompositeDisposable compositeDisposable = new CompositeDisposable();

@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
scanQRViewModel = ViewModelProviders.of(this, viewModelFactory).get(ScanQRViewModel.class);

setContentView(R.layout.activity_scan_qr);

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

ButterKnife.bind(this);

onCameraLoaded();

startScanningAgain.setOnClickListener(v -> startScan());
}

@Override
protected void onStart() {
super.onStart();

long eventId = getIntent().getLongExtra(MainActivity.EVENT_KEY, -1);
if (eventId == -1) {
Timber.d("No Event ID provided. Exiting ...");
finish();
return;
}

scanQRViewModel.getProgress().observe(this, this::showProgress);
scanQRViewModel.getError().observe(this, this::showPermissionError);
scanQRViewModel.getMessage().observe(this, this::showMessage);
scanQRViewModel.getTint().observe(this, this::setTint);
scanQRViewModel.getShowBarcodePanelLiveData().observe(this, this::showBarcodePanel);
scanQRViewModel.getOnScannedAttendeeLiveData().observe(this, this::onScannedAttendee);
scanQRViewModel.loadAttendees();
}

@Override
protected void onPause() {
super.onPause();
}

@Override
protected void onResume() {
super.onResume();
}

@Override
protected void onDestroy() {
super.onDestroy();

compositeDisposable.dispose();
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode != PERM_REQ_CODE)
return;

// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
cameraPermissionGranted(true);
} else {
cameraPermissionGranted(false);
}
}

// View Implementation Start

@Override
public boolean hasCameraPermission() {
return ContextCompat.checkSelfPermission(this, permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
}

@Override
public void requestCameraPermission() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERM_REQ_CODE);
}

@Override
public void showPermissionError(String error) {
Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
}

@Override
public void onScannedAttendee(Attendee attendee) {
showToggleDialog(attendee.getId());
}

@Override
public void showBarcodePanel(boolean show) {
showView(barcodePanel, show);
}

@Override
public void showMessage(int stringRes) {
barcodePanel.setText(getString(stringRes));
}

@Override
public void setTint(boolean matched) {
ViewUtils.setTint(barcodePanel,
ContextCompat.getColor(this, matched ? R.color.green_a400 : R.color.red_500)
);
}

@Override
public void showProgress(boolean show) {
showView(progressBar, show);
}

public void onCameraLoaded() {
if (hasCameraPermission()) {
startScan();
} else {
requestCameraPermission();
}
}

public void cameraPermissionGranted(boolean granted) {
if (granted) {
startScan();
} else {
showProgress(false);
showPermissionError("User denied permission");
}
}

@Override
public void startScan() {
Intent i = new Intent(ScanQRActivity.this, QrCodeActivity.class);
startActivityForResult(i, REQUEST_CODE_QR_SCAN);
}

public void onActivityResult(int requestCode, int resultCode, Intent intent) {

if (requestCode == REQUEST_CODE_QR_SCAN) {
if (intent == null)
return;

scanQRViewModel.processBarcode(intent.getStringExtra
("com.blikoon.qrcodescanner.got_qr_scan_relult"));

} else {
super.onActivityResult(requestCode, resultCode, intent);
}
}

public void showToggleDialog(long attendeeId) {
AttendeeCheckInFragment bottomSheetDialogFragment = AttendeeCheckInFragment.newInstance(attendeeId);
bottomSheetDialogFragment.show(getSupportFragmentManager(), bottomSheetDialogFragment.getTag());
bottomSheetDialogFragment.setOnCancelListener(() -> {
ViewUtils.setTint(barcodePanel, ContextCompat.getColor(this, R.color.light_blue_a400));
showBarcodePanel(false);
startScan();
});
}

@Override
public AndroidInjector<Activity> activityInjector() {
return dispatchingAndroidInjector;
}
}
51 changes: 51 additions & 0 deletions app/src/fdroid/res/layout/activity_scan_qr.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_scan_qr"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.eventyay.organizer.core.attendee.qrscan.ScanQRActivity">

<TextView
android:id="@+id/barcodePanel"
style="@style/TextCapsule"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
tools:text="Barcode Value"
tools:visibility="visible" />

<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
tools:visibility="visible" />

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">

<ImageView
android:layout_width="@dimen/avatar_size"
android:layout_height="@dimen/avatar_size"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="@dimen/spacing_large"
android:src="@drawable/qrcode_scan" />

<Button
android:id="@+id/startScanningAgain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/light_blue_500"
android:padding="@dimen/spacing_medium"
android:text="@string/start_scanning_again" />

</LinearLayout>


</androidx.coordinatorlayout.widget.CoordinatorLayout>
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />

<application
android:name="com.eventyay.organizer.OrgaApplication"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public List<Attendee> getAttendees() {
return attendees;
}

private void processBarcode(String barcode) {
public void processBarcode(String barcode) {

Observable.fromIterable(attendees)
.filter(attendee -> attendee.getOrder() != null)
Expand Down Expand Up @@ -141,6 +141,7 @@ private void checkAttendee(Attendee attendee) {
toCheckOut && !attendee.isCheckedIn);

attendee.setChecking(true);
showBarcodePanelLiveData.setValue(true);

if (toCheckIn) {
message.setValue(
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

<dimen name="image_small">50dp</dimen>
<dimen name="image_medium">60dp</dimen>
<dimen name="image_large">70dp</dimen>
<dimen name="progressbar_large">80dp</dimen>

<dimen name="check_in_button_width">100dp</dimen>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="my_account">My Account</string>
<string name="start_scanning_again">Start scanning again</string>

<string-array name="timezones">
<item>Africa/Abidjan</item>
Expand Down
Loading

0 comments on commit 777be9f

Please sign in to comment.