package org.edx.mobile.view;
import android.app.DownloadManager;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.ListView;
import org.edx.mobile.R;
import org.edx.mobile.base.BaseFragmentActivity;
import org.edx.mobile.model.VideoModel;
import org.edx.mobile.model.db.DownloadEntry;
import org.edx.mobile.model.download.NativeDownloadModel;
import org.edx.mobile.module.analytics.ISegment;
import org.edx.mobile.module.db.DataCallback;
import org.edx.mobile.module.db.IDbCallback;
import org.edx.mobile.module.db.ObservableDataCallback;
import org.edx.mobile.view.adapters.DownloadEntryAdapter;
import java.util.ArrayList;
import java.util.List;
public class DownloadListActivity extends BaseFragmentActivity {
public static int REFRESH_INTERVAL_IN_MILLISECONDS = 3000;
@Nullable
private DownloadEntryAdapter adapter;
@Nullable
private View offlineBar;
@NonNull
private final Handler handler = new Handler();
@NonNull
private final ObservableDataCallback<List<DownloadEntryAdapter.Item>> observable = new ObservableDataCallback<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_downloads_list);
environment.getSegment().trackScreenView(ISegment.Screens.DOWNLOADS);
offlineBar = findViewById(R.id.offline_bar);
adapter = new DownloadEntryAdapter(this, environment) {
@Override
public void onItemClicked(DownloadEntryAdapter.Item model) {
// nothing to do here
}
@Override
public void onDeleteClicked(DownloadEntryAdapter.Item item) {
assert adapter != null;
final VideoModel videoModel = ((DownloadItem) item).model;
if (environment.getStorage().removeDownload(videoModel) >= 1) {
adapter.remove(item);
}
}
};
final ListView downloadListView = (ListView) findViewById(R.id.my_downloads_list);
downloadListView.setAdapter(adapter);
}
@Override
protected void onResume() {
super.onResume();
observable.setObserver(new IDbCallback<List<DownloadEntryAdapter.Item>>() {
@Override
public void sendResult(List<DownloadEntryAdapter.Item> result) {
if (result != null) {
adapter.setItems(result);
}
fetchOngoingDownloadsAfterDelay();
}
@Override
public void sendException(Exception ex) {
logger.error(ex);
fetchOngoingDownloadsAfterDelay();
}
private void fetchOngoingDownloadsAfterDelay() {
handler.postDelayed(new Runnable() {
@Override
public void run() {
fetchOngoingDownloads();
}
}, REFRESH_INTERVAL_IN_MILLISECONDS);
}
});
fetchOngoingDownloads();
}
@Override
protected void onPause() {
super.onPause();
observable.setObserver(null);
handler.removeCallbacksAndMessages(null);
}
@Override
protected void onOffline() {
super.onOffline();
assert offlineBar != null;
offlineBar.setVisibility(View.VISIBLE);
}
@Override
protected void onOnline() {
super.onOnline();
assert offlineBar != null;
offlineBar.setVisibility(View.GONE);
}
private void fetchOngoingDownloads() {
environment.getDatabase().getListOfOngoingDownloads(new DataCallback<List<VideoModel>>(false) {
@Override
public void onResult(List<VideoModel> result) {
final List<DownloadEntryAdapter.Item> downloadItems = new ArrayList<>(result.size());
for (VideoModel model : result) {
final DownloadEntry downloadEntry = (DownloadEntry) model;
final NativeDownloadModel nativeModel = environment.getStorage().getNativeDownload(downloadEntry.dmId);
if (null != nativeModel) {
downloadItems.add(new DownloadItem(downloadEntry, nativeModel));
}
}
observable.sendResult(downloadItems);
}
@Override
public void onFail(Exception ex) {
observable.sendException(ex);
}
});
}
private static class DownloadItem implements DownloadEntryAdapter.Item {
@NonNull
private final DownloadEntry model;
@NonNull
private final NativeDownloadModel nativeModel;
public DownloadItem(@NonNull DownloadEntry model, @NonNull NativeDownloadModel nativeModel) {
this.model = model;
this.nativeModel = nativeModel;
}
@Override
@Nullable
public Long getTotalByteCount() {
if (model.size <= 0) {
if (nativeModel.size <= 0) {
return null; // Size not known
}
return nativeModel.size;
}
return model.size;
}
@Override
@NonNull
public String getTitle() {
return model.getTitle();
}
@Override
@NonNull
public String getDuration() {
return model.getDurationReadable();
}
@Override
public long getDownloadedByteCount() {
return nativeModel.downloaded;
}
@Override
@NonNull
public Status getStatus() {
if (nativeModel.status == DownloadManager.STATUS_FAILED) {
return Status.FAILED;
}
if (nativeModel.status == DownloadManager.STATUS_PENDING
|| nativeModel.size == -1) {
return Status.PENDING;
}
return Status.DOWNLOADING;
}
@Override
public int getPercent() {
return nativeModel.getPercentDownloaded();
}
}
}