switch RepoDetailsActivity to plain structure, purge RepoDetailsFragment
No need for a reusable Fragment here, its only used in one place. This changes the structure to be a regular Activity, with all View and Menu setup in XML files loaded in onCreate(). This also converts the URL to a TextView. Having it editable in this Activity makes for a confusing user experience. Instead, the "Add Repo" input should validate the URL and not allow creating repos that don't work. This also purges the use of UpdateService.UpdateReceiver, it will be going away in the upcoming commits.
This commit is contained in:
parent
50ac03e97d
commit
7ea294bb66
@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/repoView"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
@ -12,21 +13,14 @@
|
||||
android:paddingRight="@dimen/padding_side"
|
||||
android:paddingEnd="@dimen/padding_side">
|
||||
|
||||
<!-- Editable URL of this repo -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/label_repo_url"
|
||||
android:text="@string/repo_url"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true" />
|
||||
<EditText
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/input_repo_url"
|
||||
android:inputType="textUri"
|
||||
android:layout_below="@id/label_repo_url" />
|
||||
android:textStyle="bold"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true" />
|
||||
|
||||
<!-- Name of this repo -->
|
||||
<TextView
|
||||
|
21
F-Droid/res/menu/repo_details_activity.xml
Normal file
21
F-Droid/res/menu/repo_details_activity.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_update"
|
||||
android:icon="@drawable/ic_refresh_white"
|
||||
android:title="@string/repo_update"
|
||||
app:showAsAction="always|withText" />
|
||||
<item
|
||||
android:id="@+id/menu_delete"
|
||||
android:icon="@drawable/ic_delete_white"
|
||||
android:title="@string/delete"
|
||||
app:showAsAction="ifRoom|withText" />
|
||||
<item
|
||||
android:id="@+id/menu_enable_nfc"
|
||||
android:icon="@drawable/ic_nfc_white"
|
||||
android:title="@string/enable_nfc_send"
|
||||
app:showAsAction="ifRoom|withText" />
|
||||
|
||||
</menu>
|
@ -74,7 +74,6 @@ import org.fdroid.fdroid.data.RepoProvider;
|
||||
import org.fdroid.fdroid.net.MDnsHelper;
|
||||
import org.fdroid.fdroid.net.MDnsHelper.DiscoveredRepo;
|
||||
import org.fdroid.fdroid.net.MDnsHelper.RepoScanListAdapter;
|
||||
import org.fdroid.fdroid.views.fragments.RepoDetailsFragment;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
@ -888,7 +887,7 @@ public class ManageReposActivity extends ActionBarActivity {
|
||||
|
||||
public void editRepo(Repo repo) {
|
||||
Intent intent = new Intent(getActivity(), RepoDetailsActivity.class);
|
||||
intent.putExtra(RepoDetailsFragment.ARG_REPO_ID, repo.getId());
|
||||
intent.putExtra(RepoDetailsActivity.ARG_REPO_ID, repo.getId());
|
||||
startActivityForResult(intent, SHOW_REPO_DETAILS);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
package org.fdroid.fdroid.views;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.ContentValues;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.nfc.NdefMessage;
|
||||
@ -8,26 +10,76 @@ import android.nfc.NfcAdapter;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.LinearLayout;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.fdroid.fdroid.FDroidApp;
|
||||
import org.fdroid.fdroid.NfcHelper;
|
||||
import org.fdroid.fdroid.NfcNotEnabledActivity;
|
||||
import org.fdroid.fdroid.ProgressListener;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.UpdateService;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.data.Repo;
|
||||
import org.fdroid.fdroid.data.RepoProvider;
|
||||
import org.fdroid.fdroid.views.fragments.RepoDetailsFragment;
|
||||
|
||||
public class RepoDetailsActivity extends ActionBarActivity {
|
||||
private static final String TAG = "RepoDetailsActivity";
|
||||
|
||||
private Repo repo;
|
||||
public static final String MIME_TYPE = "application/vnd.org.fdroid.fdroid.repo";
|
||||
public static final String ARG_REPO_ID = "repo_id";
|
||||
|
||||
static final String MIME_TYPE = "application/vnd.org.fdroid.fdroid.repo";
|
||||
/**
|
||||
* If the repo has been updated at least once, then we will show
|
||||
* all of this info, otherwise they will be hidden.
|
||||
*/
|
||||
private static final int[] SHOW_IF_EXISTS = {
|
||||
R.id.label_repo_name,
|
||||
R.id.text_repo_name,
|
||||
R.id.label_description,
|
||||
R.id.text_description,
|
||||
R.id.label_num_apps,
|
||||
R.id.text_num_apps,
|
||||
R.id.label_last_update,
|
||||
R.id.text_last_update,
|
||||
R.id.label_repo_fingerprint,
|
||||
R.id.text_repo_fingerprint,
|
||||
R.id.text_repo_fingerprint_description
|
||||
};
|
||||
/**
|
||||
* If the repo has <em>not</em> been updated yet, then we only show
|
||||
* these, otherwise they are hidden.
|
||||
*/
|
||||
private static final int[] HIDE_IF_EXISTS = {
|
||||
R.id.text_not_yet_updated,
|
||||
R.id.btn_update
|
||||
};
|
||||
private Repo repo;
|
||||
private long repoId;
|
||||
private View repoView;
|
||||
|
||||
/**
|
||||
* Help function to make switching between two view states easier.
|
||||
* Perhaps there is a better way to do this. I recall that using Adobe
|
||||
* Flex, there was a thing called "ViewStates" for exactly this. Wonder if
|
||||
* that exists in Android?
|
||||
*/
|
||||
private static void setMultipleViewVisibility(View parent,
|
||||
int[] viewIds,
|
||||
int visibility) {
|
||||
for (int viewId : viewIds) {
|
||||
parent.findViewById(viewId).setVisibility(visibility);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -35,27 +87,11 @@ public class RepoDetailsActivity extends ActionBarActivity {
|
||||
((FDroidApp) getApplication()).applyTheme(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
long repoId = getIntent().getLongExtra(RepoDetailsFragment.ARG_REPO_ID, 0);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
|
||||
// Need to set a dummy view (which will get overridden by the fragment manager
|
||||
// below) so that we can call setContentView(). This is a work around for
|
||||
// a (bug?) thing in 3.0, 3.1 which requires setContentView to be invoked before
|
||||
// the actionbar is played with:
|
||||
// http://blog.perpetumdesign.com/2011/08/strange-case-of-dr-action-and-mr-bar.html
|
||||
if (Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT <= 13) {
|
||||
setContentView(new LinearLayout(this));
|
||||
}
|
||||
|
||||
RepoDetailsFragment fragment = new RepoDetailsFragment();
|
||||
fragment.setArguments(getIntent().getExtras());
|
||||
getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.add(android.R.id.content, fragment)
|
||||
.commit();
|
||||
}
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
setContentView(R.layout.repodetails);
|
||||
repoView = findViewById(R.id.repoView);
|
||||
|
||||
repoId = getIntent().getLongExtra(ARG_REPO_ID, 0);
|
||||
final String[] projection = {
|
||||
RepoProvider.DataColumns.NAME,
|
||||
RepoProvider.DataColumns.ADDRESS,
|
||||
@ -63,8 +99,18 @@ public class RepoDetailsActivity extends ActionBarActivity {
|
||||
};
|
||||
repo = RepoProvider.Helper.findById(this, repoId, projection);
|
||||
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
setTitle(repo.getName());
|
||||
setTitle(repo.name);
|
||||
|
||||
TextView inputUrl = (TextView) findViewById(R.id.input_repo_url);
|
||||
inputUrl.setText(repo.address);
|
||||
|
||||
Button update = (Button) repoView.findViewById(R.id.btn_update);
|
||||
update.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
performUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@TargetApi(14)
|
||||
@ -82,6 +128,16 @@ public class RepoDetailsActivity extends ActionBarActivity {
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
/*
|
||||
* After, for example, a repo update, the details will have changed in the
|
||||
* database. However, or local reference to the Repo object will not
|
||||
* have been updated. The safest way to deal with this is to reload the
|
||||
* repo object directly from the database.
|
||||
*/
|
||||
repo = RepoProvider.Helper.findById(this, repoId);
|
||||
updateRepoView();
|
||||
|
||||
// FDroid.java and AppDetails set different NFC actions, so reset here
|
||||
setNfc();
|
||||
processIntent(getIntent());
|
||||
@ -112,14 +168,177 @@ public class RepoDetailsActivity extends ActionBarActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.repo_details_activity, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
NavUtils.navigateUpFromSameTask(this);
|
||||
return true;
|
||||
case R.id.menu_update:
|
||||
performUpdate();
|
||||
return true;
|
||||
case R.id.menu_delete:
|
||||
promptForDelete();
|
||||
return true;
|
||||
case R.id.menu_enable_nfc:
|
||||
Intent intent = new Intent(this, NfcNotEnabledActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
if (Build.VERSION.SDK_INT >= 14) {
|
||||
prepareNfcMenuItems(menu);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@TargetApi(16)
|
||||
private void prepareNfcMenuItems(Menu menu) {
|
||||
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
|
||||
if (nfcAdapter == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean needsEnableNfcMenuItem;
|
||||
if (Build.VERSION.SDK_INT < 16) {
|
||||
needsEnableNfcMenuItem = !nfcAdapter.isEnabled();
|
||||
} else {
|
||||
needsEnableNfcMenuItem = !nfcAdapter.isNdefPushEnabled();
|
||||
}
|
||||
|
||||
MenuItem menuItem = menu.findItem(R.id.menu_enable_nfc);
|
||||
menuItem.setVisible(needsEnableNfcMenuItem);
|
||||
}
|
||||
|
||||
private void setupDescription(View parent, Repo repo) {
|
||||
|
||||
TextView descriptionLabel = (TextView) parent.findViewById(R.id.label_description);
|
||||
TextView description = (TextView) parent.findViewById(R.id.text_description);
|
||||
|
||||
if (TextUtils.isEmpty(repo.description)) {
|
||||
descriptionLabel.setVisibility(View.GONE);
|
||||
description.setVisibility(View.GONE);
|
||||
description.setText("");
|
||||
} else {
|
||||
descriptionLabel.setVisibility(View.VISIBLE);
|
||||
description.setVisibility(View.VISIBLE);
|
||||
description.setText(repo.description.replaceAll("\n", " "));
|
||||
}
|
||||
}
|
||||
|
||||
private void setupRepoFingerprint(View parent, Repo repo) {
|
||||
TextView repoFingerprintView = (TextView) parent.findViewById(R.id.text_repo_fingerprint);
|
||||
TextView repoFingerprintDescView = (TextView) parent.findViewById(R.id.text_repo_fingerprint_description);
|
||||
|
||||
String repoFingerprint;
|
||||
int repoFingerprintColor;
|
||||
|
||||
// TODO show the current state of the signature check, not just whether there is a key or not
|
||||
if (TextUtils.isEmpty(repo.fingerprint) && TextUtils.isEmpty(repo.pubkey)) {
|
||||
repoFingerprint = getResources().getString(R.string.unsigned);
|
||||
repoFingerprintColor = getResources().getColor(R.color.unsigned);
|
||||
repoFingerprintDescView.setVisibility(View.VISIBLE);
|
||||
repoFingerprintDescView.setText(getResources().getString(R.string.unsigned_description));
|
||||
} else {
|
||||
// this is based on repo.fingerprint always existing, which it should
|
||||
repoFingerprint = Utils.formatFingerprint(this, repo.fingerprint);
|
||||
repoFingerprintColor = getResources().getColor(R.color.signed);
|
||||
repoFingerprintDescView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
repoFingerprintView.setText(repoFingerprint);
|
||||
repoFingerprintView.setTextColor(repoFingerprintColor);
|
||||
}
|
||||
|
||||
private void updateRepoView() {
|
||||
|
||||
if (repo.hasBeenUpdated()) {
|
||||
updateViewForExistingRepo(repoView);
|
||||
} else {
|
||||
updateViewForNewRepo(repoView);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateViewForNewRepo(View repoView) {
|
||||
setMultipleViewVisibility(repoView, HIDE_IF_EXISTS, View.VISIBLE);
|
||||
setMultipleViewVisibility(repoView, SHOW_IF_EXISTS, View.GONE);
|
||||
}
|
||||
|
||||
private void updateViewForExistingRepo(View repoView) {
|
||||
setMultipleViewVisibility(repoView, SHOW_IF_EXISTS, View.VISIBLE);
|
||||
setMultipleViewVisibility(repoView, HIDE_IF_EXISTS, View.GONE);
|
||||
|
||||
TextView name = (TextView) repoView.findViewById(R.id.text_repo_name);
|
||||
TextView numApps = (TextView) repoView.findViewById(R.id.text_num_apps);
|
||||
TextView lastUpdated = (TextView) repoView.findViewById(R.id.text_last_update);
|
||||
|
||||
name.setText(repo.name);
|
||||
|
||||
int appCount = RepoProvider.Helper.countAppsForRepo(this, repoId);
|
||||
numApps.setText(Integer.toString(appCount));
|
||||
|
||||
setupDescription(repoView, repo);
|
||||
setupRepoFingerprint(repoView, repo);
|
||||
|
||||
// Repos that existed before this feature was supported will have an
|
||||
// "Unknown" last update until next time they update...
|
||||
String lastUpdate = repo.lastUpdated != null
|
||||
? repo.lastUpdated.toString() : getString(R.string.unknown);
|
||||
lastUpdated.setText(lastUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* When an update is performed, notify the listener so that the repo
|
||||
* list can be updated. We will perform the update ourselves though.
|
||||
*/
|
||||
private void performUpdate() {
|
||||
// Ensure repo is enabled before updating...
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(RepoProvider.DataColumns.IN_USE, 1);
|
||||
RepoProvider.Helper.update(this, repo, values);
|
||||
|
||||
UpdateService.updateRepoNow(repo.address, this).setListener(new ProgressListener() {
|
||||
@Override
|
||||
public void onProgress(Event event) {
|
||||
switch (event.type) {
|
||||
case UpdateService.EVENT_COMPLETE_WITH_CHANGES:
|
||||
updateRepoView();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void promptForDelete() {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.repo_confirm_delete_title)
|
||||
.setMessage(R.string.repo_confirm_delete_body)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
RepoProvider.Helper.remove(getApplicationContext(), repoId);
|
||||
finish();
|
||||
}
|
||||
}).setNegativeButton(android.R.string.cancel,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
// Do nothing...
|
||||
}
|
||||
}
|
||||
).show();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,392 +0,0 @@
|
||||
package org.fdroid.fdroid.views.fragments;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.ContentValues;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.fdroid.fdroid.NfcNotEnabledActivity;
|
||||
import org.fdroid.fdroid.ProgressListener;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.UpdateService;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.data.Repo;
|
||||
import org.fdroid.fdroid.data.RepoProvider;
|
||||
|
||||
public class RepoDetailsFragment extends Fragment {
|
||||
|
||||
public static final String ARG_REPO_ID = "repo_id";
|
||||
|
||||
/**
|
||||
* If the repo has been updated at least once, then we will show
|
||||
* all of this info, otherwise they will be hidden.
|
||||
*/
|
||||
private static final int[] SHOW_IF_EXISTS = {
|
||||
R.id.label_repo_name,
|
||||
R.id.text_repo_name,
|
||||
R.id.label_description,
|
||||
R.id.text_description,
|
||||
R.id.label_num_apps,
|
||||
R.id.text_num_apps,
|
||||
R.id.label_last_update,
|
||||
R.id.text_last_update,
|
||||
R.id.label_repo_fingerprint,
|
||||
R.id.text_repo_fingerprint,
|
||||
R.id.text_repo_fingerprint_description
|
||||
};
|
||||
|
||||
/**
|
||||
* If the repo has <em>not</em> been updated yet, then we only show
|
||||
* these, otherwise they are hidden.
|
||||
*/
|
||||
private static final int[] HIDE_IF_EXISTS = {
|
||||
R.id.text_not_yet_updated,
|
||||
R.id.btn_update
|
||||
};
|
||||
|
||||
private static final int DELETE = 0;
|
||||
private static final int UPDATE = 1;
|
||||
private static final int ENABLE_NFC = 2;
|
||||
|
||||
private static final String TAG = "RepoDetailsFragment";
|
||||
|
||||
private MenuItem enableNfc = null;
|
||||
private UpdateService.UpdateReceiver updateHandler = null;
|
||||
|
||||
// TODO: Currently initialised in onCreateView. Not sure if that is the
|
||||
// best way to go about this...
|
||||
private Repo repo;
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
if (updateHandler != null) {
|
||||
updateHandler.showDialog(getActivity());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
if (updateHandler != null) {
|
||||
updateHandler.hideDialog();
|
||||
}
|
||||
}
|
||||
|
||||
private long getRepoId() {
|
||||
return getArguments().getLong(RepoDetailsFragment.ARG_REPO_ID, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* After, for example, a repo update, the details will have changed in the
|
||||
* database. However, or local reference to the Repo object will not
|
||||
* have been updated. The safest way to deal with this is to reload the
|
||||
* repo object directly from the database.
|
||||
*/
|
||||
private Repo loadRepoDetails() {
|
||||
return RepoProvider.Helper.findById(getActivity(), getRepoId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
repo = loadRepoDetails();
|
||||
|
||||
if (repo == null) {
|
||||
Log.e(TAG, "Error showing details for repo '" + getRepoId() + "'");
|
||||
return new LinearLayout(container.getContext());
|
||||
}
|
||||
|
||||
ViewGroup repoView = (ViewGroup)inflater.inflate(R.layout.repodetails, null);
|
||||
updateView(repoView);
|
||||
|
||||
// Setup listeners here, rather than in updateView(...),
|
||||
// because otherwise we will end up adding multiple listeners with
|
||||
// subsequent calls to updateView().
|
||||
EditText inputUrl = (EditText)repoView.findViewById(R.id.input_repo_url);
|
||||
inputUrl.addTextChangedListener(new UrlWatcher());
|
||||
|
||||
Button update = (Button)repoView.findViewById(R.id.btn_update);
|
||||
update.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
performUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
return repoView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates relevant views with properties from the current repository.
|
||||
* Decides which views to show and hide depending on the state of the
|
||||
* repository.
|
||||
*/
|
||||
private void updateView(ViewGroup repoView) {
|
||||
|
||||
EditText inputUrl = (EditText)repoView.findViewById(R.id.input_repo_url);
|
||||
inputUrl.setText(repo.address);
|
||||
|
||||
if (repo.hasBeenUpdated()) {
|
||||
updateViewForExistingRepo(repoView);
|
||||
} else {
|
||||
updateViewForNewRepo(repoView);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Help function to make switching between two view states easier.
|
||||
* Perhaps there is a better way to do this. I recall that using Adobe
|
||||
* Flex, there was a thing called "ViewStates" for exactly this. Wonder if
|
||||
* that exists in Android?
|
||||
*/
|
||||
private static void setMultipleViewVisibility(ViewGroup parent,
|
||||
int[] viewIds,
|
||||
int visibility) {
|
||||
for (int viewId : viewIds) {
|
||||
parent.findViewById(viewId).setVisibility(visibility);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateViewForNewRepo(ViewGroup repoView) {
|
||||
setMultipleViewVisibility(repoView, HIDE_IF_EXISTS, View.VISIBLE);
|
||||
setMultipleViewVisibility(repoView, SHOW_IF_EXISTS, View.GONE);
|
||||
}
|
||||
|
||||
private void updateViewForExistingRepo(ViewGroup repoView) {
|
||||
setMultipleViewVisibility(repoView, SHOW_IF_EXISTS, View.VISIBLE);
|
||||
setMultipleViewVisibility(repoView, HIDE_IF_EXISTS, View.GONE);
|
||||
|
||||
TextView name = (TextView)repoView.findViewById(R.id.text_repo_name);
|
||||
TextView numApps = (TextView)repoView.findViewById(R.id.text_num_apps);
|
||||
TextView lastUpdated = (TextView)repoView.findViewById(R.id.text_last_update);
|
||||
|
||||
name.setText(repo.getName());
|
||||
|
||||
int appCount = RepoProvider.Helper.countAppsForRepo(getActivity(), repo.getId());
|
||||
numApps.setText(Integer.toString(appCount));
|
||||
|
||||
setupDescription(repoView, repo);
|
||||
setupRepoFingerprint(repoView, repo);
|
||||
|
||||
// Repos that existed before this feature was supported will have an
|
||||
// "Unknown" last update until next time they update...
|
||||
String lastUpdate = repo.lastUpdated != null
|
||||
? repo.lastUpdated.toString() : getString(R.string.unknown);
|
||||
lastUpdated.setText(lastUpdate);
|
||||
}
|
||||
|
||||
private void setupDescription(ViewGroup parent, Repo repo) {
|
||||
|
||||
TextView descriptionLabel = (TextView)parent.findViewById(R.id.label_description);
|
||||
TextView description = (TextView)parent.findViewById(R.id.text_description);
|
||||
|
||||
if (repo.description == null || repo.description.length() == 0) {
|
||||
descriptionLabel.setVisibility(View.GONE);
|
||||
description.setVisibility(View.GONE);
|
||||
} else {
|
||||
descriptionLabel.setVisibility(View.VISIBLE);
|
||||
description.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
String descriptionText = repo.description == null
|
||||
? "" : repo.description.replaceAll("\n", " ");
|
||||
description.setText(descriptionText);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* When an update is performed, notify the listener so that the repo
|
||||
* list can be updated. We will perform the update ourselves though.
|
||||
*/
|
||||
private void performUpdate() {
|
||||
// Ensure repo is enabled before updating...
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(RepoProvider.DataColumns.IN_USE, 1);
|
||||
RepoProvider.Helper.update(getActivity(), repo, values);
|
||||
|
||||
updateHandler = UpdateService.updateRepoNow(repo.address, getActivity()).setListener(new ProgressListener() {
|
||||
@Override
|
||||
public void onProgress(Event event) {
|
||||
switch (event.type) {
|
||||
case UpdateService.EVENT_COMPLETE_WITH_CHANGES:
|
||||
repo = loadRepoDetails();
|
||||
updateView((ViewGroup)getView());
|
||||
break;
|
||||
case UpdateService.EVENT_FINISHED:
|
||||
updateHandler = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* When the URL is changed, notify the repoChangeListener.
|
||||
*/
|
||||
class UrlWatcher implements TextWatcher {
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {}
|
||||
|
||||
@Override
|
||||
// TODO: This is called each character change, resulting in a DB query.
|
||||
// Doesn't exactly cause performance problems,
|
||||
// but seems silly not to go for more of a "focus out" event then
|
||||
// this "text changed" event.
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
if (!repo.address.equals(s.toString())) {
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(RepoProvider.DataColumns.ADDRESS, s.toString());
|
||||
RepoProvider.Helper.update(getActivity(), repo, values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
menu.clear();
|
||||
|
||||
MenuItem update = menu.add(Menu.NONE, UPDATE, 0, R.string.repo_update);
|
||||
update.setIcon(R.drawable.ic_refresh_white);
|
||||
MenuItemCompat.setShowAsAction(update,
|
||||
MenuItemCompat.SHOW_AS_ACTION_ALWAYS |
|
||||
MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
|
||||
|
||||
MenuItem delete = menu.add(Menu.NONE, DELETE, 0, R.string.delete);
|
||||
delete.setIcon(R.drawable.ic_delete_white);
|
||||
MenuItemCompat.setShowAsAction(delete,
|
||||
MenuItemCompat.SHOW_AS_ACTION_IF_ROOM |
|
||||
MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
if (Build.VERSION.SDK_INT >= 14)
|
||||
prepareNfcMenuItems(menu);
|
||||
}
|
||||
|
||||
@TargetApi(16)
|
||||
private void prepareNfcMenuItems(Menu menu) {
|
||||
boolean needsEnableNfcMenuItem;
|
||||
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
|
||||
if (nfcAdapter == null) {
|
||||
return;
|
||||
}
|
||||
if (Build.VERSION.SDK_INT < 16)
|
||||
needsEnableNfcMenuItem = !nfcAdapter.isEnabled();
|
||||
else
|
||||
needsEnableNfcMenuItem = !nfcAdapter.isNdefPushEnabled();
|
||||
if (needsEnableNfcMenuItem) {
|
||||
if (enableNfc != null)
|
||||
return; // already created
|
||||
enableNfc = menu.add(Menu.NONE, ENABLE_NFC, 0, R.string.enable_nfc_send);
|
||||
enableNfc.setIcon(R.drawable.ic_nfc_white);
|
||||
MenuItemCompat.setShowAsAction(enableNfc,
|
||||
MenuItemCompat.SHOW_AS_ACTION_IF_ROOM |
|
||||
MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
|
||||
} else if (enableNfc != null) {
|
||||
// remove the existing MenuItem since NFC is now enabled
|
||||
menu.removeItem(enableNfc.getItemId());
|
||||
enableNfc = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case DELETE:
|
||||
promptForDelete();
|
||||
return true;
|
||||
case UPDATE:
|
||||
performUpdate();
|
||||
return true;
|
||||
case ENABLE_NFC:
|
||||
Intent intent = new Intent(getActivity(), NfcNotEnabledActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void promptForDelete() {
|
||||
new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.repo_confirm_delete_title)
|
||||
.setMessage(R.string.repo_confirm_delete_body)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Repo repo = RepoDetailsFragment.this.repo;
|
||||
RepoProvider.Helper.remove(getActivity(), repo.getId());
|
||||
getActivity().finish();
|
||||
}
|
||||
}).setNegativeButton(android.R.string.cancel,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
// Do nothing...
|
||||
}
|
||||
}
|
||||
).show();
|
||||
}
|
||||
|
||||
private void setupRepoFingerprint(ViewGroup parent, Repo repo) {
|
||||
TextView repoFingerprintView = (TextView)parent.findViewById(R.id.text_repo_fingerprint);
|
||||
TextView repoFingerprintDescView = (TextView)parent.findViewById(R.id.text_repo_fingerprint_description);
|
||||
|
||||
String repoFingerprint;
|
||||
int repoFingerprintColor;
|
||||
|
||||
// TODO show the current state of the signature check, not just whether there is a key or not
|
||||
if (TextUtils.isEmpty(repo.fingerprint) && TextUtils.isEmpty(repo.pubkey)) {
|
||||
repoFingerprint = getResources().getString(R.string.unsigned);
|
||||
repoFingerprintColor = getResources().getColor(R.color.unsigned);
|
||||
repoFingerprintDescView.setVisibility(View.VISIBLE);
|
||||
repoFingerprintDescView.setText(getResources().getString(R.string.unsigned_description));
|
||||
} else {
|
||||
// this is based on repo.fingerprint always existing, which it should
|
||||
repoFingerprint = Utils.formatFingerprint(getActivity(), repo.fingerprint);
|
||||
repoFingerprintColor = getResources().getColor(R.color.signed);
|
||||
repoFingerprintDescView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
repoFingerprintView.setText(repoFingerprint);
|
||||
repoFingerprintView.setTextColor(repoFingerprintColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
setRetainInstance(true);
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user