Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ae51ba4

Browse files
author
Sabari
committed
Logout and user profile page implemented.
1 parent de43268 commit ae51ba4

32 files changed

+834
-331
lines changed

‎app/src/main/java/com/nathansdev/stack/AppConstants.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ public final class AppConstants {
77
public static final String AUTH_URL = "https://stackoverflow.com/oauth/dialog";
88
public static final String VOTES = "votes";
99
public static final String ACTIVITY = "activity";
10+
public static final String REPUTATION = "reputation";
1011
public static final String HOT = "hot";
12+
public static final String MY_FEED = "myFeed";
1113
public static final String WEEK = "week";
1214
public static final String MONTH = "month";
1315
public static final String DESC = "desc";

‎app/src/main/java/com/nathansdev/stack/AppPreferences.java‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,12 @@ public String getAccessToken() {
3232
public void setAccessToken(String token) {
3333
prefs.edit().putString(ACCESS_TOKEN, token).apply();
3434
}
35+
36+
public SharedPreferences.Editor editor() {
37+
return prefs.edit();
38+
}
39+
40+
public void removeAccessToken() {
41+
prefs.edit().remove(ACCESS_TOKEN).apply();
42+
}
3543
}

‎app/src/main/java/com/nathansdev/stack/ProfileScrollBehavior.java‎

Lines changed: 0 additions & 104 deletions
This file was deleted.

‎app/src/main/java/com/nathansdev/stack/base/BasePresenter.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class BasePresenter<V extends MvpView> implements MvpPresenter<V> {
1313

1414
@Override
1515
public void onAttach(V mvpView) {
16-
Timber.v("attachPresenter view");
16+
Timber.v("loadFeedWithDelay view");
1717
mMvpView = mvpView;
1818
}
1919

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.nathansdev.stack.common;
2+
3+
4+
import com.nathansdev.stack.base.MvpPresenter;
5+
import com.nathansdev.stack.base.MvpView;
6+
7+
public interface CommonPresenter<V extends MvpView> extends MvpPresenter<V> {
8+
void loadUser();
9+
10+
void invalidateAccessToken(String token);
11+
12+
void init();
13+
14+
void cleanUp();
15+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package com.nathansdev.stack.common;
2+
3+
4+
import com.nathansdev.stack.AppConstants;
5+
import com.nathansdev.stack.base.BasePresenter;
6+
import com.nathansdev.stack.data.api.StackExchangeApi;
7+
import com.nathansdev.stack.data.model.CommonResponseWrapper;
8+
import com.nathansdev.stack.data.model.UsersResponse;
9+
10+
import javax.inject.Inject;
11+
12+
import io.reactivex.Observable;
13+
import io.reactivex.android.schedulers.AndroidSchedulers;
14+
import io.reactivex.disposables.CompositeDisposable;
15+
import io.reactivex.disposables.Disposable;
16+
import io.reactivex.functions.Consumer;
17+
import io.reactivex.functions.Function;
18+
import io.reactivex.schedulers.Schedulers;
19+
import timber.log.Timber;
20+
21+
public class CommonPresenterImpl<V extends CommonView> extends BasePresenter<V> implements CommonPresenter<V> {
22+
23+
private StackExchangeApi api;
24+
private CompositeDisposable disposables = new CompositeDisposable();
25+
26+
@Inject
27+
CommonPresenterImpl(StackExchangeApi api) {
28+
this.api = api;
29+
}
30+
31+
@Override
32+
public void loadUser() {
33+
Disposable disposable = getObservable()
34+
.observeOn(AndroidSchedulers.mainThread())
35+
.onErrorReturn(new Function<Throwable, UsersResponse>() {
36+
@Override
37+
public UsersResponse apply(Throwable throwable) throws Exception {
38+
Timber.e(throwable);
39+
return null;
40+
}
41+
})
42+
.subscribe(new Consumer<UsersResponse>() {
43+
@Override
44+
public void accept(UsersResponse response) throws Exception {
45+
handleUserProfileReceived(response);
46+
}
47+
});
48+
disposables.add(disposable);
49+
}
50+
51+
@Override
52+
public void invalidateAccessToken(String token) {
53+
Disposable disposable = getObservable(token)
54+
.observeOn(AndroidSchedulers.mainThread())
55+
.onErrorReturn(new Function<Throwable, CommonResponseWrapper>() {
56+
@Override
57+
public CommonResponseWrapper apply(Throwable throwable) throws Exception {
58+
Timber.e(throwable);
59+
getMvpView().onLoggedOut();
60+
return null;
61+
}
62+
})
63+
.subscribe(new Consumer<CommonResponseWrapper>() {
64+
@Override
65+
public void accept(CommonResponseWrapper response) throws Exception {
66+
Timber.d("logout response %s", response);
67+
getMvpView().onLoggedOut();
68+
}
69+
});
70+
disposables.add(disposable);
71+
}
72+
73+
private void handleUserProfileReceived(UsersResponse response) {
74+
Timber.d("handleUserProfileReceived %s", response);
75+
if (!response.users().isEmpty()) {
76+
getMvpView().showUser(response.users().get(0));
77+
}
78+
}
79+
80+
@Override
81+
public void init() {
82+
83+
}
84+
85+
@Override
86+
public void cleanUp() {
87+
disposables.clear();
88+
}
89+
90+
private Observable<UsersResponse> getObservable() {
91+
return api.getUserRx(AppConstants.REPUTATION, AppConstants.SITE, AppConstants.DESC)
92+
.subscribeOn(Schedulers.io());
93+
}
94+
95+
private Observable<CommonResponseWrapper> getObservable(String accessToken) {
96+
return api.invalidateRx(accessToken)
97+
.subscribeOn(Schedulers.io());
98+
}
99+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.nathansdev.stack.common;
2+
3+
4+
import com.nathansdev.stack.base.MvpView;
5+
import com.nathansdev.stack.data.model.Owner;
6+
7+
public interface CommonView extends MvpView {
8+
void showUser(Owner owner);
9+
10+
void onLoggedOut();
11+
}

‎app/src/main/java/com/nathansdev/stack/data/api/StackExchangeApi.java‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
package com.nathansdev.stack.data.api;
22

33

4+
import com.nathansdev.stack.data.model.CommonResponseWrapper;
45
import com.nathansdev.stack.data.model.QuestionsResponse;
6+
import com.nathansdev.stack.data.model.UsersResponse;
57

68
import io.reactivex.Flowable;
79
import io.reactivex.Observable;
810
import retrofit2.Call;
911
import retrofit2.http.GET;
12+
import retrofit2.http.Path;
1013
import retrofit2.http.Query;
1114

1215
public interface StackExchangeApi {
1316
String API_V1_QUESTIONS_JSON = "/2.2/questions?";
17+
String API_V1_USERS_QUESTIONS_JSON = "/2.2/users/{ids}/questions?";
18+
String API_V1_USER_ME_JSON = "/2.2/me?";
19+
String API_V1_ACCESS_TOKEN_INVALIDATE_JSON = "/2.2/access-tokens/{accessTokens}/invalidate";
1420
String SORT = "sort";
1521
String SITE = "site";
1622
String ORDER = "order";
1723
String PAGE = "page";
1824
String PAGE_SIZE = "pagesize";
25+
String IDS = "ids";
26+
String ACCESS_TOKENS = "accessTokens";
1927

2028
@GET(API_V1_QUESTIONS_JSON)
2129
Observable<QuestionsResponse> getQuestionsRx(@Query(SORT) String sort, @Query(SITE) String site,
@@ -31,4 +39,34 @@ Flowable<QuestionsResponse> getQuestionsFlowable(@Query(SORT) String sort, @Quer
3139
Call<QuestionsResponse> getQuestions(@Query(SORT) String sort, @Query(SITE) String site,
3240
@Query(ORDER) String order, @Query(PAGE) String page,
3341
@Query(PAGE_SIZE) String size);
42+
43+
@GET(API_V1_USERS_QUESTIONS_JSON)
44+
Call<QuestionsResponse> getUsersQuestions(@Path(IDS) String ids, @Query(SORT) String sort, @Query(SITE) String site,
45+
@Query(ORDER) String order, @Query(PAGE) String page,
46+
@Query(PAGE_SIZE) String size);
47+
48+
@GET(API_V1_USERS_QUESTIONS_JSON)
49+
Observable<QuestionsResponse> getUsersQuestionsRx(@Path(IDS) String ids, @Query(SORT) String sort, @Query(SITE) String site,
50+
@Query(ORDER) String order, @Query(PAGE) String page,
51+
@Query(PAGE_SIZE) String size);
52+
53+
@GET(API_V1_USERS_QUESTIONS_JSON)
54+
Flowable<QuestionsResponse> getUsersQuestionsFlowable(@Path(IDS) String ids, @Query(SORT) String sort, @Query(SITE) String site,
55+
@Query(ORDER) String order, @Query(PAGE) long page,
56+
@Query(PAGE_SIZE) long size);
57+
58+
@GET(API_V1_USER_ME_JSON)
59+
Call<UsersResponse> getUser(@Query(SORT) String sort, @Query(SITE) String site,
60+
@Query(ORDER) String order);
61+
62+
@GET(API_V1_USER_ME_JSON)
63+
Observable<UsersResponse> getUserRx(@Query(SORT) String sort, @Query(SITE) String site,
64+
@Query(ORDER) String order);
65+
66+
@GET(API_V1_USER_ME_JSON)
67+
Flowable<UsersResponse> getUserFlowable(@Query(SORT) String sort, @Query(SITE) String site,
68+
@Query(ORDER) String order);
69+
70+
@GET(API_V1_ACCESS_TOKEN_INVALIDATE_JSON)
71+
Observable<CommonResponseWrapper> invalidateRx(@Path(ACCESS_TOKENS) String sort);
3472
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.nathansdev.stack.data.model;
2+
3+
import android.os.Parcelable;
4+
import android.support.annotation.Nullable;
5+
6+
import com.google.auto.value.AutoValue;
7+
import com.squareup.moshi.Json;
8+
import com.squareup.moshi.JsonAdapter;
9+
import com.squareup.moshi.Moshi;
10+
11+
import java.util.List;
12+
13+
@AutoValue
14+
public abstract class CommonResponseWrapper implements Parcelable {
15+
16+
@Nullable
17+
@Json(name = "items")
18+
public abstract List<Object> users();
19+
20+
@Nullable
21+
@Json(name = "has_more")
22+
public abstract Boolean hasMore();
23+
24+
@Nullable
25+
@Json(name = "quota_max")
26+
public abstract Long max();
27+
28+
@Nullable
29+
@Json(name = "quota_remaining")
30+
public abstract Long remaining();
31+
32+
public static JsonAdapter<CommonResponseWrapper> commonResponseWrapperJsonAdapter(Moshi moshi) {
33+
return new AutoValue_CommonResponseWrapper.MoshiJsonAdapter(moshi);
34+
}
35+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /