Loading best posts in specific subreddits is now working.

This commit is contained in:
Alex Ning 2018-12-27 13:28:23 +08:00
parent 45f67457fa
commit 5603df7546
5 changed files with 196 additions and 68 deletions

View File

@ -17,8 +17,9 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
private String accessToken; private String accessToken;
private Locale locale; private Locale locale;
private boolean isBestPost; private boolean isBestPost;
private String subredditName;
//private MutableLiveData networkState; private MutableLiveData networkState;
private MutableLiveData initialLoading; private MutableLiveData initialLoading;
PostDataSource(Retrofit retrofit, String accessToken, Locale locale, boolean isBestPost) { PostDataSource(Retrofit retrofit, String accessToken, Locale locale, boolean isBestPost) {
@ -26,14 +27,23 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
this.accessToken = accessToken; this.accessToken = accessToken;
this.locale = locale; this.locale = locale;
this.isBestPost = isBestPost; this.isBestPost = isBestPost;
//networkState = new MutableLiveData(); networkState = new MutableLiveData();
initialLoading = new MutableLiveData(); initialLoading = new MutableLiveData();
} }
/*public MutableLiveData getNetworkState() { PostDataSource(Retrofit retrofit, Locale locale, boolean isBestPost, String subredditName) {
this.retrofit = retrofit;
this.locale = locale;
this.isBestPost = isBestPost;
this.subredditName = subredditName;
networkState = new MutableLiveData();
initialLoading = new MutableLiveData();
}
public MutableLiveData getNetworkState() {
return networkState; return networkState;
}*/ }
public MutableLiveData getInitialLoading() { public MutableLiveData getInitialLoading() {
return initialLoading; return initialLoading;
@ -42,8 +52,9 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
@Override @Override
public void loadInitial(@NonNull LoadInitialParams<String> params, @NonNull final LoadInitialCallback<String, Post> callback) { public void loadInitial(@NonNull LoadInitialParams<String> params, @NonNull final LoadInitialCallback<String, Post> callback) {
initialLoading.postValue(NetworkState.LOADING); initialLoading.postValue(NetworkState.LOADING);
//networkState.postValue(NetworkState.LOADING); networkState.postValue(NetworkState.LOADING);
if(isBestPost) {
RedditAPI api = retrofit.create(RedditAPI.class); RedditAPI api = retrofit.create(RedditAPI.class);
Call<String> bestPost = api.getBestPost(null, RedditUtils.getOAuthHeader(accessToken)); Call<String> bestPost = api.getBestPost(null, RedditUtils.getOAuthHeader(accessToken));
@ -57,7 +68,7 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
callback.onResult(newPosts, null, lastItem); callback.onResult(newPosts, null, lastItem);
initialLoading.postValue(NetworkState.LOADED); initialLoading.postValue(NetworkState.LOADED);
//networkState.postValue(NetworkState.LOADED); networkState.postValue(NetworkState.LOADED);
} }
@Override @Override
@ -68,16 +79,51 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
} else { } else {
Log.i("Post fetch error", response.message()); Log.i("Post fetch error", response.message());
initialLoading.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); initialLoading.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
//networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
} }
} }
@Override @Override
public void onFailure(Call<String> call, Throwable t) { public void onFailure(Call<String> call, Throwable t) {
String errorMessage = t == null ? "unknown error" : t.getMessage(); String errorMessage = t == null ? "unknown error" : t.getMessage();
//networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
} }
}); });
} else {
RedditAPI api = retrofit.create(RedditAPI.class);
Call<String> getPost = api.getPost(subredditName, null);
getPost.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, retrofit2.Response<String> response) {
if(response.isSuccessful()) {
ParsePost.parsePost(response.body(), locale,
new ParsePost.ParsePostListener() {
@Override
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
callback.onResult(newPosts, null, lastItem);
initialLoading.postValue(NetworkState.LOADED);
networkState.postValue(NetworkState.LOADED);
}
@Override
public void onParsePostFail() {
Log.i("Post fetch error", "Error parsing data");
}
});
} else {
Log.i("Post fetch error", response.message());
initialLoading.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
String errorMessage = t == null ? "unknown error" : t.getMessage();
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
}
});
}
} }
@Override @Override
@ -87,8 +133,9 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
@Override @Override
public void loadAfter(@NonNull LoadParams<String> params, @NonNull final LoadCallback<String, Post> callback) { public void loadAfter(@NonNull LoadParams<String> params, @NonNull final LoadCallback<String, Post> callback) {
//networkState.postValue(NetworkState.LOADING); networkState.postValue(NetworkState.LOADING);
if(isBestPost) {
RedditAPI api = retrofit.create(RedditAPI.class); RedditAPI api = retrofit.create(RedditAPI.class);
Call<String> bestPost = api.getBestPost(params.key, RedditUtils.getOAuthHeader(accessToken)); Call<String> bestPost = api.getBestPost(params.key, RedditUtils.getOAuthHeader(accessToken));
@ -100,7 +147,7 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
@Override @Override
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
callback.onResult(newPosts, lastItem); callback.onResult(newPosts, lastItem);
//networkState.postValue(NetworkState.LOADED); networkState.postValue(NetworkState.LOADED);
} }
@Override @Override
@ -110,15 +157,47 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
}); });
} else { } else {
Log.i("best post", response.message()); Log.i("best post", response.message());
//networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
} }
} }
@Override @Override
public void onFailure(Call<String> call, Throwable t) { public void onFailure(Call<String> call, Throwable t) {
String errorMessage = t == null ? "unknown error" : t.getMessage(); String errorMessage = t == null ? "unknown error" : t.getMessage();
//networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
}
});
} else {
RedditAPI api = retrofit.create(RedditAPI.class);
Call<String> getPost = api.getPost(subredditName, params.key);
getPost.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, retrofit2.Response<String> response) {
if(response.isSuccessful()) {
ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() {
@Override
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
callback.onResult(newPosts, lastItem);
networkState.postValue(NetworkState.LOADED);
}
@Override
public void onParsePostFail() {
Log.i("Best post", "Error parsing data");
}
});
} else {
Log.i("best post", response.message());
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
String errorMessage = t == null ? "unknown error" : t.getMessage();
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
} }
}); });
} }
}
} }

