Browse Source

Fix loading of server settings, albels and show proper loading state.

pull/11/head
Eric Kok 12 years ago
parent
commit
fd6ff088b8
  1. 6
      core/res/layout/fragment_details.xml
  2. 4
      core/res/layout/fragment_torrents.xml
  3. 4
      core/res/values/strings.xml
  4. 26
      core/src/org/transdroid/core/gui/TorrentsActivity.java
  5. 26
      core/src/org/transdroid/core/gui/TorrentsFragment.java
  6. 39
      core/src/org/transdroid/core/gui/navigation/Label.java
  7. 3
      core/src/org/transdroid/core/gui/navigation/StatusType.java

6
core/res/layout/fragment_details.xml

@ -15,10 +15,12 @@
<ProgressBar <ProgressBar
android:id="@+id/loading_progress" android:id="@+id/loading_progress"
android:layout_width="wrap_content" android:layout_width="128dp"
android:layout_height="wrap_content" android:layout_height="128dp"
android:layout_gravity="center" android:layout_gravity="center"
android:indeterminate="true"
android:indeterminateDrawable="@drawable/loading_progress" android:indeterminateDrawable="@drawable/loading_progress"
android:indeterminateOnly="true"
android:visibility="gone" /> android:visibility="gone" />
<TextView <TextView

4
core/res/layout/fragment_torrents.xml

@ -13,8 +13,8 @@
<ProgressBar <ProgressBar
android:id="@+id/loading_progress" android:id="@+id/loading_progress"
android:layout_width="wrap_content" android:layout_width="128dp"
android:layout_height="wrap_content" android:layout_height="128dp"
android:layout_gravity="center" android:layout_gravity="center"
android:indeterminate="true" android:indeterminate="true"
android:indeterminateDrawable="@drawable/loading_progress" android:indeterminateDrawable="@drawable/loading_progress"

4
core/res/values/strings.xml

@ -52,14 +52,14 @@
<string name="navigation_status_onlyactive">Active</string> <string name="navigation_status_onlyactive">Active</string>
<string name="navigation_status_onlyinactive">Inactive</string> <string name="navigation_status_onlyinactive">Inactive</string>
<string name="status_status">Status: %1$s</string> <string name="status_status">STATUS: %1$s</string>
<string name="status_waiting">Waiting to check&#8230;</string> <string name="status_waiting">Waiting to check&#8230;</string>
<string name="status_checking">Verifying local data&#8230;</string> <string name="status_checking">Verifying local data&#8230;</string>
<string name="status_waitingtodl">Waiting to download %s</string> <string name="status_waitingtodl">Waiting to download %s</string>
<string name="status_error">Error&#8230;</string> <string name="status_error">Error&#8230;</string>
<string name="status_size1">%1$s OF %2$s (%3$s)</string> <string name="status_size1">%1$s OF %2$s (%3$s)</string>
<string name="status_size2">%1$s, UPLOADED %2$s</string> <string name="status_size2">%1$s, UPLOADED %2$s</string>
<string name="status_sincedate">SINCE $1%s</string> <string name="status_sincedate">SINCE %1$s</string>
<string name="status_eta">~ %1$s</string> <string name="status_eta">~ %1$s</string>
<string name="status_etalong">ETA %1$s</string> <string name="status_etalong">ETA %1$s</string>
<string name="status_unknowneta">UNKNOWN ETA</string> <string name="status_unknowneta">UNKNOWN ETA</string>

26
core/src/org/transdroid/core/gui/TorrentsActivity.java

