mirror of
https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy.git
synced 2025-02-02 21:04:48 +01:00
View user details in ViewUserDetailActivity. Follow or unfollow user is not properly implemented right now. Change users and subscribed_users databases' schemes. Press Profile in navigation drawer to view my reddit info. Press the username in the post to view that account's info.
This commit is contained in:
parent
f0b149ce82
commit
e48bb565a5
@ -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>
|
@ -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")
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
39
app/src/main/java/User/UserRepository.java
Normal file
39
app/src/main/java/User/UserRepository.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
|
48
app/src/main/java/User/UserViewModel.java
Normal file
48
app/src/main/java/User/UserViewModel.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>>() {
|
||||
|
@ -11,4 +11,5 @@ interface NetworkComponent {
|
||||
void inject(PostFragment postFragment);
|
||||
void inject(ViewPostDetailActivity viewPostDetailActivity);
|
||||
void inject(ViewSubredditDetailActivity viewSubredditDetailActivity);
|
||||
void inject(ViewUserDetailActivity viewUserDetailActivity);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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<>();
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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" />
|
||||
|
@ -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>
|
||||
|
2
gradlew
vendored
2
gradlew
vendored
@ -119,7 +119,7 @@ if $cygwin ; then
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
# Add a userData-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
|
Loading…
x
Reference in New Issue
Block a user