View File

@ -13,6 +13,7 @@ class PostDataSourceFactory extends DataSource.Factory {
private String accessToken; private String accessToken;
private Locale locale; private Locale locale;
private boolean isBestPost; private boolean isBestPost;
private String subredditName;
private MutableLiveData<PageKeyedDataSource<String, Post>> mutableLiveData; private MutableLiveData<PageKeyedDataSource<String, Post>> mutableLiveData;
@ -24,9 +25,22 @@ class PostDataSourceFactory extends DataSource.Factory {
mutableLiveData = new MutableLiveData<>(); mutableLiveData = new MutableLiveData<>();
} }
PostDataSourceFactory(Retrofit retrofit, Locale locale, boolean isBestPost, String subredditName) {
this.retrofit = retrofit;
this.locale = locale;
this.isBestPost = isBestPost;
mutableLiveData = new MutableLiveData<>();
this.subredditName = subredditName;
}
@Override @Override
public DataSource create() { public DataSource create() {
PostDataSource postDataSource = new PostDataSource(retrofit, accessToken, locale, isBestPost); PostDataSource postDataSource;
if(isBestPost) {
postDataSource = new PostDataSource(retrofit, accessToken, locale, isBestPost);
} else {
postDataSource = new PostDataSource(retrofit, locale, isBestPost, subredditName);
}
mutableLiveData.postValue(postDataSource); mutableLiveData.postValue(postDataSource);
return postDataSource; return postDataSource;
} }

View File

@ -124,8 +124,14 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
String accessToken = getActivity().getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE) String accessToken = getActivity().getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE)
.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, ""); .getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
PostViewModel.Factory factory = new PostViewModel.Factory(mOauthRetrofit, accessToken, PostViewModel.Factory factory;
if(mIsBestPost) {
factory = new PostViewModel.Factory(mOauthRetrofit, accessToken,
getResources().getConfiguration().locale, mIsBestPost); getResources().getConfiguration().locale, mIsBestPost);
} else {
factory = new PostViewModel.Factory(mRetrofit,
getResources().getConfiguration().locale, mIsBestPost, mSubredditName);
}
mPostViewModel = ViewModelProviders.of(this, factory).get(PostViewModel.class); mPostViewModel = ViewModelProviders.of(this, factory).get(PostViewModel.class);
mPostViewModel.getPosts().observe(this, posts -> mAdapter.submitList(posts)); mPostViewModel.getPosts().observe(this, posts -> mAdapter.submitList(posts));

View File

@ -36,6 +36,23 @@ public class PostViewModel extends ViewModel {
posts = (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build(); posts = (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build();
} }
public PostViewModel(Retrofit retrofit, Locale locale, boolean isBestPost, String subredditName) {
//executor = Executors.newFixedThreadPool(5);
PostDataSourceFactory postDataSourceFactory = new PostDataSourceFactory(retrofit, locale, isBestPost, subredditName);
/*networkState = Transformations.switchMap(postDataSourceFactory.getMutableLiveData(),
(Function<PostDataSource, LiveData<NetworkState>>) PostDataSource::getNetworkState);*/
liveDataSource = postDataSourceFactory.getMutableLiveData();
PagedList.Config pagedListConfig =
(new PagedList.Config.Builder())
.setEnablePlaceholders(false)
.setPageSize(25)
.build();
posts = (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build();
}
LiveData<PagedList<Post>> getPosts() { LiveData<PagedList<Post>> getPosts() {
return posts; return posts;
} }
@ -49,6 +66,7 @@ public class PostViewModel extends ViewModel {
private String accessToken; private String accessToken;
private Locale locale; private Locale locale;
private boolean isBestPost; private boolean isBestPost;
private String subredditName;
public Factory(Retrofit retrofit, String accessToken, Locale locale, boolean isBestPost) { public Factory(Retrofit retrofit, String accessToken, Locale locale, boolean isBestPost) {
this.retrofit = retrofit; this.retrofit = retrofit;
@ -57,10 +75,21 @@ public class PostViewModel extends ViewModel {
this.isBestPost = isBestPost; this.isBestPost = isBestPost;
} }
public Factory(Retrofit retrofit, Locale locale, boolean isBestPost, String subredditName) {
this.retrofit = retrofit;
this.locale = locale;
this.isBestPost = isBestPost;
this.subredditName = subredditName;
}
@NonNull @NonNull
@Override @Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if(isBestPost) {
return (T) new PostViewModel(retrofit, accessToken, locale, isBestPost); return (T) new PostViewModel(retrofit, accessToken, locale, isBestPost);
} else {
return (T) new PostViewModel(retrofit, locale, isBestPost, subredditName);
}
} }
} }
} }

View File

@ -36,7 +36,7 @@ public interface RedditAPI {
@GET("best?raw_json=1") @GET("best?raw_json=1")
Call<String> getBestPost(@Query("after") String lastItem, @HeaderMap Map<String, String> headers); Call<String> getBestPost(@Query("after") String lastItem, @HeaderMap Map<String, String> headers);
@GET("r/{subredditName}.json?raw_json=1") @GET("r/{subredditName}.json?raw_json=1&limit=25")
Call<String> getPost(@Path("subredditName") String subredditName, @Query("after") String lastItem); 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")