Display user name and user icon in each post when loading posts in specific subreddits.

This commit is contained in:
Alex Ning 2019-01-01 23:32:03 +08:00
parent f529bba550
commit 49d25314d5
20 changed files with 603 additions and 173 deletions

View File

@ -20,6 +20,6 @@ public interface SubredditDao {
@Query("SELECT * from subreddits WHERE name = :namePrefixed")
LiveData<SubredditData> getSubredditLiveDataByNamePrefixed(String namePrefixed);
@Query("SELECT * from subreddits WHERE name = :namePrefixed")
@Query("SELECT * from subreddits WHERE name = :namePrefixed LIMIT 1")
SubredditData getSubredditData(String namePrefixed);
}

View File

@ -0,0 +1,50 @@
package User;
import android.support.annotation.NonNull;
import android.util.Log;
import ml.docilealligator.infinityforreddit.RedditAPI;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Retrofit;
public class FetchUserData {
public interface FetchUserDataListener {
void onFetchUserDataSuccess(User user);
void onFetchUserDataFail();
}
public static void fetchUserData(final Retrofit retrofit, String userName,
final FetchUserDataListener fetchUserDataListener) {
RedditAPI api = retrofit.create(RedditAPI.class);
Call<String> userInfo = api.getUserData(userName);
userInfo.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) {
if(response.isSuccessful()) {
ParseUserData.parseMyInfo(response.body(), new ParseUserData.ParseUserDataListener() {
@Override
public void onParseUserDataSuccess(User user) {
fetchUserDataListener.onFetchUserDataSuccess(user);
}
@Override
public void onParseUserDataFail() {
fetchUserDataListener.onFetchUserDataFail();
}
});
} else {
Log.i("call failed", response.message());
fetchUserDataListener.onFetchUserDataFail();
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Log.i("call failed", t.getMessage());
fetchUserDataListener.onFetchUserDataFail();
}
});
}
}

View File

@ -0,0 +1,72 @@
package User;
import android.os.AsyncTask;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import ml.docilealligator.infinityforreddit.JSONUtils;
public class ParseUserData {
interface ParseUserDataListener {
void onParseUserDataSuccess(User user);
void onParseUserDataFail();
}
static void parseMyInfo(String response, ParseUserDataListener parseUserDataListener) {
new ParseUserDataAsyncTask(response, parseUserDataListener).execute();
}
private static class ParseUserDataAsyncTask extends AsyncTask<Void, Void, Void> {
private JSONObject jsonResponse;
private ParseUserDataListener parseUserDataListener;
private boolean parseFailed;
private User user;
ParseUserDataAsyncTask(String response, ParseUserDataListener parseUserDataListener){
try {
jsonResponse = new JSONObject(response);
this.parseUserDataListener = parseUserDataListener;
parseFailed = false;
} catch (JSONException e) {
Log.i("user data json error", e.getMessage());
parseUserDataListener.onParseUserDataFail();
}
}
@Override
protected Void doInBackground(Void... voids) {
try {
jsonResponse = jsonResponse.getJSONObject(JSONUtils.DATA_KEY);
String userName = jsonResponse.getString(JSONUtils.NAME_KEY);
String iconImageUrl = jsonResponse.getString(JSONUtils.ICON_IMG_KEY);
String bannerImageUrl = "";
if(!jsonResponse.isNull(JSONUtils.SUBREDDIT_KEY)) {
bannerImageUrl = jsonResponse.getJSONObject(JSONUtils.SUBREDDIT_KEY).getString(JSONUtils.BANNER_IMG_KEY);
}
int linkKarma = jsonResponse.getInt(JSONUtils.LINK_KARMA_KEY);
int commentKarma = jsonResponse.getInt(JSONUtils.COMMENT_KARMA_KEY);
int karma = linkKarma + commentKarma;
boolean isGold = jsonResponse.getBoolean(JSONUtils.IS_GOLD_KEY);
boolean isFriend = jsonResponse.getBoolean(JSONUtils.IS_FRIEND_KEY);
user = new User(userName, iconImageUrl, bannerImageUrl, karma, isGold, isFriend);
} catch (JSONException e) {
parseFailed = true;
Log.i("parse user data error", e.getMessage());
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
if(!parseFailed) {
parseUserDataListener.onParseUserDataSuccess(user);
} else {
parseUserDataListener.onParseUserDataFail();
}
}
}
}

View File

@ -0,0 +1,58 @@
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;
@Entity(tableName = "users")
public class User {
@PrimaryKey
@NonNull
@ColumnInfo(name = "user_name")
private String userName;
@ColumnInfo(name = "icon")
private String icon;
@ColumnInfo(name = "banner")
private String banner;
@ColumnInfo(name = "karma")
private int karma;
@ColumnInfo(name = "is_gold")
private boolean isGold;
@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;
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;
}
public int getKarma() {
return karma;
}
public boolean isGold() {
return isGold;
}
public boolean isFriend() {
return isFriend;
}
}

