diff options
Diffstat (limited to 'app/src/main/java/ml')
14 files changed, 605 insertions, 48 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserData.java new file mode 100644 index 00000000..9bfcf7c3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserData.java @@ -0,0 +1,50 @@ +package ml.docilealligator.infinityforreddit; + +import android.support.annotation.NonNull; +import android.util.Log; + +import User.UserData; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Retrofit; + +public class FetchUserData { + public interface FetchUserDataListener { + void onFetchUserDataSuccess(UserData userData); + void onFetchUserDataFail(); + } + + public static void fetchUserData(final Retrofit retrofit, String userName, + final FetchUserDataListener fetchUserDataListener) { + RedditAPI api = retrofit.create(RedditAPI.class); + + Call<String> userInfo = api.getUserData(userName); + userInfo.enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { + if(response.isSuccessful()) { + ParseUserData.parseUserData(response.body(), new ParseUserData.ParseUserDataListener() { + @Override + public void onParseUserDataSuccess(UserData userData) { + fetchUserDataListener.onFetchUserDataSuccess(userData); + } + + @Override + public void onParseUserDataFail() { + fetchUserDataListener.onFetchUserDataFail(); + } + }); + } else { + Log.i("call failed", response.message()); + fetchUserDataListener.onFetchUserDataFail(); + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + Log.i("call failed", t.getMessage()); + fetchUserDataListener.onFetchUserDataFail(); + } + }); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/InsertUserDataAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/InsertUserDataAsyncTask.java index 823e014e..6db03920 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/InsertUserDataAsyncTask.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/InsertUserDataAsyncTask.java @@ -2,27 +2,27 @@ package ml.docilealligator.infinityforreddit; import android.os.AsyncTask; -import User.User; +import User.UserData; import User.UserDao; public class InsertUserDataAsyncTask extends AsyncTask<Void, Void, Void> { private UserDao userDao; - private User user; + private UserData userData; private InsertUserDataCallback insertUserDataCallback; public interface InsertUserDataCallback { void insertSuccess(); } - public InsertUserDataAsyncTask(UserDao userDao, User user, InsertUserDataCallback insertUserDataCallback) { + public InsertUserDataAsyncTask(UserDao userDao, UserData userData, InsertUserDataCallback insertUserDataCallback) { this.userDao = userDao; - this.user = user; + this.userData = userData; this.insertUserDataCallback = insertUserDataCallback; } @Override protected Void doInBackground(Void... voids) { - userDao.insert(user); + userDao.insert(userData); return null; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/LoadUserDataAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/LoadUserDataAsyncTask.java index be8c182c..704c3e08 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/LoadUserDataAsyncTask.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/LoadUserDataAsyncTask.java @@ -2,8 +2,7 @@ package ml.docilealligator.infinityforreddit; import android.os.AsyncTask; -import User.FetchUserData; -import User.User; +import User.UserData; import User.UserDao; import retrofit2.Retrofit; @@ -29,7 +28,7 @@ public class LoadUserDataAsyncTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... voids) { if(userDao.getUserData(userName) != null) { - iconImageUrl = userDao.getUserData(userName).getIcon(); + iconImageUrl = userDao.getUserData(userName).getIconUrl(); hasUserInDb = true; } else { hasUserInDb = false; @@ -45,13 +44,8 @@ public class LoadUserDataAsyncTask extends AsyncTask<Void, Void, Void> { } else { FetchUserData.fetchUserData(retrofit, userName, new FetchUserData.FetchUserDataListener() { @Override - public void onFetchUserDataSuccess(User user) { - new InsertUserDataAsyncTask(userDao, user, new InsertUserDataAsyncTask.InsertUserDataCallback() { - @Override - public void insertSuccess() { - loadUserDataAsyncTaskListener.loadUserDataSuccess(user.getIcon()); - } - }).execute(); + public void onFetchUserDataSuccess(UserData userData) { + new InsertUserDataAsyncTask(userDao, userData, () -> loadUserDataAsyncTaskListener.loadUserDataSuccess(userData.getIconUrl())).execute(); } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java index 773ec885..7254bfcf 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java @@ -20,6 +20,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import com.bumptech.glide.Glide; @@ -61,6 +62,7 @@ public class MainActivity extends AppCompatActivity { @BindView(R.id.subscriptions_label_main_activity) TextView subscriptionsLabelTextView; @BindView(R.id.subscribed_user_recycler_view_main_activity) RecyclerView subscribedUserRecyclerView; @BindView(R.id.following_label_main_activity) TextView followingLabelTextView; + @BindView(R.id.profile_linear_layout_main_activity) LinearLayout profileLinearLayout; private TextView mNameTextView; private TextView mKarmaTextView; @@ -153,13 +155,14 @@ public class MainActivity extends AppCompatActivity { glide.load(mBannerImageUrl).into(mBannerImageView); } - final SubscribedSubredditRecyclerViewAdapter subredditadapter = new SubscribedSubredditRecyclerViewAdapter(this, - new SubscribedSubredditRecyclerViewAdapter.OnItemClickListener() { - @Override - public void onClick() { - drawer.closeDrawers(); - } - }); + profileLinearLayout.setOnClickListener(view -> { + Intent intent = new Intent(MainActivity.this, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mName); + startActivity(intent); + }); + + final SubscribedSubredditRecyclerViewAdapter subredditadapter = + new SubscribedSubredditRecyclerViewAdapter(this, drawer::closeDrawers); subscribedSubredditRecyclerView.setAdapter(subredditadapter); mSubscribedSubredditViewModel = ViewModelProviders.of(this).get(SubscribedSubredditViewModel.class); @@ -176,13 +179,8 @@ public class MainActivity extends AppCompatActivity { } }); - final SubscribedUserRecyclerViewAdapter userAdapter = new SubscribedUserRecyclerViewAdapter(this, - new SubscribedUserRecyclerViewAdapter.OnItemClickListener() { - @Override - public void onClick() { - drawer.closeDrawers(); - } - }); + final SubscribedUserRecyclerViewAdapter userAdapter = + new SubscribedUserRecyclerViewAdapter(this, drawer::closeDrawers); subscribedUserRecyclerView.setAdapter(userAdapter); mSubscribedUserViewModel = ViewModelProviders.of(this).get(SubscribedUserViewModel.class); mSubscribedUserViewModel.getAllSubscribedUsers().observe(this, new Observer<List<SubscribedUserData>>() { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/NetworkComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/NetworkComponent.java index 354dfbea..747dead0 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/NetworkComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/NetworkComponent.java @@ -11,4 +11,5 @@ interface NetworkComponent { void inject(PostFragment postFragment); void inject(ViewPostDetailActivity viewPostDetailActivity); void inject(ViewSubredditDetailActivity viewSubredditDetailActivity); + void inject(ViewUserDetailActivity viewUserDetailActivity); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java index 6b9ef580..fc69c82b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java @@ -94,7 +94,7 @@ class ParseSubscribedThing { if(data.getString(JSONUtils.SUBREDDIT_TYPE_KEY) .equals(JSONUtils.SUBREDDIT_TYPE_VALUE_USER)) { //It's a user - newSubscribedUserData.add(new SubscribedUserData(id, name.substring(2), iconUrl)); + newSubscribedUserData.add(new SubscribedUserData(name.substring(2), iconUrl)); } else { String subredditFullName = data.getString(JSONUtils.DISPLAY_NAME); String description = data.getString(JSONUtils.PUBLIC_DESCRIPTION_KEY).trim(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseUserData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseUserData.java new file mode 100644 index 00000000..12402f03 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseUserData.java @@ -0,0 +1,73 @@ +package ml.docilealligator.infinityforreddit; + +import android.os.AsyncTask; +import android.util.Log; + +import org.json.JSONException; +import org.json.JSONObject; + +import User.UserData; + +public class ParseUserData { + interface ParseUserDataListener { + void onParseUserDataSuccess(UserData userData); + void onParseUserDataFail(); + } + + static void parseUserData(String response, ParseUserDataListener parseUserDataListener) { + new ParseUserDataAsyncTask(response, parseUserDataListener).execute(); + } + + private static class ParseUserDataAsyncTask extends AsyncTask<Void, Void, Void> { + private JSONObject jsonResponse; + private ParseUserDataListener parseUserDataListener; + private boolean parseFailed; + + private UserData userData; + + ParseUserDataAsyncTask(String response, ParseUserDataListener parseUserDataListener){ + try { + Log.i("response", response); + jsonResponse = new JSONObject(response); + this.parseUserDataListener = parseUserDataListener; + parseFailed = false; + } catch (JSONException e) { + Log.i("userdata json error", e.getMessage()); + parseUserDataListener.onParseUserDataFail(); + } + } + + @Override + protected Void doInBackground(Void... voids) { + try { + jsonResponse = jsonResponse.getJSONObject(JSONUtils.DATA_KEY); + String userName = jsonResponse.getString(JSONUtils.NAME_KEY); + String iconImageUrl = jsonResponse.getString(JSONUtils.ICON_IMG_KEY); + String bannerImageUrl = ""; + if(jsonResponse.has(JSONUtils.SUBREDDIT_KEY) && !jsonResponse.isNull(JSONUtils.SUBREDDIT_KEY)) { + bannerImageUrl = jsonResponse.getJSONObject(JSONUtils.SUBREDDIT_KEY).getString(JSONUtils.BANNER_IMG_KEY); + } + int linkKarma = jsonResponse.getInt(JSONUtils.LINK_KARMA_KEY); + int commentKarma = jsonResponse.getInt(JSONUtils.COMMENT_KARMA_KEY); + int karma = linkKarma + commentKarma; + boolean isGold = jsonResponse.getBoolean(JSONUtils.IS_GOLD_KEY); + boolean isFriend = jsonResponse.getBoolean(JSONUtils.IS_FRIEND_KEY); + + userData = new UserData(userName, iconImageUrl, bannerImageUrl, karma, isGold, isFriend); + } catch (JSONException e) { + parseFailed = true; + Log.i("parse user data error", e.getMessage()); + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + if(!parseFailed) { + parseUserDataListener.onParseUserDataSuccess(userData); + } else { + parseUserDataListener.onParseUserDataFail(); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java index bc851a8f..35e95b75 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java @@ -300,6 +300,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo if(canStartActivity) { canStartActivity = false; Intent intent = new Intent(mContext, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, post.getAuthor()); mContext.startActivity(intent); } }); @@ -310,6 +311,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo if(canStartActivity) { canStartActivity = false; Intent intent = new Intent(mContext, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, post.getAuthor()); mContext.startActivity(intent); } }); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java index 25b74317..25f83bbd 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java @@ -3,11 +3,13 @@ package ml.docilealligator.infinityforreddit; import java.util.Map; import retrofit2.Call; +import retrofit2.http.DELETE; import retrofit2.http.FieldMap; import retrofit2.http.FormUrlEncoded; import retrofit2.http.GET; import retrofit2.http.HeaderMap; import retrofit2.http.POST; +import retrofit2.http.PUT; import retrofit2.http.Path; import retrofit2.http.Query; @@ -45,4 +47,10 @@ public interface RedditAPI { @FormUrlEncoded @POST("api/subscribe") Call<String> subredditSubscription(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> params); + + @PUT("/api/v1/me/friends/username") + Call<String> subscribeUser(@HeaderMap Map<String, String> headers); + + @DELETE("/api/v1/me/friends/username") + Call<String> unsubscribeUser(@HeaderMap Map<String, String> headers); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditUtils.java index d598f684..627b7f10 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditUtils.java @@ -30,7 +30,7 @@ public class RedditUtils { static final String AUTHORIZATION_KEY = "Authorization"; static final String AUTHORIZATION_BASE = "bearer "; - static final String USER_AGENT_KEY = "User-Agent"; + static final String USER_AGENT_KEY = "UserData-Agent"; static final String USER_AGENT = ""; static final String GRANT_TYPE_KEY = "grant_type"; @@ -47,6 +47,7 @@ public class RedditUtils { static final String ACTION_KEY = "action"; static final String SR_NAME_KEY = "sr_name"; + static final String SR_KEY = "sr"; static Map<String, String> getHttpBasicAuthHeader() { Map<String, String> params = new HashMap<>(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRecyclerViewAdapter.java index 013d75c1..bec617c6 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRecyclerViewAdapter.java @@ -1,6 +1,7 @@ package ml.docilealligator.infinityforreddit; import android.content.Context; +import android.content.Intent; import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; import android.support.annotation.NonNull; @@ -27,6 +28,7 @@ import jp.wasabeef.glide.transformations.RoundedCornersTransformation; public class SubscribedUserRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<SubscribedUserData> mSubscribedUserData; + private Context mContext; private RequestManager glide; private OnItemClickListener mOnItemClickListener; @@ -35,6 +37,7 @@ public class SubscribedUserRecyclerViewAdapter extends RecyclerView.Adapter<Recy } SubscribedUserRecyclerViewAdapter(Context context, OnItemClickListener onItemClickListener) { + mContext = context; glide = Glide.with(context.getApplicationContext()); mOnItemClickListener = onItemClickListener; } @@ -47,13 +50,11 @@ public class SubscribedUserRecyclerViewAdapter extends RecyclerView.Adapter<Recy @Override public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int i) { - viewHolder.itemView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - //Need to be implemented - - mOnItemClickListener.onClick(); - } + viewHolder.itemView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mSubscribedUserData.get(viewHolder.getAdapterPosition()).getName()); + mContext.startActivity(intent); + mOnItemClickListener.onClick(); }); if(!mSubscribedUserData.get(i).getIconUrl().equals("")) { glide.load(mSubscribedUserData.get(i).getIconUrl()) diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/UserFollowing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/UserFollowing.java new file mode 100644 index 00000000..c5af5a26 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/UserFollowing.java @@ -0,0 +1,117 @@ +package ml.docilealligator.infinityforreddit; + +import android.content.SharedPreferences; +import android.os.AsyncTask; +import android.support.annotation.NonNull; +import android.util.Log; + +import java.util.HashMap; +import java.util.Map; + +import SubscribedUserDatabase.SubscribedUserDao; +import SubscribedUserDatabase.SubscribedUserData; +import User.UserData; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Retrofit; + +class UserFollowing { + interface UserFollowingListener { + void onUserFollowingSuccess(); + void onUserFollowingFail(); + } + + static void followUser(Retrofit oauthRetrofit, Retrofit retrofit, + SharedPreferences authInfoSharedPreferences, String userName, + SubscribedUserDao subscribedUserDao, + UserFollowingListener userFollowingListener) { + userFollowing(oauthRetrofit, retrofit, authInfoSharedPreferences, userName, "sub", + subscribedUserDao, userFollowingListener); + } + + static void unfollowUser(Retrofit oauthRetrofit, Retrofit retrofit, + SharedPreferences authInfoSharedPreferences, String userName, + SubscribedUserDao subscribedUserDao, + UserFollowingListener userFollowingListener) { + userFollowing(oauthRetrofit, retrofit, authInfoSharedPreferences, userName, "unsub", + subscribedUserDao, userFollowingListener); + } + + private static void userFollowing(Retrofit oauthRetrofit, Retrofit retrofit, SharedPreferences authInfoSharedPreferences, + String userName, String action, SubscribedUserDao subscribedUserDao, + UserFollowingListener userFollowingListener) { + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + + String accessToken = authInfoSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, ""); + + Map<String, String> params = new HashMap<>(); + params.put(RedditUtils.ACTION_KEY, action); + params.put(RedditUtils.SR_KEY, "u/" + userName); + + Call<String> subredditSubscriptionCall = api.subredditSubscription(RedditUtils.getOAuthHeader(accessToken), params); + subredditSubscriptionCall.enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { + if(response.isSuccessful()) { + if(action.equals("sub")) { + FetchUserData.fetchUserData(retrofit, userName, new FetchUserData.FetchUserDataListener() { + @Override + public void onFetchUserDataSuccess(UserData userData) { + new UpdateSubscriptionAsyncTask(subscribedUserDao, userData, true).execute(); + } + + @Override + public void onFetchUserDataFail() { + + } + }); + } else { + new UpdateSubscriptionAsyncTask(subscribedUserDao, userName, false).execute(); + } + userFollowingListener.onUserFollowingSuccess(); + } else { + Log.i("call failed", response.message()); + userFollowingListener.onUserFollowingFail(); + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + Log.i("call failed", t.getMessage()); + userFollowingListener.onUserFollowingFail(); + } + }); + } + + private static class UpdateSubscriptionAsyncTask extends AsyncTask<Void, Void, Void> { + + private SubscribedUserDao subscribedUserDao; + private String userName; + private SubscribedUserData subscribedUserData; + private boolean isSubscribing; + + UpdateSubscriptionAsyncTask(SubscribedUserDao subscribedUserDao, String userName, + boolean isSubscribing) { + this.subscribedUserDao = subscribedUserDao; + this.userName = userName; + this.isSubscribing = isSubscribing; + } + + UpdateSubscriptionAsyncTask(SubscribedUserDao subscribedUserDao, SubscribedUserData subscribedUserData, + boolean isSubscribing) { + this.subscribedUserDao = subscribedUserDao; + this.subscribedUserData = subscribedUserData; + this.isSubscribing = isSubscribing; + } + + @Override + protected Void doInBackground(Void... voids) { + if(isSubscribing) { + subscribedUserDao.insert(subscribedUserData); + } else { + subscribedUserDao.deleteSubscribedUser(userName);; + } + return null; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java index cf9b0f9a..67042e55 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java @@ -22,7 +22,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import android.widget.Toast; import com.bumptech.glide.Glide; import com.bumptech.glide.RequestManager; @@ -104,11 +103,11 @@ public class ViewSubredditDetailActivity extends AppCompatActivity { ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); params.topMargin = statusBarHeight; - final String subredditName = getIntent().getExtras().getString(EXTRA_SUBREDDIT_NAME_KEY); + String subredditName = getIntent().getExtras().getString(EXTRA_SUBREDDIT_NAME_KEY); - final String title = "r/" + subredditName; - final CollapsingToolbarLayout collapsingToolbarLayout = findViewById(R.id.collapsing_toolbar_layout_view_subreddit_detail_activity); - final AppBarLayout appBarLayout = findViewById(R.id.app_bar_layout_view_subreddit_detail_activity); + String title = "r/" + subredditName; + CollapsingToolbarLayout collapsingToolbarLayout = findViewById(R.id.collapsing_toolbar_layout_view_subreddit_detail_activity); + AppBarLayout appBarLayout = findViewById(R.id.app_bar_layout_view_subreddit_detail_activity); appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { int previousVerticalOffset = 0; @@ -136,10 +135,10 @@ public class ViewSubredditDetailActivity extends AppCompatActivity { }); subscribedSubredditDao = SubscribedSubredditRoomDatabase.getDatabase(this).subscribedSubredditDao(); - glide = Glide.with(ViewSubredditDetailActivity.this); + glide = Glide.with(this); - SubredditViewModel.Factory factory = new SubredditViewModel.Factory(getApplication(), subredditName); - mSubredditViewModel = ViewModelProviders.of(this, factory).get(SubredditViewModel.class); + mSubredditViewModel = ViewModelProviders.of(this, new SubredditViewModel.Factory(getApplication(), subredditName)) + .get(SubredditViewModel.class); mSubredditViewModel.getSubredditLiveData().observe(this, subredditData -> { if(subredditData != null) { if(subredditData.getBannerUrl().equals("")) { @@ -279,7 +278,7 @@ public class ViewSubredditDetailActivity extends AppCompatActivity { @Override public void onParseSubredditDataFail() { - Toast.makeText(ViewSubredditDetailActivity.this, "Cannot fetch subreddit info", Toast.LENGTH_SHORT).show(); + makeSnackbar(R.string.cannot_fetch_subreddit_info); } }); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java index 0ec59030..8b3fa0a1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java @@ -1,13 +1,78 @@ package ml.docilealligator.infinityforreddit; +import android.arch.lifecycle.ViewModelProviders; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.drawable.Animatable; +import android.graphics.drawable.Drawable; +import android.os.AsyncTask; import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.design.chip.Chip; +import android.support.design.widget.AppBarLayout; +import android.support.design.widget.CollapsingToolbarLayout; +import android.support.design.widget.CoordinatorLayout; +import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; +import android.view.MenuItem; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.Target; +import com.felipecsl.gifimageview.library.GifImageView; + +import javax.inject.Inject; +import javax.inject.Named; + +import SubscribedUserDatabase.SubscribedUserDao; +import SubscribedUserDatabase.SubscribedUserData; +import SubscribedUserDatabase.SubscribedUserRoomDatabase; +import User.UserDao; +import User.UserData; +import User.UserRoomDatabase; +import User.UserViewModel; +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import retrofit2.Retrofit; public class ViewUserDetailActivity extends AppCompatActivity { static final String EXTRA_USER_NAME_KEY = "EUNK"; + @BindView(R.id.coordinator_layout_view_user_detail_activity) CoordinatorLayout coordinatorLayout; + @BindView(R.id.banner_image_view_view_user_detail_activity) ImageView bannerImageView; + @BindView(R.id.icon_gif_image_view_view_user_detail_activity) GifImageView iconGifImageView; + @BindView(R.id.user_name_text_view_view_user_detail_activity) TextView userNameTextView; + @BindView(R.id.subscribe_user_chip_view_user_detail_activity) Chip subscribeUserChip; + @BindView(R.id.karma_text_view_view_user_detail_activity) TextView karmaTextView; + + private SubscribedUserDao subscribedUserDao; + private RequestManager glide; + private UserViewModel userViewModel; + + private boolean subscriptionReady = false; + + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + + @Inject + @Named("auth_info") + SharedPreferences sharedPreferences; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -15,6 +80,254 @@ public class ViewUserDetailActivity extends AppCompatActivity { Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - + ButterKnife.bind(this); + + ((Infinity) getApplication()).getmNetworkComponent().inject(this); + + setSupportActionBar(toolbar); + + //Get status bar height + int statusBarHeight = 0; + int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resourceId > 0) { + statusBarHeight = getResources().getDimensionPixelSize(resourceId); + } + + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); + params.topMargin = statusBarHeight; + + String userName = getIntent().getExtras().getString(EXTRA_USER_NAME_KEY); + String title = "u/" + userName; + + CollapsingToolbarLayout collapsingToolbarLayout = findViewById(R.id.collapsing_toolbar_layout_view_user_detail_activity); + AppBarLayout appBarLayout = findViewById(R.id.app_bar_layout_view_user_detail_activity); + + appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { + int previousVerticalOffset = 0; + int scrollRange = -1; + + @Override + public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { + if(scrollRange == -1) { + scrollRange = appBarLayout.getTotalScrollRange(); + } else { + if(verticalOffset < previousVerticalOffset) { + //Scroll down + if(scrollRange - Math.abs(verticalOffset) <= toolbar.getHeight()) { + collapsingToolbarLayout.setTitle(title); + } + } else { + //Scroll up + if(scrollRange - Math.abs(verticalOffset) > toolbar.getHeight()) { + collapsingToolbarLayout.setTitle(" ");//carefull there should a space between double quote otherwise it wont work + } + } + previousVerticalOffset = verticalOffset; + } + } + }); + + subscribeUserChip.setOnClickListener(view -> { + if(subscriptionReady) { + subscriptionReady = false; + if(subscribeUserChip.getText().equals(getResources().getString(R.string.subscribe))) { + UserFollowing.followUser(mOauthRetrofit, mRetrofit, sharedPreferences, + userName, subscribedUserDao, new UserFollowing.UserFollowingListener() { + @Override + public void onUserFollowingSuccess() { + subscribeUserChip.setText(R.string.unfollow); + subscribeUserChip.setChipBackgroundColor(getResources().getColorStateList(R.color.colorAccent)); + makeSnackbar(R.string.followed); + subscriptionReady = true; + } + + @Override + public void onUserFollowingFail() { + makeSnackbar(R.string.follow_failed); + subscriptionReady = true; + } + }); + } else { + UserFollowing.unfollowUser(mOauthRetrofit, mRetrofit, sharedPreferences, + userName, subscribedUserDao, new UserFollowing.UserFollowingListener() { + @Override + public void onUserFollowingSuccess() { + subscribeUserChip.setText(R.string.follow); + subscribeUserChip.setChipBackgroundColor(getResources().getColorStateList(R.color.colorPrimaryDark)); + makeSnackbar(R.string.unfollowed); + subscriptionReady = true; + } + + @Override + public void onUserFollowingFail() { + makeSnackbar(R.string.unfollow_failed); + subscriptionReady = true; + } + }); + } + } + }); + + subscribedUserDao = SubscribedUserRoomDatabase.getDatabase(this).subscribedUserDao(); + + new CheckIsFollowingUserAsyncTask(subscribedUserDao, userName, new CheckIsFollowingUserAsyncTask.CheckIsFollowingUserListener() { + @Override + public void isSubscribed() { + subscribeUserChip.setText(R.string.unfollow); + subscribeUserChip.setChipBackgroundColor(getResources().getColorStateList(R.color.colorAccent)); + subscriptionReady = true; + } + + @Override + public void isNotSubscribed() { + subscribeUserChip.setText(R.string.follow); + subscribeUserChip.setChipBackgroundColor(getResources().getColorStateList(R.color.colorPrimaryDark)); + subscriptionReady = true; + } + }).execute(); + + glide = Glide.with(this); + + userViewModel = ViewModelProviders.of(this, new UserViewModel.Factory(getApplication(), userName)) + .get(UserViewModel.class); + userViewModel.getUserLiveData().observe(this, userData -> { + if(userData != null) { + if(userData.getBanner().equals("")) { + bannerImageView.setOnClickListener(view -> { + //Do nothing since the user has no banner image + }); + } else { + glide.load(userData.getBanner()).into(bannerImageView); + bannerImageView.setOnClickListener(view -> { + Intent intent = new Intent(this, ViewImageActivity.class); + intent.putExtra(ViewImageActivity.TITLE_KEY, title); + intent.putExtra(ViewImageActivity.IMAGE_URL_KEY, userData.getBanner()); + intent.putExtra(ViewImageActivity.FILE_NAME_KEY, userName + "-banner"); + startActivity(intent); + }); + } + + if(userData.getIconUrl().equals("")) { + glide.load(getDrawable(R.drawable.subreddit_default_icon)) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(216, 0))) + .into(iconGifImageView); + iconGifImageView.setOnClickListener(view -> { + //Do nothing since the user has no icon image + }); + } else { + glide.load(userData.getIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(216, 0))) + .error(glide.load(R.drawable.subreddit_default_icon)) + .listener(new RequestListener<Drawable>() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { + if(resource instanceof Animatable) { + //This is a gif + ((Animatable) resource).start(); + iconGifImageView.startAnimation(); + } + return false; + } + }) + .into(iconGifImageView); + iconGifImageView.setOnClickListener(view -> { + Intent intent = new Intent(this, ViewImageActivity.class); + intent.putExtra(ViewImageActivity.TITLE_KEY, title); + intent.putExtra(ViewImageActivity.IMAGE_URL_KEY, userData.getIconUrl()); + intent.putExtra(ViewImageActivity.FILE_NAME_KEY, userName + "-icon"); + startActivity(intent); + }); + } + + String userFullName = "u/" + userData.getName(); + userNameTextView.setText(userFullName); + String karma = getString(R.string.karma_info, userData.getKarma()); + karmaTextView.setText(karma); + } + }); + + FetchUserData.fetchUserData(mRetrofit, userName, new FetchUserData.FetchUserDataListener() { + @Override + public void onFetchUserDataSuccess(UserData userData) { + new InsertUserDataAsyncTask(UserRoomDatabase.getDatabase(ViewUserDetailActivity.this).userDao(), userData).execute(); + } + + @Override + public void onFetchUserDataFail() { + makeSnackbar(R.string.cannot_fetch_user_info); + } + }); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + } + return false; + } + + private void makeSnackbar(int resId) { + Snackbar.make(coordinatorLayout, resId, Snackbar.LENGTH_SHORT).show(); + } + + private static class InsertUserDataAsyncTask extends AsyncTask<Void, Void, Void> { + + private UserDao userDao; + private UserData subredditData; + + InsertUserDataAsyncTask(UserDao userDao, UserData userData) { + this.userDao = userDao; + this.subredditData = userData; + } + + @Override + protected Void doInBackground(final Void... params) { + userDao.insert(subredditData); + return null; + } + } + + private static class CheckIsFollowingUserAsyncTask extends AsyncTask<Void, Void, Void> { + + private SubscribedUserDao subscribedUserDao; + private String userName; + private SubscribedUserData subscribedUserData; + private CheckIsFollowingUserListener checkIsFollowingUserListener; + + interface CheckIsFollowingUserListener { + void isSubscribed(); + void isNotSubscribed(); + } + + CheckIsFollowingUserAsyncTask(SubscribedUserDao subscribedUserDao, String userName, + CheckIsFollowingUserListener checkIsFollowingUserListener) { + this.subscribedUserDao = subscribedUserDao; + this.userName = userName; + this.checkIsFollowingUserListener = checkIsFollowingUserListener; + } + + @Override + protected Void doInBackground(Void... voids) { + subscribedUserData = subscribedUserDao.getSubscribedUser(userName); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if(subscribedUserData != null) { + checkIsFollowingUserListener.isSubscribed(); + } else { + checkIsFollowingUserListener.isNotSubscribed(); + } + } } } |