move ConnectingView to pure XML view, and remove Receiver superclass

The Receiver superclass is not reusing difficult code, but it is hiding the
simple list of UI configuration that it does.

This also eliminates the "error" TextView and just reuses the existing
TextView for error messages.
This commit is contained in:
Hans-Christoph Steiner 2019-05-15 16:09:49 +02:00
parent 5ddc287ab3
commit 5851ea73e0
3 changed files with 110 additions and 205 deletions
app/src/full
java/org/fdroid/fdroid/views/swap
res/layout

@ -1,188 +0,0 @@
package org.fdroid.fdroid.views.swap;
import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.UpdateService;
import org.fdroid.fdroid.localrepo.SwapView;
public class ConnectingView extends SwapView {
@SuppressWarnings("unused")
private static final String TAG = "ConnectingView";
public ConnectingView(Context context) {
super(context);
}
public ConnectingView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@TargetApi(11)
public ConnectingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(21)
public ConnectingView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
((TextView) findViewById(R.id.heading)).setText(R.string.swap_connecting);
findViewById(R.id.back).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
getActivity().showIntro();
}
});
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
repoUpdateReceiver, new IntentFilter(UpdateService.LOCAL_ACTION_STATUS));
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
prepareSwapReceiver, new IntentFilter(SwapWorkflowActivity.PrepareSwapRepo.ACTION));
}
/**
* Remove relevant listeners/receivers/etc so that they do not receive and process events
* when this view is not in use.
*/
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(repoUpdateReceiver);
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(prepareSwapReceiver);
}
private final BroadcastReceiver repoUpdateReceiver = new ConnectSwapReceiver();
private final BroadcastReceiver prepareSwapReceiver = new PrepareSwapReceiver();
/**
* Listens for feedback about a local repository being prepared:
* * Apk files copied to the LocalHTTPD webroot
* * index.html file prepared
* * Icons will be copied to the webroot in the background and so are not part of this process.
*/
class PrepareSwapReceiver extends Receiver {
@Override
protected String getMessageExtra() {
return SwapWorkflowActivity.PrepareSwapRepo.EXTRA_MESSAGE;
}
protected int getType(Intent intent) {
return intent.getIntExtra(SwapWorkflowActivity.PrepareSwapRepo.EXTRA_TYPE, -1);
}
@Override
protected boolean isComplete(Intent intent) {
return getType(intent) == SwapWorkflowActivity.PrepareSwapRepo.TYPE_COMPLETE;
}
@Override
protected boolean isError(Intent intent) {
return getType(intent) == SwapWorkflowActivity.PrepareSwapRepo.TYPE_ERROR;
}
@Override
protected void onComplete() {
getActivity().onLocalRepoPrepared();
}
}
/**
* Listens for feedback about a repo update process taking place.
* Tracks an index.jar download and show the progress messages
*/
class ConnectSwapReceiver extends Receiver {
@Override
protected String getMessageExtra() {
return UpdateService.EXTRA_MESSAGE;
}
protected int getStatusCode(Intent intent) {
return intent.getIntExtra(UpdateService.EXTRA_STATUS_CODE, -1);
}
@Override
protected boolean isComplete(Intent intent) {
int status = getStatusCode(intent);
return status == UpdateService.STATUS_COMPLETE_AND_SAME ||
status == UpdateService.STATUS_COMPLETE_WITH_CHANGES;
}
@Override
protected boolean isError(Intent intent) {
int status = getStatusCode(intent);
return status == UpdateService.STATUS_ERROR_GLOBAL ||
status == UpdateService.STATUS_ERROR_LOCAL ||
status == UpdateService.STATUS_ERROR_LOCAL_SMALL;
}
@Override
protected void onComplete() {
getActivity().inflateSwapView(R.layout.swap_success);
}
}
abstract class Receiver extends BroadcastReceiver {
protected abstract String getMessageExtra();
protected abstract boolean isComplete(Intent intent);
protected abstract boolean isError(Intent intent);
protected abstract void onComplete();
@Override
public void onReceive(Context context, Intent intent) {
TextView progressText = (TextView) findViewById(R.id.heading);
ProgressBar progressBar = findViewById(R.id.progress_bar);
TextView errorText = (TextView) findViewById(R.id.error);
Button backButton = (Button) findViewById(R.id.back);
String message;
if (intent.hasExtra(getMessageExtra())) {
message = intent.getStringExtra(getMessageExtra());
if (message != null) {
progressText.setText(message);
}
}
progressText.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.VISIBLE);
errorText.setVisibility(View.GONE);
backButton.setVisibility(View.GONE);
if (isError(intent)) {
progressText.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
errorText.setVisibility(View.VISIBLE);
backButton.setVisibility(View.VISIBLE);
return;
}
if (isComplete(intent)) {
onComplete();
}
}
}
}

@ -37,7 +37,10 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import cc.mvdan.accesspoint.WifiApControl;
@ -49,6 +52,7 @@ import org.fdroid.fdroid.NfcHelper;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.QrGenAsyncTask;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.UpdateService;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.App;
@ -336,6 +340,10 @@ public class SwapWorkflowActivity extends AppCompatActivity {
localBroadcastManager.registerReceiver(onWifiStateChanged,
new IntentFilter(WifiStateChangeService.BROADCAST));
localBroadcastManager.registerReceiver(prepareSwapReceiver,
new IntentFilter(SwapWorkflowActivity.PrepareSwapRepo.ACTION));
localBroadcastManager.registerReceiver(repoUpdateReceiver,
new IntentFilter(UpdateService.LOCAL_ACTION_STATUS));
checkIncomingIntent();
showRelevantView();
@ -346,6 +354,8 @@ public class SwapWorkflowActivity extends AppCompatActivity {
super.onPause();
localBroadcastManager.unregisterReceiver(onWifiStateChanged);
localBroadcastManager.unregisterReceiver(prepareSwapReceiver);
localBroadcastManager.unregisterReceiver(repoUpdateReceiver);
}
/**
@ -509,6 +519,9 @@ public class SwapWorkflowActivity extends AppCompatActivity {
case R.layout.swap_nfc:
setUpNfcView();
break;
case R.layout.swap_connecting:
setUpConnectingView();
break;
}
return currentView;
@ -617,7 +630,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
}
/**
* Once the UpdateAsyncTask has finished preparing our repository index, we can
* Once the LocalRepoService has finished preparing our repository index, we can
* show the next screen to the user. This will be one of two things:
* <ol>
* <li>If we directly selected a peer to swap with initially, we will skip straight to getting
@ -1065,4 +1078,95 @@ public class SwapWorkflowActivity extends AppCompatActivity {
});
}
private void setUpConnectingProgressText(String message) {
TextView progressText = container.findViewById(R.id.progress_text);
if (progressText != null && message != null) {
progressText.setVisibility(View.VISIBLE);
progressText.setText(message);
}
}
/**
* Listens for feedback about a local repository being prepared, like APK
* files copied to the LocalHTTPD webroot, the {@code index.html} generated,
* etc. Icons will be copied to the webroot in the background and so are
* not part of this process.
*/
private final BroadcastReceiver prepareSwapReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
setUpConnectingProgressText(intent.getStringExtra(SwapWorkflowActivity.PrepareSwapRepo.EXTRA_MESSAGE));
ProgressBar progressBar = container.findViewById(R.id.progress_bar);
Button backButton = container.findViewById(R.id.back);
if (progressBar == null || backButton == null) {
Utils.debugLog(TAG, "prepareSwapReceiver received intent without view: " + intent);
return;
}
int type = intent.getIntExtra(SwapWorkflowActivity.PrepareSwapRepo.EXTRA_TYPE, -1);
if (type == SwapWorkflowActivity.PrepareSwapRepo.TYPE_ERROR) {
progressBar.setVisibility(View.GONE);
backButton.setVisibility(View.VISIBLE);
return;
} else {
progressBar.setVisibility(View.VISIBLE);
backButton.setVisibility(View.GONE);
}
if (type == SwapWorkflowActivity.PrepareSwapRepo.TYPE_COMPLETE) {
onLocalRepoPrepared();
}
}
};
/**
* Listens for feedback about a repo update process taking place.
* Tracks an index.jar download and show the progress messages
*/
private final BroadcastReceiver repoUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
setUpConnectingProgressText(intent.getStringExtra(UpdateService.EXTRA_MESSAGE));
ProgressBar progressBar = container.findViewById(R.id.progress_bar);
Button backButton = container.findViewById(R.id.back);
if (progressBar == null || backButton == null) {
Utils.debugLog(TAG, "repoUpdateReceiver received intent without view: " + intent);
return;
}
int status = intent.getIntExtra(UpdateService.EXTRA_STATUS_CODE, -1);
if (status == UpdateService.STATUS_ERROR_GLOBAL ||
status == UpdateService.STATUS_ERROR_LOCAL ||
status == UpdateService.STATUS_ERROR_LOCAL_SMALL) {
progressBar.setVisibility(View.GONE);
backButton.setVisibility(View.VISIBLE);
return;
} else {
progressBar.setVisibility(View.VISIBLE);
backButton.setVisibility(View.GONE);
}
if (status == UpdateService.STATUS_COMPLETE_AND_SAME
|| status == UpdateService.STATUS_COMPLETE_WITH_CHANGES) {
inflateSwapView(R.layout.swap_success);
}
}
};
private void setUpConnectingView() {
TextView heading = container.findViewById(R.id.progress_text);
heading.setText(R.string.swap_connecting);
container.findViewById(R.id.back).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showIntro();
}
});
}
}

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.views.swap.ConnectingView
<org.fdroid.fdroid.localrepo.SwapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarColor="@color/swap_bright_blue"
@ -10,7 +10,7 @@
android:layout_height="match_parent">
<TextView
android:id="@+id/heading"
android:id="@+id/progress_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
@ -25,28 +25,17 @@
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_centerInParent="true"
android:layout_below="@+id/heading"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:id="@+id/error"
android:textSize="20sp"
android:textAlignment="center"
android:text="@string/swap_connection_misc_error"
android:visibility="gone"
android:padding="30dp"/>
android:layout_below="@+id/progress_text"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@+id/error"
android:layout_below="@+id/progress_text"
android:id="@+id/back"
android:backgroundTint="@color/swap_light_blue"
android:textColor="@android:color/white"
android:visibility="gone"
android:text="@string/back"/>
</org.fdroid.fdroid.views.swap.ConnectingView>
</org.fdroid.fdroid.localrepo.SwapView>