View File

@ -0,0 +1,18 @@
package User;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Query;
@Dao
public interface UserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(User user);
@Query("DELETE FROM users")
void deleteAllUsers();
@Query("SELECT * FROM users WHERE user_name = :userName LIMIT 1")
User getUserData(String userName);
}

View File

@ -1,4 +0,0 @@
package User;
public class UserData {
}

View File

@ -0,0 +1,26 @@
package User;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
import android.content.Context;
@Database(entities = {User.class}, version = 1)
public abstract class UserRoomDatabase extends RoomDatabase {
private static UserRoomDatabase INSTANCE;
public abstract UserDao userDao();
public static UserRoomDatabase getDatabase(final Context context) {
if(INSTANCE == null) {
synchronized (UserRoomDatabase.class) {
if(INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
UserRoomDatabase.class, "users")
.build();
}
}
}
return INSTANCE;
}
}

View File

@ -8,34 +8,34 @@ import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Retrofit;
class FetchUserInfo {
class FetchMyInfo {
interface FetchUserInfoListener {
void onFetchUserInfoSuccess(String response);
void onFetchUserInfoFail();
interface FetchUserMyListener {
void onFetchMyInfoSuccess(String response);
void onFetchMyInfoFail();
}
static void fetchUserInfo(final Retrofit retrofit, SharedPreferences authInfoSharedPreferences,
final FetchUserInfoListener fetchUserInfoListener) {
static void fetchMyInfo(final Retrofit retrofit, SharedPreferences authInfoSharedPreferences,
final FetchUserMyListener fetchUserMyListener) {
RedditAPI api = retrofit.create(RedditAPI.class);
String accessToken = authInfoSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
Call<String> userInfo = api.getUserInfo(RedditUtils.getOAuthHeader(accessToken));
Call<String> userInfo = api.getMyInfo(RedditUtils.getOAuthHeader(accessToken));
userInfo.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) {
if(response.isSuccessful()) {
fetchUserInfoListener.onFetchUserInfoSuccess(response.body());
fetchUserMyListener.onFetchMyInfoSuccess(response.body());
} else {
Log.i("call failed", response.message());
fetchUserInfoListener.onFetchUserInfoFail();
fetchUserMyListener.onFetchMyInfoFail();
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Log.i("call failed", t.getMessage());
fetchUserInfoListener.onFetchUserInfoFail();
fetchUserMyListener.onFetchMyInfoFail();
}
});
}

View File

@ -0,0 +1,36 @@
package ml.docilealligator.infinityforreddit;
import android.os.AsyncTask;
import User.User;
import User.UserDao;
public class InsertUserDataAsyncTask extends AsyncTask<Void, Void, Void> {
private UserDao userDao;
private User user;
private InsertUserDataCallback insertUserDataCallback;
public interface InsertUserDataCallback {
void insertSuccess();
}
public InsertUserDataAsyncTask(UserDao userDao, User user, InsertUserDataCallback insertUserDataCallback) {
this.userDao = userDao;
this.user = user;
this.insertUserDataCallback = insertUserDataCallback;
}
@Override
protected Void doInBackground(Void... voids) {
userDao.insert(user);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(insertUserDataCallback != null) {
insertUserDataCallback.insertSuccess();
}
}
}

View File

@ -4,14 +4,14 @@ package ml.docilealligator.infinityforreddit;
* Created by alex on 2/25/18.
*/
class JSONUtils {
static final String DATA_KEY = "data";
public class JSONUtils {
public static final String DATA_KEY = "data";
static final String AFTER_KEY = "after";
static final String MODHASH_KEY = "modhash";
static final String CHILDREN_KEY = "children";
static final String COUNT_KEY = "count";
static final String TITLE_KEY = "title";
static final String NAME_KEY = "name";
public static final String NAME_KEY = "name";
static final String SUBREDDIT_NAME_PREFIX_KEY = "subreddit_name_prefixed";
static final String SELFTEXT_HTML_KEY = "selftext_html";
static final String AUTHOR_KEY = "author";
@ -51,13 +51,13 @@ class JSONUtils {
static final String DEPTH_KEY = "depth";
static final String ID_KEY = "id";
static final String SCORE_HIDDEN_KEY = "score_hidden";
static final String SUBREDDIT_KEY = "subreddit";
static final String BANNER_IMG_KEY = "banner_img";
public static final String SUBREDDIT_KEY = "subreddit";
public static final String BANNER_IMG_KEY = "banner_img";
static final String BANNER_BACKGROUND_IMAGE_KEY = "banner_background_image";
static final String ICON_IMG_KEY = "icon_img";
public static final String ICON_IMG_KEY = "icon_img";
static final String COMMUNITY_ICON_KEY = "community_icon";
static final String LINK_KARMA_KEY = "link_karma";
static final String COMMENT_KARMA_KEY = "comment_karma";
public static final String LINK_KARMA_KEY = "link_karma";
public static final String COMMENT_KARMA_KEY = "comment_karma";
static final String DISPLAY_NAME = "display_name";
static final String SUBREDDIT_TYPE_KEY = "subreddit_type";
static final String SUBREDDIT_TYPE_VALUE_USER = "user";
@ -66,4 +66,6 @@ class JSONUtils {
static final String ACTIVE_USER_COUNT_KEY = "active_user_count";
static final String DISPLAY_NAME_PREFIXED_KEY = "display_name_prefixed";
static final String LINK_ID_KEY = "link_id";
public static final String IS_GOLD_KEY = "is_gold";
public static final String IS_FRIEND_KEY = "is_friend";
}

View File

@ -0,0 +1,64 @@
package ml.docilealligator.infinityforreddit;
import android.os.AsyncTask;
import User.FetchUserData;
import User.User;
import User.UserDao;
import retrofit2.Retrofit;
public class LoadUserDataAsyncTask extends AsyncTask<Void, Void, Void> {
interface LoadUserDataAsyncTaskListener {
void loadUserDataSuccess(String iconImageUrl);
}
private UserDao userDao;
private String userName;
private String iconImageUrl;
private boolean hasUserInDb;
private Retrofit retrofit;
private LoadUserDataAsyncTaskListener loadUserDataAsyncTaskListener;
LoadUserDataAsyncTask(UserDao userDao, String userName, Retrofit retrofit, LoadUserDataAsyncTaskListener loadUserDataAsyncTaskListener) {
this.userDao = userDao;
this.userName = userName;
this.retrofit = retrofit;
this.loadUserDataAsyncTaskListener = loadUserDataAsyncTaskListener;
}
@Override
protected Void doInBackground(Void... voids) {
if(userDao.getUserData(userName) != null) {
iconImageUrl = userDao.getUserData(userName).getIcon();
hasUserInDb = true;
} else {
hasUserInDb = false;
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(hasUserInDb) {
loadUserDataAsyncTaskListener.loadUserDataSuccess(iconImageUrl);
} 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();
}
@Override
public void onFetchUserDataFail() {
loadUserDataAsyncTaskListener.loadUserDataSuccess("");
}
});
}
}
}

View File

@ -202,12 +202,12 @@ public class MainActivity extends AppCompatActivity {
private void loadUserData(Bundle savedInstanceState) {
if (savedInstanceState == null) {
if (!mFetchUserInfoSuccess) {
FetchUserInfo.fetchUserInfo(mOauthRetrofit, mAuthInfoSharedPreferences, new FetchUserInfo.FetchUserInfoListener() {
FetchMyInfo.fetchMyInfo(mOauthRetrofit, mAuthInfoSharedPreferences, new FetchMyInfo.FetchUserMyListener() {
@Override
public void onFetchUserInfoSuccess(String response) {
ParseUserInfo.parseUserInfo(response, new ParseUserInfo.ParseUserInfoListener() {
public void onFetchMyInfoSuccess(String response) {
ParseMyInfo.parseMyInfo(response, new ParseMyInfo.ParseMyInfoListener() {
@Override
public void onParseUserInfoSuccess(String name, String profileImageUrl, String bannerImageUrl, int karma) {
public void onParseMyInfoSuccess(String name, String profileImageUrl, String bannerImageUrl, int karma) {
mNameTextView.setText(name);
if (!mProfileImageUrl.equals("")) {
glide.load(profileImageUrl).into(mProfileImageView);
@ -233,14 +233,14 @@ public class MainActivity extends AppCompatActivity {
}
@Override
public void onParseUserInfoFail() {
public void onParseMyInfoFail() {
mFetchUserInfoSuccess = false;
}
});
}
@Override
public void onFetchUserInfoFail() {
public void onFetchMyInfoFail() {
mFetchUserInfoSuccess = false;
}
});

View File

@ -7,19 +7,19 @@ import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
class ParseUserInfo {
interface ParseUserInfoListener {
void onParseUserInfoSuccess(String name, String profileImageUrl, String bannerImageUrl, int karma);
void onParseUserInfoFail();
class ParseMyInfo {
interface ParseMyInfoListener {
void onParseMyInfoSuccess(String name, String profileImageUrl, String bannerImageUrl, int karma);
void onParseMyInfoFail();
}
static void parseUserInfo(String response, ParseUserInfoListener parseUserInfoListener) {
new ParseUserInfoAsyncTask(response, parseUserInfoListener).execute();
static void parseMyInfo(String response, ParseMyInfoListener parseMyInfoListener) {
new ParseMyInfoAsyncTask(response, parseMyInfoListener).execute();
}
private static class ParseUserInfoAsyncTask extends AsyncTask<Void, Void, Void> {
private static class ParseMyInfoAsyncTask extends AsyncTask<Void, Void, Void> {
private JSONObject jsonResponse;
private ParseUserInfoListener parseUserInfoListener;
private ParseMyInfoListener parseMyInfoListener;
private boolean parseFailed;
private String name;
@ -27,14 +27,14 @@ class ParseUserInfo {
private String bannerImageUrl;
private int karma;
ParseUserInfoAsyncTask(String response, ParseUserInfoListener parseUserInfoListener){
ParseMyInfoAsyncTask(String response, ParseMyInfoListener parseMyInfoListener){
try {
jsonResponse = new JSONObject(response);
this.parseUserInfoListener = parseUserInfoListener;
this.parseMyInfoListener = parseMyInfoListener;
parseFailed = false;
} catch (JSONException e) {
Log.i("user info json error", e.getMessage());
parseUserInfoListener.onParseUserInfoFail();
parseMyInfoListener.onParseMyInfoFail();
}
}
@ -43,7 +43,9 @@ class ParseUserInfo {
try {
name = jsonResponse.getString(JSONUtils.NAME_KEY);
profileImageUrl = Html.fromHtml(jsonResponse.getString(JSONUtils.ICON_IMG_KEY)).toString();
bannerImageUrl = Html.fromHtml(jsonResponse.getJSONObject(JSONUtils.SUBREDDIT_KEY).getString(JSONUtils.BANNER_IMG_KEY)).toString();
if(!jsonResponse.isNull(JSONUtils.SUBREDDIT_KEY)) {
bannerImageUrl = Html.fromHtml(jsonResponse.getJSONObject(JSONUtils.SUBREDDIT_KEY).getString(JSONUtils.BANNER_IMG_KEY)).toString();
}
int linkKarma = jsonResponse.getInt(JSONUtils.LINK_KARMA_KEY);
int commentKarma = jsonResponse.getInt(JSONUtils.COMMENT_KARMA_KEY);
karma = linkKarma + commentKarma;
@ -57,9 +59,9 @@ class ParseUserInfo {
@Override
protected void onPostExecute(Void aVoid) {
if(!parseFailed) {
parseUserInfoListener.onParseUserInfoSuccess(name, profileImageUrl, bannerImageUrl, karma);
parseMyInfoListener.onParseMyInfoSuccess(name, profileImageUrl, bannerImageUrl, karma);
} else {
parseUserInfoListener.onParseUserInfoFail();
parseMyInfoListener.onParseMyInfoFail();
}
}
}

View File

@ -59,6 +59,7 @@ class ParsePost {
String id = data.getString(JSONUtils.ID_KEY);
String fullName = data.getString(JSONUtils.NAME_KEY);
String subredditNamePrefixed = data.getString(JSONUtils.SUBREDDIT_NAME_PREFIX_KEY);
String author = data.getString(JSONUtils.AUTHOR_KEY);
long postTime = data.getLong(JSONUtils.CREATED_UTC_KEY) * 1000;
String title = data.getString(JSONUtils.TITLE_KEY);
int score = data.getInt(JSONUtils.SCORE_KEY);
@ -95,11 +96,11 @@ class ParsePost {
//Cross post
data = data.getJSONArray(JSONUtils.CROSSPOST_PARENT_LIST).getJSONObject(0);
parseData(data, permalink, newPosts, id, fullName, subredditNamePrefixed,
formattedPostTime, title, previewUrl, previewWidth, previewHeight,
author, formattedPostTime, title, previewUrl, previewWidth, previewHeight,
score, voteType, gilded, nsfw, stickied, true, i);
} else {
parseData(data, permalink, newPosts, id, fullName, subredditNamePrefixed,
formattedPostTime, title, previewUrl, previewWidth, previewHeight,
author, formattedPostTime, title, previewUrl, previewWidth, previewHeight,
score, voteType, gilded, nsfw, stickied, false, i);
}
}
@ -121,9 +122,10 @@ class ParsePost {
}
private static void parseData(JSONObject data, String permalink, ArrayList<Post> bestPostData,
String id, String fullName, String subredditNamePrefixed, String formattedPostTime,
String title, String previewUrl, int previewWidth, int previewHeight ,int score, int voteType, int gilded,
boolean nsfw, boolean stickied, boolean isCrosspost, int i) throws JSONException {
String id, String fullName, String subredditNamePrefixed, String author,
String formattedPostTime, String title, String previewUrl, int previewWidth,
int previewHeight ,int score, int voteType, int gilded,
boolean nsfw, boolean stickied, boolean isCrosspost, int i) throws JSONException {
boolean isVideo = data.getBoolean(JSONUtils.IS_VIDEO_KEY);
String url = data.getString(JSONUtils.URL_KEY);
@ -132,7 +134,7 @@ class ParsePost {
//Text post
Log.i("text", Integer.toString(i));
int postType = Post.TEXT_TYPE;
Post post = new Post(id, fullName, subredditNamePrefixed, formattedPostTime,
Post post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime,
title, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost);
if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) {
post.setSelfText("");
@ -144,7 +146,7 @@ class ParsePost {
//No preview link post
Log.i("no preview link", Integer.toString(i));
int postType = Post.NO_PREVIEW_LINK_TYPE;
Post linkPost = new Post(id, fullName, subredditNamePrefixed, formattedPostTime,
Post linkPost = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime,
title, previewUrl, url, permalink, score, postType,
voteType, gilded, nsfw, stickied, isCrosspost);
if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) {
@ -161,7 +163,7 @@ class ParsePost {
int postType = Post.VIDEO_TYPE;
String videoUrl = redditVideoObject.getString(JSONUtils.DASH_URL_KEY);
Post videoPost = new Post(id, fullName, subredditNamePrefixed, formattedPostTime,
Post videoPost = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime,
title, previewUrl, permalink, score, postType, voteType,
gilded, nsfw, stickied, isCrosspost, true);
@ -179,7 +181,7 @@ class ParsePost {
int postType = Post.GIF_VIDEO_TYPE;
String videoUrl = variations.getJSONObject(JSONUtils.VARIANTS_KEY).getJSONObject(JSONUtils.MP4_KEY).getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY);
String gifDownloadUrl = variations.getJSONObject(JSONUtils.VARIANTS_KEY).getJSONObject(JSONUtils.GIF_KEY).getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY);
Post post = new Post(id, fullName, subredditNamePrefixed, formattedPostTime, title,
Post post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title,
previewUrl, permalink, score, postType, voteType,
gilded, nsfw, stickied, isCrosspost, false);
@ -197,7 +199,7 @@ class ParsePost {
String videoUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY)
.getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.DASH_URL_KEY);
Post post = new Post(id, fullName, subredditNamePrefixed, formattedPostTime, title,
Post post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title,
previewUrl, permalink, score, postType, voteType,
gilded, nsfw, stickied, isCrosspost, true);
@ -213,7 +215,7 @@ class ParsePost {
Log.i("image", Integer.toString(i));
int postType = Post.IMAGE_TYPE;
Post imagePost = new Post(id, fullName, subredditNamePrefixed, formattedPostTime,
Post imagePost = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime,
title, url, url, permalink, score, postType,
voteType, gilded, nsfw, stickied, isCrosspost);
@ -226,7 +228,7 @@ class ParsePost {
//Text post but with a preview
Log.i("text with image", Integer.toString(i));
int postType = Post.TEXT_TYPE;
Post textWithImagePost = new Post(id, fullName, subredditNamePrefixed, formattedPostTime,
Post textWithImagePost = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime,
title, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost);
textWithImagePost.setPreviewWidth(previewWidth);
@ -242,7 +244,7 @@ class ParsePost {
//Link post
Log.i("link", Integer.toString(i));
int postType = Post.LINK_TYPE;
Post linkPost = new Post(id, fullName, subredditNamePrefixed, formattedPostTime,
Post linkPost = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime,
title, previewUrl, url, permalink, score,
postType, voteType, gilded, nsfw, stickied, isCrosspost);
if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) {
@ -263,7 +265,7 @@ class ParsePost {
//Image post
Log.i("CP image", Integer.toString(i));
int postType = Post.IMAGE_TYPE;
Post linkPost = new Post(id, fullName, subredditNamePrefixed, formattedPostTime,
Post linkPost = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime,
title, previewUrl, url, permalink, score, postType,
voteType, gilded, nsfw, stickied, isCrosspost);
linkPost.setPreviewWidth(previewWidth);
@ -273,7 +275,7 @@ class ParsePost {
//CP No Preview Link post
Log.i("CP no preview link", Integer.toString(i));
int postType = Post.NO_PREVIEW_LINK_TYPE;
bestPostData.add(new Post(id, fullName, subredditNamePrefixed, formattedPostTime, title,
bestPostData.add(new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title,
url, url, permalink, score, postType, voteType,
gilded, nsfw, stickied, isCrosspost));
}

View File

@ -19,6 +19,8 @@ class Post implements Parcelable {
private String fullName;
private String subredditNamePrefixed;
private String subredditIconUrl;
private String author;
private String authorIconUrl;
private String postTime;
private String title;
private String selfText;
@ -40,12 +42,13 @@ class Post implements Parcelable {
private boolean isDownloadableGifOrVideo;
private Post crosspostParentPost;
Post(String id, String fullName, String subredditNamePrefixed, String postTime, String title,
String previewUrl, String permalink, int score, int postType, int voteType, int gilded,
boolean nsfw, boolean stickied, boolean isCrosspost, boolean isDashVideo) {
Post(String id, String fullName, String subredditNamePrefixed, String author, String postTime,
String title, String previewUrl, String permalink, int score, int postType, int voteType,
int gilded, boolean nsfw, boolean stickied, boolean isCrosspost, boolean isDashVideo) {
this.id = id;
this.fullName = fullName;
this.subredditNamePrefixed = subredditNamePrefixed;
this.author = author;
this.postTime = postTime;
this.title = title;
this.previewUrl = previewUrl;
@ -60,12 +63,13 @@ class Post implements Parcelable {
this.isDashVideo = isDashVideo;
}
Post(String id, String fullName, String subredditNamePrefixed, String postTime, String title,
String previewUrl, String url, String permalink, int score, int postType, int voteType,
int gilded, boolean nsfw, boolean stickied, boolean isCrosspost) {
Post(String id, String fullName, String subredditNamePrefixed, String author, String postTime,
String title, String previewUrl, String url, String permalink, int score, int postType,
int voteType, int gilded, boolean nsfw, boolean stickied, boolean isCrosspost) {
this.id = id;
this.fullName = fullName;
this.subredditNamePrefixed = subredditNamePrefixed;
this.author = author;
this.postTime = postTime;
this.title = title;
this.previewUrl = previewUrl;
@ -80,12 +84,13 @@ class Post implements Parcelable {
this.isCrosspost = isCrosspost;
}
Post(String id, String fullName, String subredditNamePrefixed, String postTime, String title,
String permalink, int score, int postType, int voteType, int gilded, boolean nsfw,
Post(String id, String fullName, String subredditNamePrefixed, String author, String postTime,
String title, String permalink, int score, int postType, int voteType, int gilded, boolean nsfw,
boolean stickied, boolean isCrosspost) {
this.id = id;
this.fullName = fullName;
this.subredditNamePrefixed = subredditNamePrefixed;
this.author = author;
this.postTime = postTime;
this.title = title;
this.permalink = RedditUtils.API_BASE_URI + permalink;
@ -103,6 +108,8 @@ class Post implements Parcelable {
fullName = in.readString();
subredditNamePrefixed = in.readString();
subredditIconUrl = in.readString();
author = in.readString();
authorIconUrl = in.readString();
postTime = in.readString();
title = in.readString();
selfText = in.readString();
@ -156,6 +163,18 @@ class Post implements Parcelable {
this.subredditIconUrl = subredditIconUrl;
}
public String getAuthor() {
return author;
}
public String getAuthorIconUrl() {
return authorIconUrl;
}
public void setAuthorIconUrl(String authorIconUrl) {
this.authorIconUrl = authorIconUrl;
}
public String getPostTime() {
return postTime;
}
@ -279,6 +298,8 @@ class Post implements Parcelable {
parcel.writeString(fullName);
parcel.writeString(subredditNamePrefixed);
parcel.writeString(subredditIconUrl);
parcel.writeString(author);
parcel.writeString(authorIconUrl);
parcel.writeString(postTime);
parcel.writeString(title);
parcel.writeString(selfText);

View File

@ -38,6 +38,8 @@ import com.bumptech.glide.request.target.Target;
import CustomView.AspectRatioGifImageView;
import SubredditDatabase.SubredditDao;
import SubredditDatabase.SubredditRoomDatabase;
import User.UserDao;
import User.UserRoomDatabase;
import butterknife.BindView;
import butterknife.ButterKnife;
import jp.wasabeef.glide.transformations.BlurTransformation;
@ -54,6 +56,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
private SharedPreferences mSharedPreferences;
private RequestManager glide;
private SubredditDao subredditDao;
private UserDao userDao;
private boolean canStartActivity = true;
private boolean hasMultipleSubreddits;
@ -78,6 +81,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
this.hasMultipleSubreddits = hasMultipleSubreddits;
glide = Glide.with(mContext.getApplicationContext());
subredditDao = SubredditRoomDatabase.getDatabase(mContext.getApplicationContext()).subredditDao();
userDao = UserRoomDatabase.getDatabase(mContext.getApplicationContext()).userDao();
this.retryLoadingMoreCallback = retryLoadingMoreCallback;
}
}
@ -122,6 +126,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
} else {
final String id = post.getFullName();
final String subredditName = post.getSubredditNamePrefixed();
String author = "u/" + post.getAuthor();
final String postTime = post.getPostTime();
final String title = post.getTitle();
final String permalink = post.getPermalink();
@ -129,115 +134,193 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
int gilded = post.getGilded();
boolean nsfw = post.isNSFW();
if(post.getSubredditIconUrl() == null) {
new LoadSubredditIconAsyncTask(subredditDao, subredditName,
iconImageUrl -> {
if(mContext != null && getItemCount() > 0) {
if(!iconImageUrl.equals("")) {
glide.load(iconImageUrl)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 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;
}
((DataViewHolder) holder).cardView.setOnClickListener(view -> {
if(canStartActivity) {
canStartActivity = 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();
((DataViewHolder) holder).subredditIconGifImageView.startAnimation();
Intent intent = new Intent(mContext, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_TITLE, title);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, post);
mContext.startActivity(intent);
}
});
if(hasMultipleSubreddits) {
if(post.getSubredditIconUrl() == null) {
new LoadSubredditIconAsyncTask(subredditDao, subredditName,
iconImageUrl -> {
if(mContext != null && getItemCount() > 0) {
if(!iconImageUrl.equals("")) {
glide.load(iconImageUrl)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 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;
}
return false;
}
})
.into(((DataViewHolder) holder).subredditIconGifImageView);
} else {
glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.into(((DataViewHolder) holder).subredditIconGifImageView);
@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();
((DataViewHolder) holder).subredditIconGifImageView.startAnimation();
}
return false;
}
})
.into(((DataViewHolder) holder).subredditIconGifImageView);
} else {
glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.into(((DataViewHolder) holder).subredditIconGifImageView);
}
if(holder.getAdapterPosition() >= 0) {
post.setSubredditIconUrl(iconImageUrl);
}
}
}).execute();
} else if(!post.getSubredditIconUrl().equals("")) {
glide.load(post.getSubredditIconUrl())
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 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;
}
if(holder.getAdapterPosition() >= 0) {
post.setSubredditIconUrl(iconImageUrl);
@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();
((DataViewHolder) holder).subredditIconGifImageView.startAnimation();
}
return false;
}
}
}).execute();
} else if(!post.getSubredditIconUrl().equals("")) {
glide.load(post.getSubredditIconUrl())
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 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;
}
})
.into(((DataViewHolder) holder).subredditIconGifImageView);
} else {
glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.into(((DataViewHolder) holder).subredditIconGifImageView);
}
@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();
((DataViewHolder) holder).subredditIconGifImageView.startAnimation();
}
return false;
}
})
.into(((DataViewHolder) holder).subredditIconGifImageView);
((DataViewHolder) holder).subredditIconGifImageView.setOnClickListener(view -> {
if(canStartActivity) {
canStartActivity = false;
Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY,
post.getSubredditNamePrefixed().substring(2));
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_VALUE_KEY,
post.getSubredditNamePrefixed());
intent.putExtra(ViewSubredditDetailActivity.EXTRA_QUERY_BY_ID_KEY, false);
mContext.startActivity(intent);
}
});
((DataViewHolder) holder).subredditNameTextView.setText(subredditName);
((DataViewHolder) holder).subredditNameTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(canStartActivity) {
canStartActivity = false;
Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY,
post.getSubredditNamePrefixed().substring(2));
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_VALUE_KEY,
post.getSubredditNamePrefixed());
intent.putExtra(ViewSubredditDetailActivity.EXTRA_QUERY_BY_ID_KEY, false);
mContext.startActivity(intent);
}
}
});
} else {
glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.into(((DataViewHolder) holder).subredditIconGifImageView);
if(post.getAuthorIconUrl() == null) {
new LoadUserDataAsyncTask(userDao, post.getAuthor(), mOauthRetrofit, iconImageUrl -> {
if(mContext != null && getItemCount() > 0) {
if(!iconImageUrl.equals("")) {
glide.load(iconImageUrl)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 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();
((DataViewHolder) holder).subredditIconGifImageView.startAnimation();
}
return false;
}
})
.into(((DataViewHolder) holder).subredditIconGifImageView);
} else {
glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.into(((DataViewHolder) holder).subredditIconGifImageView);
}
if(holder.getAdapterPosition() >= 0) {
post.setAuthorIconUrl(iconImageUrl);
}
}
}).execute();
} else if(!post.getAuthorIconUrl().equals("")) {
glide.load(post.getAuthorIconUrl())
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 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();
((DataViewHolder) holder).subredditIconGifImageView.startAnimation();
}
return false;
}
})
.into(((DataViewHolder) holder).subredditIconGifImageView);
} else {
glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.into(((DataViewHolder) holder).subredditIconGifImageView);
}
((DataViewHolder) holder).subredditIconGifImageView.setOnClickListener(view -> {
if(canStartActivity) {
canStartActivity = false;
Intent intent = new Intent(mContext, ViewUserDetailActivity.class);
mContext.startActivity(intent);
}
});
((DataViewHolder) holder).subredditNameTextView.setText(author);
((DataViewHolder) holder).subredditNameTextView.setOnClickListener(view -> {
if(canStartActivity) {
canStartActivity = false;
Intent intent = new Intent(mContext, ViewUserDetailActivity.class);
mContext.startActivity(intent);
}
});
}
((DataViewHolder) holder).cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(canStartActivity) {
canStartActivity = false;
Intent intent = new Intent(mContext, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_TITLE, title);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, post);
mContext.startActivity(intent);
}
}
});
((DataViewHolder) holder).subredditIconGifImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(canStartActivity) {
canStartActivity = false;
Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY,
post.getSubredditNamePrefixed().substring(2));
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_VALUE_KEY,
post.getSubredditNamePrefixed());
intent.putExtra(ViewSubredditDetailActivity.EXTRA_QUERY_BY_ID_KEY, false);
mContext.startActivity(intent);
}
}
});
((DataViewHolder) holder).subredditNameTextView.setText(subredditName);
((DataViewHolder) holder).subredditNameTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(canStartActivity) {
canStartActivity = false;
Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY,
post.getSubredditNamePrefixed().substring(2));
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_VALUE_KEY,
post.getSubredditNamePrefixed());
intent.putExtra(ViewSubredditDetailActivity.EXTRA_QUERY_BY_ID_KEY, false);
mContext.startActivity(intent);
}
}
});
((DataViewHolder) holder).postTimeTextView.setText(postTime);
((DataViewHolder) holder).titleTextView.setText(title);
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore()));

