aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--app/src/main/AndroidManifest.xml4
-rw-r--r--app/src/main/java/SubredditDatabase/SubredditDao.java2
-rw-r--r--app/src/main/java/SubredditDatabase/SubredditRepository.java6
-rw-r--r--app/src/main/java/SubredditDatabase/SubredditViewModel.java2
-rw-r--r--app/src/main/java/SubscribedUserDatabase/SubscribedUserDao.java8
-rw-r--r--app/src/main/java/SubscribedUserDatabase/SubscribedUserData.java9
-rw-r--r--app/src/main/java/User/UserDao.java10
-rw-r--r--app/src/main/java/User/UserData.java (renamed from app/src/main/java/User/User.java)25
-rw-r--r--app/src/main/java/User/UserRepository.java39
-rw-r--r--app/src/main/java/User/UserRoomDatabase.java2
-rw-r--r--app/src/main/java/User/UserViewModel.java48
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserData.java (renamed from app/src/main/java/User/FetchUserData.java)12
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/InsertUserDataAsyncTask.java10
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/LoadUserDataAsyncTask.java14
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java26
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/NetworkComponent.java1
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java2
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/ParseUserData.java (renamed from app/src/main/java/User/ParseUserData.java)19
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java2
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java8
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/RedditUtils.java3
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRecyclerViewAdapter.java15
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/UserFollowing.java117
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java17
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java315
-rw-r--r--app/src/main/res/layout/activity_main.xml1
-rw-r--r--app/src/main/res/layout/activity_view_user_detail.xml80
-rw-r--r--app/src/main/res/values/strings.xml25
28 files changed, 703 insertions, 119 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a36ebe04..5d815b6d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -50,8 +50,8 @@
android:theme="@style/AppTheme.NoActionBarWithTranslucentStatusBar" />
<activity
android:name=".ViewUserDetailActivity"
- android:label="@string/title_activity_view_user_detail"
- android:theme="@style/AppTheme.NoActionBar" />
+ android:parentActivityName=".MainActivity"
+ android:theme="@style/AppTheme.NoActionBarWithTranslucentStatusBar" />
</application>
</manifest> \ No newline at end of file
diff --git a/app/src/main/java/SubredditDatabase/SubredditDao.java b/app/src/main/java/SubredditDatabase/SubredditDao.java
index ac291f9a..df763c93 100644
--- a/app/src/main/java/SubredditDatabase/SubredditDao.java
+++ b/app/src/main/java/SubredditDatabase/SubredditDao.java
@@ -14,7 +14,7 @@ public interface SubredditDao {
@Query("DELETE FROM subreddits")
void deleteAllSubreddits();
- @Query("SELECT * from subreddits WHERE name = :namePrefixed")
+ @Query("SELECT * from subreddits WHERE name = :namePrefixed LIMIT 1")
LiveData<SubredditData> getSubredditLiveDataByName(String namePrefixed);
@Query("SELECT * from subreddits WHERE name = :namePrefixed LIMIT 1")
diff --git a/app/src/main/java/SubredditDatabase/SubredditRepository.java b/app/src/main/java/SubredditDatabase/SubredditRepository.java
index 495f6e3d..4e435da9 100644
--- a/app/src/main/java/SubredditDatabase/SubredditRepository.java
+++ b/app/src/main/java/SubredditDatabase/SubredditRepository.java
@@ -20,14 +20,14 @@ public class SubredditRepository {
}
public void insert(SubredditData subredditData) {
- new SubredditRepository.insertAsyncTask(mSubredditDao).execute(subredditData);
+ new InsertAsyncTask(mSubredditDao).execute(subredditData);
}
- private static class insertAsyncTask extends AsyncTask<SubredditData, Void, Void> {
+ private static class InsertAsyncTask extends AsyncTask<SubredditData, Void, Void> {
private SubredditDao mAsyncTaskDao;
- insertAsyncTask(SubredditDao dao) {
+ InsertAsyncTask(SubredditDao dao) {
mAsyncTaskDao = dao;
}
diff --git a/app/src/main/java/SubredditDatabase/SubredditViewModel.java b/app/src/main/java/SubredditDatabase/SubredditViewModel.java
index a9d176b3..19c2d726 100644
--- a/app/src/main/java/SubredditDatabase/SubredditViewModel.java
+++ b/app/src/main/java/SubredditDatabase/SubredditViewModel.java
@@ -11,7 +11,7 @@ public class SubredditViewModel extends AndroidViewModel {
private SubredditRepository mSubredditRepository;
private LiveData<SubredditData> mSubredditLiveData;
- SubredditViewModel(Application application, String id) {
+ public SubredditViewModel(Application application, String id) {
super(application);
mSubredditRepository = new SubredditRepository(application, id);
mSubredditLiveData = mSubredditRepository.getSubredditLiveData();
diff --git a/app/src/main/java/SubscribedUserDatabase/SubscribedUserDao.java b/app/src/main/java/SubscribedUserDatabase/SubscribedUserDao.java
index 2b61a666..83bdf6fe 100644
--- a/app/src/main/java/SubscribedUserDatabase/SubscribedUserDao.java
+++ b/app/src/main/java/SubscribedUserDatabase/SubscribedUserDao.java
@@ -16,6 +16,12 @@ public interface SubscribedUserDao {
@Query("DELETE FROM subscribed_users")
void deleteAllSubscribedUsers();
- @Query("SELECT * from subscribed_users ORDER BY name COLLATE NOCASE ASC")
+ @Query("SELECT * FROM subscribed_users ORDER BY name COLLATE NOCASE ASC")
LiveData<List<SubscribedUserData>> getAllSubscribedUsers();
+
+ @Query("SELECT * FROM subscribed_users WHERE name = :userName LIMIT 1")
+ SubscribedUserData getSubscribedUser(String userName);
+
+ @Query("DELETE FROM subscribed_users WHERE name = :userName")
+ void deleteSubscribedUser(String userName);
}
diff --git a/app/src/main/java/SubscribedUserDatabase/SubscribedUserData.java b/app/src/main/java/SubscribedUserDatabase/SubscribedUserData.java
index 8494e784..41947efe 100644
--- a/app/src/main/java/SubscribedUserDatabase/SubscribedUserData.java
+++ b/app/src/main/java/SubscribedUserDatabase/SubscribedUserData.java
@@ -9,24 +9,17 @@ import android.support.annotation.NonNull;
public class SubscribedUserData {
@PrimaryKey
@NonNull
- @ColumnInfo(name = "id")
- private String id;
@ColumnInfo(name = "name")
private String name;
@ColumnInfo(name = "icon")
private String iconUrl;
- public SubscribedUserData(@NonNull String id, String name, String iconUrl) {
- this.id = id;
+ public SubscribedUserData(@NonNull String name, String iconUrl) {
this.name = name;
this.iconUrl = iconUrl;
}
@NonNull
- public String getId() {
- return id;
- }
-
public String getName() {
return name;
}
diff --git a/app/src/main/java/User/UserDao.java b/app/src/main/java/User/UserDao.java
index ec6bb7e2..7aba086d 100644
--- a/app/src/main/java/User/UserDao.java
+++ b/app/src/main/java/User/UserDao.java
@@ -1,5 +1,6 @@
package User;
+import android.arch.lifecycle.LiveData;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy;
@@ -8,11 +9,14 @@ import android.arch.persistence.room.Query;
@Dao
public interface UserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
- void insert(User user);
+ void insert(UserData userData);
@Query("DELETE FROM users")
void deleteAllUsers();
- @Query("SELECT * FROM users WHERE user_name = :userName LIMIT 1")
- User getUserData(String userName);
+ @Query("SELECT * FROM users WHERE name = :userName LIMIT 1")
+ LiveData<UserData> getUserLiveData(String userName);
+
+ @Query("SELECT * FROM users WHERE name = :userName LIMIT 1")
+ UserData getUserData(String userName);
}
diff --git a/app/src/main/java/User/User.java b/app/src/main/java/User/UserData.java
index 3fd8dcb3..89eafb96 100644
--- a/app/src/main/java/User/User.java
+++ b/app/src/main/java/User/UserData.java
@@ -2,17 +2,12 @@ package User;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
-import android.arch.persistence.room.PrimaryKey;
import android.support.annotation.NonNull;
+import SubscribedUserDatabase.SubscribedUserData;
+
@Entity(tableName = "users")
-public class User {
- @PrimaryKey
- @NonNull
- @ColumnInfo(name = "user_name")
- private String userName;
- @ColumnInfo(name = "icon")
- private String icon;
+public class UserData extends SubscribedUserData {
@ColumnInfo(name = "banner")
private String banner;
@ColumnInfo(name = "karma")
@@ -22,24 +17,14 @@ public class User {
@ColumnInfo(name = "is_friend")
private boolean isFriend;
- User(@NonNull String userName, String icon, String banner, int karma, boolean isGold, boolean isFriend) {
- this.userName = userName;
- this.icon = icon;
+ public UserData(@NonNull String name, String iconUrl, String banner, int karma, boolean isGold, boolean isFriend) {
+ super(name, iconUrl);
this.banner = banner;
this.karma = karma;
this.isGold = isGold;
this.isFriend = isFriend;
}
- @NonNull
- public String getUserName() {
- return userName;
- }
-
- public String getIcon() {
- return icon;
- }
-
public String getBanner() {
return banner;
}
diff --git a/app/src/main/java/User/UserRepository.java b/app/src/main/java/User/UserRepository.java
new file mode 100644
index 00000000..d505db2b
--- /dev/null
+++ b/app/src/main/java/User/UserRepository.java
@@ -0,0 +1,39 @@
+package User;
+
+import android.app.Application;
+import android.arch.lifecycle.LiveData;
+import android.os.AsyncTask;
+
+public class UserRepository {
+ private UserDao mUserDao;
+ private LiveData<UserData> mUserLiveData;
+
+ UserRepository(Application application, String userName) {
+ mUserDao = UserRoomDatabase.getDatabase(application).userDao();
+
+ mUserLiveData = mUserDao.getUserLiveData(userName);
+ }
+
+ LiveData<UserData> getUserLiveData() {
+ return mUserLiveData;
+ }
+
+ public void insert(UserData userData) {
+ new InsertAsyncTask(mUserDao).execute(userData);
+ }
+
+ private static class InsertAsyncTask extends AsyncTask<UserData, Void, Void> {
+
+ private UserDao mAsyncTaskDao;
+
+ InsertAsyncTask(UserDao dao) {
+ mAsyncTaskDao = dao;
+ }
+
+ @Override
+ protected Void doInBackground(final UserData... params) {
+ mAsyncTaskDao.insert(params[0]);
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/User/UserRoomDatabase.java b/app/src/main/java/User/UserRoomDatabase.java
index 31ca1259..288400a6 100644
--- a/app/src/main/java/User/UserRoomDatabase.java
+++ b/app/src/main/java/User/UserRoomDatabase.java
@@ -5,7 +5,7 @@ import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
import android.content.Context;
-@Database(entities = {User.class}, version = 1)
+@Database(entities = {UserData.class}, version = 1)
public abstract class UserRoomDatabase extends RoomDatabase {
private static UserRoomDatabase INSTANCE;
diff --git a/app/src/main/java/User/UserViewModel.java b/app/src/main/java/User/UserViewModel.java
new file mode 100644
index 00000000..a006e253
--- /dev/null
+++ b/app/src/main/java/User/UserViewModel.java
@@ -0,0 +1,48 @@
+package User;
+
+import android.app.Application;
+import android.arch.lifecycle.AndroidViewModel;
+import android.arch.lifecycle.LiveData;
+import android.arch.lifecycle.ViewModel;
+import android.arch.lifecycle.ViewModelProvider;
+import android.support.annotation.NonNull;
+
+import SubredditDatabase.SubredditViewModel;
+
+public class UserViewModel extends AndroidViewModel {
+ private UserRepository mSubredditRepository;
+ private LiveData<UserData> mUserLiveData;
+
+ public UserViewModel(Application application, String id) {
+ super(application);
+ mSubredditRepository = new UserRepository(application, id);
+ mUserLiveData = mSubredditRepository.getUserLiveData();
+ }
+
+ public LiveData<UserData> getUserLiveData() {
+ return mUserLiveData;
+ }
+
+ public void insert(UserData userData) {
+ mSubredditRepository.insert(userData);
+ }
+
+ public static class Factory extends ViewModelProvider.NewInstanceFactory {
+
+ @NonNull
+ private final Application mApplication;
+
+ private final String userName;
+
+ public Factory(@NonNull Application application, String userName) {
+ mApplication = application;
+ this.userName = userName;
+ }
+
+ @Override
+ public <T extends ViewModel> T create(Class<T> modelClass) {
+ //noinspection unchecked
+ return (T) new UserViewModel(mApplication, userName);
+ }
+ }
+}
diff --git a/app/src/main/java/User/FetchUserData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserData.java
index edaa3b14..9bfcf7c3 100644
--- a/app/src/main/java/User/FetchUserData.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserData.java
@@ -1,16 +1,16 @@
-package User;
+package ml.docilealligator.infinityforreddit;
import android.support.annotation.NonNull;
import android.util.Log;
-import ml.docilealligator.infinityforreddit.RedditAPI;
+import User.UserData;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Retrofit;
public class FetchUserData {
public interface FetchUserDataListener {
- void onFetchUserDataSuccess(User user);
+ void onFetchUserDataSuccess(UserData userData);
void onFetchUserDataFail();
}
@@ -23,10 +23,10 @@ public class FetchUserData {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) {
if(response.isSuccessful()) {
- ParseUserData.parseMyInfo(response.body(), new ParseUserData.ParseUserDataListener() {
+ ParseUserData.parseUserData(response.body(), new ParseUserData.ParseUserDataListener() {
@Override
- public void onParseUserDataSuccess(User user) {
- fetchUserDataListener.onFetchUserDataSuccess(user);
+ public void onParseUserDataSuccess(UserData userData) {
+ fetchUserDataListener.onFetchUserDataSuccess(userData);
}
@Override
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/User/ParseUserData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseUserData.java
index b6a7a39c..12402f03 100644
--- a/app/src/main/java/User/ParseUserData.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseUserData.java
@@ -1,4 +1,4 @@
-package User;
+package ml.docilealligator.infinityforreddit;
import android.os.AsyncTask;
import android.util.Log;
@@ -6,15 +6,15 @@ import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
-import ml.docilealligator.infinityforreddit.JSONUtils;
+import User.UserData;
public class ParseUserData {
interface ParseUserDataListener {
- void onParseUserDataSuccess(User user);
+ void onParseUserDataSuccess(UserData userData);
void onParseUserDataFail();
}
- static void parseMyInfo(String response, ParseUserDataListener parseUserDataListener) {
+ static void parseUserData(String response, ParseUserDataListener parseUserDataListener) {
new ParseUserDataAsyncTask(response, parseUserDataListener).execute();
}
@@ -23,15 +23,16 @@ public class ParseUserData {
private ParseUserDataListener parseUserDataListener;
private boolean parseFailed;
- private User user;
+ 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("user data json error", e.getMessage());
+ Log.i("userdata json error", e.getMessage());
parseUserDataListener.onParseUserDataFail();
}
}
@@ -43,7 +44,7 @@ public class ParseUserData {
String userName = jsonResponse.getString(JSONUtils.NAME_KEY);
String iconImageUrl = jsonResponse.getString(JSONUtils.ICON_IMG_KEY);
String bannerImageUrl = "";
- if(!jsonResponse.isNull(JSONUtils.SUBREDDIT_KEY)) {
+ 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);
@@ -52,7 +53,7 @@ public class ParseUserData {
boolean isGold = jsonResponse.getBoolean(JSONUtils.IS_GOLD_KEY);
boolean isFriend = jsonResponse.getBoolean(JSONUtils.IS_FRIEND_KEY);
- user = new User(userName, iconImageUrl, bannerImageUrl, karma, isGold, isFriend);
+ userData = new UserData(userName, iconImageUrl, bannerImageUrl, karma, isGold, isFriend);
} catch (JSONException e) {
parseFailed = true;
Log.i("parse user data error", e.getMessage());
@@ -63,7 +64,7 @@ public class ParseUserData {
@Override
protected void onPostExecute(Void aVoid) {
if(!parseFailed) {
- parseUserDataListener.onParseUserDataSuccess(user);
+ 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();
+ }
+ }
}
}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 4e6dd8aa..5da5a9d3 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -35,6 +35,7 @@
layout="@layout/nav_header_main" />
<LinearLayout
+ android:id="@+id/profile_linear_layout_main_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
diff --git a/app/src/main/res/layout/activity_view_user_detail.xml b/app/src/main/res/layout/activity_view_user_detail.xml
index 76dbba91..a292d390 100644
--- a/app/src/main/res/layout/activity_view_user_detail.xml
+++ b/app/src/main/res/layout/activity_view_user_detail.xml
@@ -4,33 +4,97 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:fitsSystemWindows="true"
+ android:id="@+id/coordinator_layout_view_user_detail_activity"
tools:context=".ViewUserDetailActivity">
<android.support.design.widget.AppBarLayout
- android:id="@+id/app_bar"
+ android:id="@+id/app_bar_layout_view_user_detail_activity"
android:layout_width="match_parent"
- android:layout_height="@dimen/app_bar_height"
- android:fitsSystemWindows="true"
+ android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
- android:id="@+id/toolbar_layout"
+ android:id="@+id/collapsing_toolbar_layout_view_user_detail_activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
- app:layout_scrollFlags="scroll|exitUntilCollapsed"
+ app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
app:toolbarId="@+id/toolbar">
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ImageView
+ android:id="@+id/banner_image_view_view_user_detail_activity"
+ android:layout_width="match_parent"
+ android:scaleType="centerCrop"
+ android:layout_height="180dp"
+ android:contentDescription="@string/content_description_banner_imageview" />
+
+ <com.felipecsl.gifimageview.library.GifImageView
+ android:id="@+id/icon_gif_image_view_view_user_detail_activity"
+ android:layout_width="72dp"
+ android:layout_height="72dp"
+ android:layout_marginTop="-36dp"
+ app:civ_border_color="@android:color/white"
+ app:civ_border_width="1dp"
+ android:layout_below="@id/banner_image_view_view_user_detail_activity"
+ android:layout_centerHorizontal="true"
+ android:elevation="4dp"
+ app:civ_circle_background_color="@android:color/white"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingTop="36dp"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:layout_below="@id/banner_image_view_view_user_detail_activity"
+ android:background="@android:color/white">
+
+ <TextView
+ android:id="@+id/user_name_text_view_view_user_detail_activity"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:textSize="18sp"
+ android:textColor="@color/colorAccent"
+ android:layout_gravity="center_horizontal"/>
+
+ <TextView
+ android:id="@+id/karma_text_view_view_user_detail_activity"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:textColor="@android:color/black"
+ android:layout_gravity="center_horizontal"/>
+
+ <android.support.design.chip.Chip
+ android:id="@+id/subscribe_user_chip_view_user_detail_activity"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:layout_marginBottom="16dp"
+ android:textColor="@android:color/white"
+ android:layout_gravity="center_horizontal"/>
+
+ </LinearLayout>
+
+ </RelativeLayout>
+
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
- app:popupTheme="@style/AppTheme.PopupOverlay" />
+ app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
+ app:popupTheme="@style/AppTheme.PopupOverlay"
+ app:navigationIcon="?attr/homeAsUpIndicator"/>
</android.support.design.widget.CollapsingToolbarLayout>
+
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_view_user_detail" />
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7084659c..cab97bbb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -26,6 +26,8 @@
<string name="subscriptions">Subscriptions</string>
<string name="subscribers_number_detail">Subscribers: %1$d</string>
<string name="online_subscribers_number_detail">Online: %1$d</string>
+ <string name="cannot_fetch_subreddit_info">Cannot fetch subreddit info</string>
+ <string name="cannot_fetch_user_info">Cannot fetch user info</string>
<string name="gilded">x%1$d</string>
<string name="title_activity_view_user_detail">ViewUserDetailActivity</string>
@@ -49,15 +51,15 @@
"and use of imagery guide visual treatments. These elements do far more than please the "
"eye. They create hierarchy, meaning, and focus. Deliberate color choices, edge to edge "
"imagery, large scale typography, and intentional white space create a bold and graphic "
- "interface that immerse the user in the experience.\n"
- "An emphasis on user actions makes core functionality immediately apparent and provides "
- "waypoints for the user.\n\n"
+ "interface that immerse the userData in the experience.\n"
+ "An emphasis on userData actions makes core functionality immediately apparent and provides "
+ "waypoints for the userData.\n\n"
"Motion provides meaning.\n\n"
- "Motion respects and reinforces the user as the prime mover. Primary user actions are "
+ "Motion respects and reinforces the userData as the prime mover. Primary userData actions are "
"inflection points that initiate motion, transforming the whole design.\n"
- "All action takes place in a single environment. Objects are presented to the user without "
+ "All action takes place in a single environment. Objects are presented to the userData without "
"breaking the continuity of experience even as they transform and reorganize.\n"
"Motion is meaningful and appropriate, serving to focus attention and maintain continuity. "
"Feedback is subtle yet clear. Transitions are efficient yet coherent.\n\n"
@@ -96,7 +98,7 @@
"Responsive elevation and dynamic elevation offsets.\n\n"
"Some component types have responsive elevation, meaning they change elevation in response "
- "to user input (e.g., normal, focused, and pressed) or system events. These elevation "
+ "to userData input (e.g., normal, focused, and pressed) or system events. These elevation "
"changes are consistently implemented using dynamic elevation offsets.\n"
"Dynamic elevation offsets are the goal elevation that a component moves towards, relative "
"to the component’s resting state. They ensure that elevation changes are consistent "
@@ -113,10 +115,10 @@
"whether on a per component basis or using the entire app layout.\n"
"On a component level, components can move or be removed before they cause interference. "
"For example, a floating action button (FAB) can disappear or move off screen before a "
- "user picks up a card, or it can move if a snackbar appears.\n"
+ "userData picks up a card, or it can move if a snackbar appears.\n"
"On the layout level, design your app layout to minimize opportunities for interference. "
"For example, position the FAB to one side of stream of a cards so the FAB won’t interfere "
- "when a user tries to pick up one of cards.\n\n"
+ "when a userData tries to pick up one of cards.\n\n"
</string>
<string name="subscribe">Subscribe</string>
@@ -126,5 +128,12 @@
<string name="unsubscribed">Unsubscribed</string>"
<string name="unsubscribe_failed">Unsubscribe Failed</string>
+ <string name="follow">Follow</string>
+ <string name="unfollow">Unfollow</string>
+ <string name="followed">Followed</string>
+ <string name="follow_failed">Following Failed</string>
+ <string name="unfollowed">Unfollowed</string>
+ <string name="unfollow_failed">Unfollowing Failed</string>
+
<string name="content_description_banner_imageview">Subreddit Banner Image</string>
</resources>