263 lines
9.7 KiB
Java
263 lines
9.7 KiB
Java
package com.iamthefij.otbeta;
|
|
|
|
import android.annotation.SuppressLint;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.net.http.HttpResponseCache;
|
|
import android.os.AsyncTask;
|
|
import android.os.Bundle;
|
|
import android.support.v7.app.AppCompatActivity;
|
|
import android.support.v7.widget.RecyclerView;
|
|
import android.support.v7.widget.Toolbar;
|
|
import android.util.Log;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.TextView;
|
|
|
|
|
|
import com.goebl.david.Response;
|
|
import com.goebl.david.WebbException;
|
|
import com.iamthefij.otbeta.api.Client;
|
|
import com.iamthefij.otbeta.api.Exerciser;
|
|
import com.iamthefij.otbeta.api.Interval;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.text.ParseException;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
|
|
/**
|
|
* An activity representing a list of Workouts. This activity
|
|
* has different presentations for handset and tablet-size devices. On
|
|
* handsets, the activity presents a list of items, which when touched,
|
|
* lead to a {@link WorkoutDetailActivity} representing
|
|
* item details. On tablets, the activity presents the list of items and
|
|
* item details side-by-side using two vertical panes.
|
|
*/
|
|
public class WorkoutListActivity extends AppCompatActivity {
|
|
|
|
private static final String TAG = "WorkoutListActivity";
|
|
/**
|
|
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
|
|
* device.
|
|
*/
|
|
private boolean mTwoPane;
|
|
private Client mClient;
|
|
private Exerciser mExerciser;
|
|
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.activity_workout_list);
|
|
|
|
// Install cache to prevent HTTP requests every time a view is revisited
|
|
installHttpCache();
|
|
|
|
// Initialize client
|
|
mClient = new Client(this);
|
|
|
|
// Get Exerciser from store
|
|
ExerciserStore exerciserStore = new ExerciserStore(this);
|
|
mExerciser = exerciserStore.getExerciser();
|
|
|
|
// Get
|
|
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.workout_list);
|
|
new WorkoutListGetter(recyclerView).execute();
|
|
|
|
// Set up the toolbar
|
|
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
|
setSupportActionBar(toolbar);
|
|
toolbar.setTitle(getTitle());
|
|
|
|
// Determine if dual pane
|
|
if (findViewById(R.id.workout_detail_container) != null) {
|
|
// The detail container view will be present only in the
|
|
// large-screen layouts (res/values-w900dp).
|
|
// If this view is present, then the
|
|
// activity should be in two-pane mode.
|
|
mTwoPane = true;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onStop() {
|
|
super.onStop();
|
|
flushHttpCache();
|
|
}
|
|
|
|
private void installHttpCache() {
|
|
try {
|
|
File httpCacheDir = new File(this.getCacheDir(), "http");
|
|
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
|
|
HttpResponseCache.install(httpCacheDir, httpCacheSize);
|
|
} catch (IOException e) {
|
|
Log.i(TAG, "HTTP response cache installation failed:" + e);
|
|
}
|
|
}
|
|
|
|
private void flushHttpCache() {
|
|
HttpResponseCache cache = HttpResponseCache.getInstalled();
|
|
if (cache != null) {
|
|
cache.flush();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Represents an asynchronous task to retrieve workouts from the api and populate
|
|
* the recycle view adapter
|
|
*/
|
|
private class WorkoutListGetter extends AsyncTask<Void, Void, Boolean> {
|
|
|
|
private final RecyclerView mRecyclerView;
|
|
private List<Interval> mWorkouts;
|
|
private boolean mInvalidSession = false;
|
|
|
|
WorkoutListGetter(RecyclerView recyclerView) {
|
|
mRecyclerView = recyclerView;
|
|
}
|
|
|
|
@Override
|
|
protected Boolean doInBackground(Void... params) {
|
|
try {
|
|
mWorkouts = mClient.getWorkouts(mExerciser, 30);
|
|
} catch (WebbException ex) {
|
|
Response response = ex.getResponse();
|
|
if (response.getStatusCode() == 403) {
|
|
mInvalidSession = true;
|
|
return false;
|
|
} else {
|
|
throw ex;
|
|
}
|
|
}
|
|
return mWorkouts != null;
|
|
}
|
|
|
|
@Override
|
|
protected void onPostExecute(Boolean success) {
|
|
super.onPostExecute(success);
|
|
if (success) {
|
|
WorkoutRecyclerAdapter adapter = new WorkoutRecyclerAdapter(mWorkouts);
|
|
mRecyclerView.setAdapter(adapter);
|
|
} else if (mInvalidSession) {
|
|
Intent loginActivity = new Intent(WorkoutListActivity.this, LoginActivity.class);
|
|
startActivity(loginActivity);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adapter to display workouts as a list of cards
|
|
*/
|
|
private class WorkoutRecyclerAdapter
|
|
extends RecyclerView.Adapter<WorkoutRecyclerAdapter.WorkoutViewHolder> {
|
|
|
|
private final List<Interval> mWorkouts;
|
|
|
|
WorkoutRecyclerAdapter(List<Interval> workouts) {
|
|
mWorkouts = workouts;
|
|
}
|
|
|
|
@Override
|
|
public WorkoutViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
|
View view = LayoutInflater.from(parent.getContext())
|
|
.inflate(R.layout.workout_card_view, parent, false);
|
|
return new WorkoutViewHolder(view);
|
|
}
|
|
|
|
@Override
|
|
public void onBindViewHolder(final WorkoutViewHolder holder, int position) {
|
|
Interval workout = mWorkouts.get(position);
|
|
if (workout != null) {
|
|
holder.fillView(workout);
|
|
|
|
holder.setOnClickListener(new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View v) {
|
|
if (mTwoPane) {
|
|
Bundle arguments = new Bundle();
|
|
arguments.putString(WorkoutDetailFragment.ARG_EXERCISER_UUID, mExerciser.getUuid());
|
|
arguments.putInt(WorkoutDetailFragment.ARG_WORKOUT_ID, holder.getWorkout().getId());
|
|
arguments.putString(WorkoutDetailFragment.ARG_WORKOUT_TITLE, holder.getTitle());
|
|
WorkoutDetailFragment fragment = new WorkoutDetailFragment();
|
|
fragment.setArguments(arguments);
|
|
getSupportFragmentManager().beginTransaction()
|
|
.replace(R.id.workout_detail_container, fragment)
|
|
.commit();
|
|
} else {
|
|
Context context = v.getContext();
|
|
Intent intent = new Intent(context, WorkoutDetailActivity.class);
|
|
intent.putExtra(WorkoutDetailFragment.ARG_EXERCISER_UUID, mExerciser.getUuid());
|
|
intent.putExtra(WorkoutDetailFragment.ARG_WORKOUT_ID, holder.getWorkout().getId());
|
|
intent.putExtra(WorkoutDetailFragment.ARG_WORKOUT_TITLE, holder.getTitle());
|
|
|
|
context.startActivity(intent);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int getItemCount() {
|
|
return mWorkouts.size();
|
|
}
|
|
|
|
class WorkoutViewHolder extends RecyclerView.ViewHolder {
|
|
private final View mView;
|
|
private final TextView mWorkoutDateView;
|
|
private final TextView mWorkoutCaloriesView;
|
|
private final TextView mWorkoutMinutesView;
|
|
private final TextView mWorkoutPointsView;
|
|
private Interval mWorkout;
|
|
|
|
Interval getWorkout() {
|
|
return mWorkout;
|
|
}
|
|
|
|
WorkoutViewHolder(View view) {
|
|
super(view);
|
|
mView = view;
|
|
mWorkoutDateView = (TextView) mView.findViewById(R.id.workout_date);
|
|
mWorkoutCaloriesView = (TextView) mView.findViewById(R.id.workout_calories);
|
|
mWorkoutMinutesView = (TextView) mView.findViewById(R.id.workout_minutes);
|
|
mWorkoutPointsView = (TextView) mView.findViewById(R.id.workout_points);
|
|
}
|
|
|
|
@SuppressLint("DefaultLocale")
|
|
void fillView(Interval workout) {
|
|
mWorkout = workout;
|
|
|
|
String workoutDate = "Unknown";
|
|
String localIsoTime = workout.getStartDateLocal();
|
|
if (localIsoTime != null) {
|
|
SimpleDateFormat isoParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
|
|
SimpleDateFormat formatter = new SimpleDateFormat("MMM d, yyyy", Locale.US);
|
|
try {
|
|
Date localIso = isoParser.parse(localIsoTime);
|
|
workoutDate = formatter.format(localIso);
|
|
} catch (ParseException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
mWorkoutDateView.setText(workoutDate);
|
|
mWorkoutCaloriesView.setText(String.format("%d Calories", workout.getTotalCalories()));
|
|
mWorkoutMinutesView.setText(String.format("%d minutes", workout.getTotalDuration()/60));
|
|
mWorkoutPointsView.setText(String.format("%d Splat Points", workout.getTotalPoints()));
|
|
}
|
|
|
|
void setOnClickListener(View.OnClickListener listener) {
|
|
mView.setOnClickListener(listener);
|
|
}
|
|
|
|
String getTitle() {
|
|
return (String) mWorkoutDateView.getText();
|
|
}
|
|
}
|
|
}
|
|
}
|