View File

@ -27,7 +27,7 @@ public interface RedditAPI {
Call<String> getSubscribedThing(@Query("after") String lastItem, @HeaderMap Map<String, String> headers);
@GET("api/v1/me?raw_json=1")
Call<String> getUserInfo(@HeaderMap Map<String, String> headers);
Call<String> getMyInfo(@HeaderMap Map<String, String> headers);
@FormUrlEncoded
@POST("api/vote")
@ -39,6 +39,6 @@ public interface RedditAPI {
@GET("r/{subredditName}.json?raw_json=1&limit=25")
Call<String> getPost(@Path("subredditName") String subredditName, @Query("after") String lastItem);
@GET("user/{username}/about.json/raw_json=1")
@GET("user/{username}/about.json?raw_json=1")
Call<String> getUserData(@Path("username") String username);
}

View File

@ -9,7 +9,7 @@ import java.util.Map;
* Created by alex on 2/23/18.
*/
class RedditUtils {
public class RedditUtils {
static final String OAUTH_URL ="https://www.reddit.com/api/v1/authorize.compact";
static final String OAUTH_API_BASE_URI = "https://oauth.reddit.com";
static final String API_BASE_URI = "https://www.reddit.com";
@ -53,7 +53,7 @@ class RedditUtils {
return params;
}
static Map<String, String> getOAuthHeader(String accessToken) {
public static Map<String, String> getOAuthHeader(String accessToken) {
Map<String, String> params = new HashMap<>();
params.put(RedditUtils.AUTHORIZATION_KEY, RedditUtils.AUTHORIZATION_BASE + accessToken);
params.put(RedditUtils.USER_AGENT_KEY, RedditUtils.USER_AGENT);

View File

@ -4,11 +4,11 @@ package ml.docilealligator.infinityforreddit;
* Created by alex on 2/23/18.
*/
class SharedPreferencesUtils {
public class SharedPreferencesUtils {
static final String AUTH_CODE_FILE_KEY = "Auth_Code_Pref";
static final String USER_INFO_FILE_KEY = "User_Info";
static final String AUTH_CODE_KEY = "code";
static final String ACCESS_TOKEN_KEY = "accessToken";
public static final String ACCESS_TOKEN_KEY = "accessToken";
static final String REFRESH_TOKEN_KEY = "refreshToken";
static final String QUERY_ACCESS_TOKEN_TIME_KEY = "queryAccessTokenTime";
static final String ACCESS_TOKEN_EXPIRE_INTERVAL_KEY = "accessTokenExpireInterval";

View File

@ -273,7 +273,7 @@ public class ViewSubredditDetailActivity extends AppCompatActivity {
private static class InsertSubredditDataAsyncTask extends AsyncTask<Void, Void, Void> {
private final SubredditDao mSubredditDao;
private SubredditDao mSubredditDao;
private SubredditData subredditData;
InsertSubredditDataAsyncTask(SubredditRoomDatabase subredditDb, SubredditData subredditData) {