@ -23,7 +23,6 @@ import org.transdroid.core.gui.log.Log;
import org.transdroid.core.gui.log.Log_; import org.transdroid.core.gui.log.Log_;
import org.transdroid.core.gui.navigation.*; import org.transdroid.core.gui.navigation.*;
import org.transdroid.core.gui.navigation.NavigationSelectionView.NavigationFilterManager; import org.transdroid.core.gui.navigation.NavigationSelectionView.NavigationFilterManager;
import org.transdroid.core.gui.navigation.StatusType;
import org.transdroid.core.gui.settings.*; import org.transdroid.core.gui.settings.*;
import org.transdroid.daemon.Daemon; import org.transdroid.daemon.Daemon;
import org.transdroid.daemon.IDaemonAdapter; import org.transdroid.daemon.IDaemonAdapter;
@ -162,8 +161,8 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
return; return;
} }
// TODO: See if this does not mean the refresh is called twice (first in onCreate) // TODO: See if this does not mean the refresh is called twice (first in onCreate)
// There is a server now: select it to establish a connection // There is a server know (now): forcefully select it to establish a connection
filterSelected(lastUsed); filterSelected(lastUsed, true);
} }
@TargetApi(Build.VERSION_CODES.FROYO) @TargetApi(Build.VERSION_CODES.FROYO)
@ -230,7 +229,7 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
Object item = navigationSpinnerAdapter.getItem(itemPosition); Object item = navigationSpinnerAdapter.getItem(itemPosition);
if (item instanceof SimpleListItem) { if (item instanceof SimpleListItem) {
// A filter item was selected form the navigation spinner // A filter item was selected form the navigation spinner
filterSelected((SimpleListItem) item); filterSelected((SimpleListItem) item, false);
return true; return true;
} }
// A header was selected; no action // A header was selected; no action
@ -243,7 +242,7 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
protected OnItemSelectedListener onFilterListItemSelected = new OnItemSelectedListener() { protected OnItemSelectedListener onFilterListItemSelected = new OnItemSelectedListener() {
@Override @Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
filterSelected((SimpleListItem) filtersList.getAdapter().getItem(position)); filterSelected((SimpleListItem) filtersList.getAdapter().getItem(position), false);
} }
@Override @Override
@ -254,10 +253,10 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
/** /**
* A new filter was selected; update the view over the current data * A new filter was selected; update the view over the current data
* @param selected True if the filter item was selected, false if it was deselected
* @param item The touched filter item * @param item The touched filter item
* @param forceNewConnection Whether a new connection should be initialised regardless of the old server selection
*/ */
protected void filterSelected(SimpleListItem item) { protected void filterSelected(SimpleListItem item, boolean forceNewConnection) {
// Server selection // Server selection
if (item instanceof ServerSetting) { if (item instanceof ServerSetting) {
@ -265,6 +264,7 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
if (currentConnection != null && server.equals(currentConnection.getSettings())) { if (currentConnection != null && server.equals(currentConnection.getSettings())) {
// Already connected to this server; just ask for a refresh instead // Already connected to this server; just ask for a refresh instead
fragmentTorrents.updateIsLoading(true);
refreshTorrents(); refreshTorrents();
return; return;
} }
@ -277,6 +277,7 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
if (fragmentDetails != null) { if (fragmentDetails != null) {
fragmentDetails.clear(); fragmentDetails.clear();
} }
fragmentTorrents.updateIsLoading(true);
updateFragmentVisibility(true); updateFragmentVisibility(true);
refreshTorrents(); refreshTorrents();
return; return;
@ -325,6 +326,7 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
@OptionsItem(resName = "action_refresh") @OptionsItem(resName = "action_refresh")
protected void refreshScreen() { protected void refreshScreen() {
fragmentTorrents.updateIsLoading(true);
refreshTorrents(); refreshTorrents();
if (Daemon.supportsStats(currentConnection.getType())) if (Daemon.supportsStats(currentConnection.getType()))
getAdditionalStats(); getAdditionalStats();
@ -352,9 +354,7 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
@Background @Background
protected void refreshTorrents() { protected void refreshTorrents() {
fragmentTorrents.updateIsLoading(true);
DaemonTaskResult result = RetrieveTask.create(currentConnection).execute(); DaemonTaskResult result = RetrieveTask.create(currentConnection).execute();
fragmentTorrents.updateIsLoading(false);
if (result instanceof RetrieveTaskSuccessResult) { if (result instanceof RetrieveTaskSuccessResult) {
onTorrentsRetrieved(((RetrieveTaskSuccessResult) result).getTorrents(), onTorrentsRetrieved(((RetrieveTaskSuccessResult) result).getTorrents(),
((RetrieveTaskSuccessResult) result).getLabels()); ((RetrieveTaskSuccessResult) result).getLabels());
@ -489,24 +489,28 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
Log.i(this, result.getException().toString()); Log.i(this, result.getException().toString());
String error = getString(LocalTorrent.getResourceForDaemonException(result.getException())); String error = getString(LocalTorrent.getResourceForDaemonException(result.getException()));
Crouton.showText(this, error, navigationHelper.CROUTON_ERROR_STYLE); Crouton.showText(this, error, navigationHelper.CROUTON_ERROR_STYLE);
fragmentTorrents.updateIsLoading(false);
fragmentTorrents.updateError(error); fragmentTorrents.updateError(error);
} }
@UiThread @UiThread
protected void onTorrentsRetrieved(List<Torrent> torrents, List<org.transdroid.daemon.Label> labels) { protected void onTorrentsRetrieved(List<Torrent> torrents, List<org.transdroid.daemon.Label> labels) {
// Report the newly retrieved list of torrents to the torrents fragment // Report the newly retrieved list of torrents to the torrents fragment
fragmentTorrents.updateIsLoading(false);
fragmentTorrents.updateTorrents(new ArrayList<Torrent>(torrents)); fragmentTorrents.updateTorrents(new ArrayList<Torrent>(torrents));
// Update the details fragment if the currently shown torrent is in the newly retrieved list // Update the details fragment if the currently shown torrent is in the newly retrieved list
if (fragmentDetails != null) { if (fragmentDetails != null) {
fragmentDetails.perhapsUpdateTorrent(torrents); fragmentDetails.perhapsUpdateTorrent(torrents);
} }
// Update local list of labels in the navigation // Update local list of labels in the navigation
List<Label> navigationLabels = Label.convertToNavigationLabels(labels,
getResources().getString(R.string.labels_unlabeled));
if (navigationListAdapter != null) { if (navigationListAdapter != null) {
// Labels are shown in the dedicated side navigation // Labels are shown in the dedicated side navigation
navigationListAdapter.updateLabels(Label.convertToNavigationLabels(labels)); navigationListAdapter.updateLabels(navigationLabels);
} else { } else {
// Labels are shown in the action bar spinner // Labels are shown in the action bar spinner
navigationSpinnerAdapter.updateLabels(Label.convertToNavigationLabels(labels)); navigationSpinnerAdapter.updateLabels(navigationLabels);
} }
} }

26
core/src/org/transdroid/core/gui/TorrentsFragment.java

@ -7,10 +7,10 @@ import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EFragment; import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.InstanceState; import org.androidannotations.annotations.InstanceState;
import org.androidannotations.annotations.ItemClick; import org.androidannotations.annotations.ItemClick;
import org.androidannotations.annotations.UiThread;
import org.androidannotations.annotations.ViewById; import org.androidannotations.annotations.ViewById;
import org.transdroid.core.R; import org.transdroid.core.R;
import org.transdroid.core.gui.lists.*; import org.transdroid.core.gui.lists.TorrentsAdapter;
import org.transdroid.core.gui.lists.TorrentsAdapter_;
import org.transdroid.core.gui.navigation.NavigationFilter; import org.transdroid.core.gui.navigation.NavigationFilter;
import org.transdroid.daemon.Torrent; import org.transdroid.daemon.Torrent;
@ -83,7 +83,7 @@ public class TorrentsFragment extends SherlockFragment {
*/ */
public void applyFilter(NavigationFilter currentFilter) { public void applyFilter(NavigationFilter currentFilter) {
this.currentFilter = currentFilter; this.currentFilter = currentFilter;
if (torrents != null) { if (torrents != null && currentFilter != null) {
// Build a local list of torrents that match the selected navigation filter // Build a local list of torrents that match the selected navigation filter
ArrayList<Torrent> filteredTorrents = new ArrayList<Torrent>(); ArrayList<Torrent> filteredTorrents = new ArrayList<Torrent>();
for (Torrent torrent : torrents) { for (Torrent torrent : torrents) {
@ -91,6 +91,9 @@ public class TorrentsFragment extends SherlockFragment {
filteredTorrents.add(torrent); filteredTorrents.add(torrent);
} }
((TorrentsAdapter) torrentsList.getAdapter()).update(filteredTorrents); ((TorrentsAdapter) torrentsList.getAdapter()).update(filteredTorrents);
} else if (torrents != null) {
// No need to filter any torrents; directly show the full list
((TorrentsAdapter) torrentsList.getAdapter()).update(torrents);
} }
updateViewVisibility(); updateViewVisibility();
} }
@ -171,7 +174,7 @@ public class TorrentsFragment extends SherlockFragment {
/** /**
* Updates the shown screen depending on whether we have a connection (so torrents can be shown) or not (in case we * Updates the shown screen depending on whether we have a connection (so torrents can be shown) or not (in case we
* need to show a message suggesting help) * need to show a message suggesting help). This should only ever be called on the UI thread.
* @param hasAConnection True if the user has servers configured and therefore has a connection that can be used * @param hasAConnection True if the user has servers configured and therefore has a connection that can be used
*/ */
public void updateConnectionStatus(boolean hasAConnection) { public void updateConnectionStatus(boolean hasAConnection) {
@ -184,7 +187,8 @@ public class TorrentsFragment extends SherlockFragment {
} }
/** /**
* Updates the shown screen depending on whether the torrents are loading * Updates the shown screen depending on whether the torrents are loading. This should only ever be called on the UI
* thread.
* @param isLoading True if the list of torrents is (re)loading, false otherwise * @param isLoading True if the list of torrents is (re)loading, false otherwise
*/ */
public void updateIsLoading(boolean isLoading) { public void updateIsLoading(boolean isLoading) {
@ -197,7 +201,8 @@ public class TorrentsFragment extends SherlockFragment {
} }
/** /**
* Updates the shown screen depending on whether a connection error occurred * Updates the shown screen depending on whether a connection error occurred. This should only ever be called on the
* UI thread.
* @param connectionErrorMessage The error message from the last failed connection attempt, or null to clear the * @param connectionErrorMessage The error message from the last failed connection attempt, or null to clear the
* visible error text * visible error text
*/ */
@ -211,8 +216,7 @@ public class TorrentsFragment extends SherlockFragment {
} }
} }
@UiThread private void updateViewVisibility() {
protected void updateViewVisibility() {
if (!hasAConnection) { if (!hasAConnection) {
torrentsList.setVisibility(View.GONE); torrentsList.setVisibility(View.GONE);
emptyText.setVisibility(View.GONE); emptyText.setVisibility(View.GONE);
@ -222,10 +226,10 @@ public class TorrentsFragment extends SherlockFragment {
return; return;
} }
boolean isEmpty = torrents == null || torrentsList.getAdapter().isEmpty(); boolean isEmpty = torrents == null || torrentsList.getAdapter().isEmpty();
boolean hasError = connectionErrorMessage == null; boolean hasError = connectionErrorMessage != null;
nosettingsText.setVisibility(View.GONE); nosettingsText.setVisibility(View.GONE);
errorText.setVisibility(hasError? View.VISIBLE : View.GONE); errorText.setVisibility(hasError ? View.VISIBLE : View.GONE);
torrentsList.setVisibility(!hasError && !isLoading && !isEmpty ? View.GONE : View.VISIBLE); torrentsList.setVisibility(!hasError && !isLoading && !isEmpty ? View.VISIBLE : View.GONE);
loadingProgress.setVisibility(!hasError && isLoading ? View.VISIBLE : View.GONE); loadingProgress.setVisibility(!hasError && isLoading ? View.VISIBLE : View.GONE);
emptyText.setVisibility(!hasError && !isLoading && isEmpty ? View.VISIBLE : View.GONE); emptyText.setVisibility(!hasError && !isLoading && isEmpty ? View.VISIBLE : View.GONE);
} }

39
core/src/org/transdroid/core/gui/navigation/Label.java

@ -8,6 +8,7 @@ import org.transdroid.daemon.Torrent;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.text.TextUtils;
/** /**
* Represents some label that is active or available on the server. * Represents some label that is active or available on the server.
@ -15,6 +16,8 @@ import android.os.Parcelable;
*/ */
public class Label implements SimpleListItem, NavigationFilter { public class Label implements SimpleListItem, NavigationFilter {
private static String unnamedLabelText = null;
private final String name; private final String name;
private final int count; private final int count;
@ -25,42 +28,56 @@ public class Label implements SimpleListItem, NavigationFilter {
@Override @Override
public String getName() { public String getName() {
if (TextUtils.isEmpty(this.name))
return unnamedLabelText;
return this.name; return this.name;
} }
public int getCount() { public int getCount() {
return count; return count;
} }
/**
* Returns true if the torrent label's name matches this (selected) label's name, false otherwise
*/
@Override @Override
public boolean matches(Torrent torrent) { public boolean matches(Torrent torrent) {
return torrent.getLabelName() != null && torrent.getLabelName().equals(name); return torrent.getLabelName() != null && torrent.getLabelName().equals(name);
} }
public static List<Label> convertToNavigationLabels(List<org.transdroid.daemon.Label> daemonLabels) { /**
* Converts a list of labels as retrieved from a server daemon into a list of labels that can be used in the UI as
* navigation filters.
* @param daemonLabels The raw list of labels as received from the server daemon adapter
* @param unnamedLabel The text to show for the empty label (i.e. the unnamed label)
* @return A label items that can be used in a filter list such as the action bar spinner
*/
public static List<Label> convertToNavigationLabels(List<org.transdroid.daemon.Label> daemonLabels,
String unnamedLabel) {
if (daemonLabels == null) if (daemonLabels == null)
return null; return null;
unnamedLabelText = unnamedLabel;
List<Label> localLabels = new ArrayList<Label>(); List<Label> localLabels = new ArrayList<Label>();
for (org.transdroid.daemon.Label label : daemonLabels) { for (org.transdroid.daemon.Label label : daemonLabels) {
localLabels.add(new Label(label)); localLabels.add(new Label(label));
} }
return localLabels; return localLabels;
} }
private Label(Parcel in) { private Label(Parcel in) {
this.name = in.readString(); this.name = in.readString();
this.count = in.readInt(); this.count = in.readInt();
} }
public static final Parcelable.Creator<Label> CREATOR = new Parcelable.Creator<Label>() { public static final Parcelable.Creator<Label> CREATOR = new Parcelable.Creator<Label>() {
public Label createFromParcel(Parcel in) { public Label createFromParcel(Parcel in) {
return new Label(in); return new Label(in);
} }
public Label[] newArray(int size) { public Label[] newArray(int size) {
return new Label[size]; return new Label[size];
} }
}; };
@Override @Override
public int describeContents() { public int describeContents() {
@ -72,5 +89,5 @@ public class Label implements SimpleListItem, NavigationFilter {
dest.writeString(name); dest.writeString(name);
dest.writeInt(count); dest.writeInt(count);
} }
} }

3
core/src/org/transdroid/core/gui/navigation/StatusType.java

@ -86,6 +86,9 @@ public enum StatusType {
return name; return name;
} }
/**
* Returns true if the torrent status matches this (selected) status type, false otherwise
*/
@Override @Override
public boolean matches(Torrent torrent) { public boolean matches(Torrent torrent) {
switch (statusType) { switch (statusType) {

Loading…
Cancel
Save