Created
April 5, 2016 13:00
-
-
Save lliepmah/595dfed21b0676e0274a9c721ff86eca to your computer and use it in GitHub Desktop.
Code Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.entirec.kindneignbour.data.network; | |
import android.support.annotation.NonNull; | |
import android.text.TextUtils; | |
import com.google.gson.Gson; | |
import com.google.gson.GsonBuilder; | |
import java.io.File; | |
import java.util.concurrent.TimeUnit; | |
import javax.inject.Singleton; | |
import okhttp3.Interceptor; | |
import okhttp3.MediaType; | |
import okhttp3.OkHttpClient; | |
import okhttp3.Request; | |
import okhttp3.RequestBody; | |
import okhttp3.logging.HttpLoggingInterceptor; | |
import retrofit2.Converter; | |
import retrofit2.GsonConverterFactory; | |
import retrofit2.Retrofit; | |
import retrofit2.RxJavaCallAdapterFactory; | |
import ru.entirec.kindneighbour.domain.entities.User; | |
import ru.entirec.kindneighbour.domain.entities.Vehicle; | |
import ru.entirec.kindneighbour.domain.entities.request.TripRequest; | |
import ru.entirec.kindneignbour.data.response.AuthResponse; | |
import ru.entirec.kindneignbour.data.response.Response; | |
import ru.entirec.kindneignbour.data.response.TripResponse; | |
import ru.entirec.kindneignbour.data.response.TripsResponse; | |
import ru.entirec.kindneignbour.data.response.UserResponse; | |
import ru.entirec.kindneignbour.data.response.VehicleResponse; | |
import ru.entirec.kindneignbour.data.utils.DateProcessor; | |
import ru.entirec.kindneignbour.data.utils.DateUtils; | |
import ru.entirec.kindneignbour.data.utils.FileUtils; | |
import rx.Observable; | |
/** | |
* Created by Arthur Korchagin on 22.01.16 | |
*/ | |
@Singleton | |
public class ApiServiceImpl implements ApiService { | |
public static final String BEARER = "Bearer "; | |
private static final String WEB_SERVICE_BASE_URL = "http://mysite.com/"; | |
private static final int OS_TYPE_ANDROID = 0; | |
private final RequestService mRequestService; | |
public ApiServiceImpl() { | |
OkHttpClient httpClient = createHttpClient(); | |
Retrofit retrofitBuilder = new Retrofit.Builder() | |
.baseUrl(WEB_SERVICE_BASE_URL) | |
.addConverterFactory(createConverterFactory()) | |
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) | |
.addConverterFactory(GsonConverterFactory.create()) | |
.client(httpClient) | |
.build(); | |
mRequestService = retrofitBuilder.create(RequestService.class); | |
} | |
@NonNull | |
private Converter.Factory createConverterFactory() { | |
return GsonConverterFactory.create(createGson()); | |
} | |
@NonNull | |
private Gson createGson() { | |
return new GsonBuilder() | |
.setDateFormat(DateUtils.PATTERN_SERVER_DATETIME) | |
.create(); | |
} | |
private OkHttpClient createHttpClient() { | |
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); | |
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); | |
return new OkHttpClient.Builder() | |
.addInterceptor(createHeadersInterceptor()) | |
.addInterceptor(interceptor) | |
.connectTimeout(1, TimeUnit.MINUTES) | |
.readTimeout(1, TimeUnit.MINUTES) | |
.build(); | |
} | |
private Interceptor createHeadersInterceptor() { | |
return (chain) -> { | |
Request.Builder requestBuilder = chain.request().newBuilder(); | |
return chain.proceed(requestBuilder.build()); | |
}; | |
} | |
@Override | |
public Observable<TripsResponse> fetchTrips(String token, int count, int offset, String role) { | |
return mRequestService.fetchTrips(processToken(token), count, offset, role); | |
} | |
@Override | |
public Observable<TripResponse> fetchTrip(String token, int tripId) { | |
return mRequestService.fetchTrip(processToken(token), tripId); | |
} | |
@Override | |
public Observable<TripResponse> createTrip(String token, TripRequest tripRequest) { | |
return mRequestService.createTrip(processToken(token), tripRequest); | |
} | |
@Override | |
public Observable<TripResponse> editTrip(String token, int tripId, TripRequest tripRequest) { | |
return mRequestService.editTrip(processToken(token), tripId, tripRequest); | |
} | |
@Override | |
public Observable<Response> removeTrip(String token, int tripId) { | |
return mRequestService.removeTrip(processToken(token), tripId); | |
} | |
@Override | |
public Observable<TripsResponse> searchTrips(String token, TripRequest tripRequest) { | |
return mRequestService.searchTrips(processToken(token), tripRequest); | |
} | |
@Override | |
public Observable<AuthResponse> authorize(String phone, String code) { | |
return mRequestService.auth(phone, code) | |
.doOnNext(authResponse -> DateProcessor.process(authResponse.getUser())); | |
} | |
@Override | |
public Observable<AuthResponse> register(String phone, String name, String date) { | |
return mRequestService.register(phone, name, date) | |
.doOnNext(authResponse -> DateProcessor.process(authResponse.getUser())); | |
} | |
@Override | |
public Observable<AuthResponse> register(String phone) { | |
return mRequestService.register(phone) | |
.doOnNext(authResponse -> DateProcessor.process(authResponse.getUser())); | |
} | |
@Override | |
public Observable<UserResponse> fetchUser(String token) { | |
return mRequestService.fetchUser(processToken(token)) | |
.doOnNext(authResponse -> DateProcessor.process(authResponse.getUser())); | |
} | |
@Override | |
public Observable<UserResponse> saveProfile(String token, User user) { | |
return mRequestService.saveUser(processToken(token), user) | |
.doOnNext(authResponse -> DateProcessor.process(authResponse.getUser())); | |
} | |
@Override | |
public Observable<VehicleResponse> putVehicle(String token, Vehicle vehicle) { | |
int id = vehicle.getId(); | |
if (id > 0) { | |
return mRequestService.saveVehicle(processToken(token), id, vehicle); | |
} else { | |
return mRequestService.createVehicle(processToken(token), vehicle); | |
} | |
} | |
@Override | |
public Observable<Response> deleteVehicle(String token, Vehicle vehicle) { | |
return mRequestService.deleteVehicle(processToken(token), vehicle.getId()); | |
} | |
@Override | |
public Observable<Response> joinAsPassenger(String token, int tripId, int reserved) { | |
return mRequestService.joinAsPassenger(processToken(token), tripId, reserved); | |
} | |
@Override | |
public Observable<Response> joinAsDriver(String token, int tripId, int vehicleId) { | |
return mRequestService.joinAsDriver(processToken(token), tripId); // TODO: 11.02.16 Add vehicle id | |
} | |
@Override | |
public Observable<Response> uploadAvatar(String token, File avatarFile) { | |
RequestBody file = RequestBody.create(MediaType.parse(FileUtils.getMimeTypeOfFile(avatarFile)), avatarFile); | |
return mRequestService.uploadAvatar(processToken(token), file); | |
} | |
@Override | |
public Observable<Response> uploadVehiclePhoto(String token, int vehicleId, File photo) { | |
RequestBody file = RequestBody.create(MediaType.parse(FileUtils.getMimeTypeOfFile(photo)), photo); | |
return mRequestService.uploadVehiclePhoto(processToken(token), vehicleId, file); | |
} | |
@Override | |
public Observable<Response> leave(String token, int tripId) { | |
return mRequestService.leave(processToken(token), tripId); | |
} | |
@Override | |
public Observable<Response> approveOrDeclineDriver(String token, int tripId, int userId, boolean approve) { | |
return mRequestService.approveOrDeclineDriver(processToken(token), tripId, userId, approve ? 1 : 0); | |
} | |
@Override | |
public Observable<Response> approveOrDeclinePassenger(String token, int tripId, int userId, boolean approve) { | |
return mRequestService.approveOrDeclinePassenger(processToken(token), tripId, userId, approve ? 1 : 0); | |
} | |
@Override | |
public Observable<Response> sendGcmToken(String token, String gcmToken) { | |
return mRequestService.sendGcmToken(processToken(token), gcmToken, OS_TYPE_ANDROID); | |
} | |
@NonNull | |
private String processToken(String token) { | |
return TextUtils.concat(BEARER, token).toString(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.entirec.kindneighbour.domain.interactor; | |
import javax.inject.Inject; | |
import ru.entirec.kindneighbour.domain.entities.User; | |
import ru.entirec.kindneighbour.domain.executor.PostExecutionThread; | |
import ru.entirec.kindneighbour.domain.executor.ThreadExecutor; | |
import ru.entirec.kindneighbour.domain.repository.ProfileRepository; | |
import ru.entirec.kindneighbour.domain.requests.UseCaseRequest; | |
import ru.entirec.kindneighbour.domain.responces.UseCaseResponse; | |
import rx.Observable; | |
/** | |
* Created by Arthur Korchagin on 27.01.16 | |
*/ | |
public class GetProfileCase extends UseCase<UseCaseRequest, UseCaseResponse<User>> { | |
public static final String CASE_NAME = "get_profile_case"; | |
private final ProfileRepository mProfileRepository; | |
@Inject | |
public GetProfileCase(ProfileRepository profileRepository, ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) { | |
super(threadExecutor, postExecutionThread); | |
mProfileRepository = profileRepository; | |
} | |
@Override | |
protected Observable<UseCaseResponse<User>> buildUseCaseObservable(UseCaseRequest r) { | |
return mProfileRepository.fetchProfile(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.entirec.kindneignbour.kindneighbour.view.fragments; | |
import android.os.Bundle; | |
import android.support.v7.widget.LinearLayoutManager; | |
import android.support.v7.widget.RecyclerView; | |
import android.view.LayoutInflater; | |
import android.view.Menu; | |
import android.view.MenuInflater; | |
import android.view.MenuItem; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.LinearLayout; | |
import com.annimon.stream.Collectors; | |
import com.annimon.stream.Stream; | |
import java.util.ArrayList; | |
import java.util.List; | |
import javax.inject.Inject; | |
import butterknife.Bind; | |
import butterknife.ButterKnife; | |
import ru.entirec.kindneighbour.domain.entities.User; | |
import ru.entirec.kindneighbour.domain.entities.Vehicle; | |
import ru.entirec.kindneignbour.kindneighbour.R; | |
import ru.entirec.kindneignbour.kindneighbour.image.ImageLoader; | |
import ru.entirec.kindneignbour.kindneighbour.internal.di.components.DaggerProfilesComponent; | |
import ru.entirec.kindneignbour.kindneighbour.internal.di.modules.UIModule; | |
import ru.entirec.kindneignbour.kindneighbour.presenter.Presenter; | |
import ru.entirec.kindneignbour.kindneighbour.presenter.ProfilePresenter; | |
import ru.entirec.kindneignbour.kindneighbour.view.ProfileView; | |
import ru.entirec.kindneignbour.kindneighbour.view.adapters.UniversalAdapter; | |
import ru.entirec.kindneignbour.kindneighbour.view.adapters.holders.ButtonAddViewHolder; | |
import ru.entirec.kindneignbour.kindneighbour.view.adapters.holders.OnPhotoClickListener; | |
import ru.entirec.kindneignbour.kindneighbour.view.adapters.holders.ProfileInfoViewHolder; | |
import ru.entirec.kindneignbour.kindneighbour.view.adapters.holders.VehicleViewHolder; | |
import ru.entirec.kindneignbour.kindneighbour.view.adapters.viewmodels.ViewModelWrapper; | |
/** | |
* Created by Arthur Korchagin on 03.02.16 | |
*/ | |
public class ProfileFragment extends BaseFragment implements ProfileView, ButtonAddViewHolder.OnAddClickListener, VehicleViewHolder.OnVehicleChooseListener, OnPhotoClickListener { | |
@Bind(R.id.rv_profile_list) | |
RecyclerView mRvProfileList; | |
@Bind(R.id.l_progress) | |
LinearLayout mLProfileProgress; | |
@Inject | |
ProfilePresenter mProfilePresenter; | |
@Inject | |
ImageLoader mImageLoader; | |
@Inject | |
ProfileInfoViewHolder.Builder mProfileHolderBuilder; | |
@Inject | |
VehicleViewHolder.Builder mVehicleHolderBuilder; | |
@Inject | |
ButtonAddViewHolder.Builder mButtonAddBuilder; | |
private int mVehicleCount = 0; | |
public static ProfileFragment newInstance() { | |
return new ProfileFragment(); | |
} | |
@Override | |
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | |
View fragmentView = inflater.inflate(R.layout.fmt_profile, container, false); | |
ButterKnife.bind(this, fragmentView); | |
return fragmentView; | |
} | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setHasOptionsMenu(true); | |
} | |
@Override | |
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { | |
inflater.inflate(R.menu.edit, menu); | |
} | |
@Override | |
public boolean onOptionsItemSelected(MenuItem item) { | |
switch (item.getItemId()) { | |
case R.id.menu_edit: | |
getNavigator().openEditProfileFragment(mProfilePresenter.getUser()); | |
return true; | |
default: | |
return super.onOptionsItemSelected(item); | |
} | |
} | |
@Override | |
public void onViewCreated(View view, Bundle savedInstanceState) { | |
super.onViewCreated(view, savedInstanceState); | |
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity()); | |
mRvProfileList.setLayoutManager(layoutManager); | |
} | |
@Override | |
public void onActivityCreated(Bundle savedInstanceState) { | |
super.onActivityCreated(savedInstanceState); | |
this.initialize(); | |
mVehicleHolderBuilder.setOnVehicleChooseListener(this); | |
mButtonAddBuilder.setOnAddClickListener(this); | |
} | |
@Override | |
protected void initialize() { | |
if (mProfilePresenter == null) { | |
DaggerProfilesComponent.builder() | |
.activityComponent(getActivityComponent()) | |
.uIModule(new UIModule() | |
.photoListener(this)) | |
.build() | |
.inject(this); | |
} | |
mProfilePresenter.setView(this); | |
} | |
@Override | |
public void renderProfile(User user) { | |
List<Vehicle> vehicles = user.getVehicles(); | |
mVehicleCount = vehicles.size(); | |
List<ViewModelWrapper> list = new ArrayList<ViewModelWrapper>() { | |
{ | |
add(ViewModelWrapper.build(user, mProfileHolderBuilder)); | |
addAll(Stream.of(vehicles) | |
.map(value -> ViewModelWrapper.build(value, mVehicleHolderBuilder)) | |
.collect(Collectors.toList())); | |
add(ViewModelWrapper.build(getString(R.string.label_add_vehicle), mButtonAddBuilder)); | |
} | |
}; | |
mRvProfileList.setAdapter(new UniversalAdapter(list)); | |
} | |
@Override | |
public void showLoading() { | |
mLProfileProgress.setVisibility(View.VISIBLE); | |
mRvProfileList.setVisibility(View.GONE); | |
} | |
@Override | |
public void hideLoading() { | |
mLProfileProgress.setVisibility(View.GONE); | |
mRvProfileList.setVisibility(View.VISIBLE); | |
} | |
@Override | |
public void showError(String message) { | |
showToastMessage(message); | |
} | |
@Override | |
protected Presenter getPresenter() { | |
return mProfilePresenter; | |
} | |
@Override | |
public void onDestroyView() { | |
super.onDestroyView(); | |
ButterKnife.unbind(this); | |
} | |
@Override | |
public void onAddClick() { | |
getNavigator().openVehicleFragment(new Vehicle(-1, mVehicleCount <= 0)); | |
} | |
@Override | |
public void onChoose(Vehicle vehicle) { | |
getNavigator().openVehicleFragment(vehicle); | |
} | |
@Override | |
protected int getTitleRes() { | |
return R.string.ttl_profile; | |
} | |
@Override | |
protected int getSubtitleRes() { | |
return R.string.label_empty; | |
} | |
@Override | |
public void onPhotoClick(String url, String title) { | |
getNavigator().openPhoto(url, title); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.entirec.kindneignbour.kindneighbour.internal.di.modules; | |
import android.app.Activity; | |
import android.graphics.Bitmap; | |
import javax.inject.Named; | |
import dagger.Module; | |
import dagger.Provides; | |
import ru.entirec.kindneighbour.domain.entities.User; | |
import ru.entirec.kindneighbour.domain.executor.PostExecutionThread; | |
import ru.entirec.kindneighbour.domain.executor.ThreadExecutor; | |
import ru.entirec.kindneighbour.domain.interactor.DeleteVehicleCase; | |
import ru.entirec.kindneighbour.domain.interactor.GetProfileCase; | |
import ru.entirec.kindneighbour.domain.interactor.ProfileUpdateCase; | |
import ru.entirec.kindneighbour.domain.interactor.PutVehicleCase; | |
import ru.entirec.kindneighbour.domain.interactor.SaveProfileCase; | |
import ru.entirec.kindneighbour.domain.interactor.UseCase; | |
import ru.entirec.kindneighbour.domain.repository.ProfileRepository; | |
import ru.entirec.kindneighbour.domain.requests.SaveProfileRequest; | |
import ru.entirec.kindneighbour.domain.requests.UseCaseRequest; | |
import ru.entirec.kindneighbour.domain.requests.VehicleRequest; | |
import ru.entirec.kindneighbour.domain.responces.UseCaseResponse; | |
import ru.entirec.kindneignbour.kindneighbour.image.ImageFile; | |
import ru.entirec.kindneignbour.kindneighbour.internal.di.PerFragment; | |
import ru.entirec.kindneignbour.kindneighbour.uiinteractor.PhotoUseCase; | |
import ru.entirec.kindneignbour.kindneighbour.uiinteractor.request.MediaRequest; | |
/** | |
* Created by Arthur Korchagin on 22.01.16 | |
* <p> | |
* Dagger module that provides trips. | |
*/ | |
@Module | |
public class ProfileModule { | |
@Provides | |
@PerFragment | |
@Named(PhotoUseCase.CASE_NAME) | |
UseCase<MediaRequest, UseCaseResponse<ImageFile>> providePhotoUseCase(Activity activity, ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) { | |
return new PhotoUseCase(threadExecutor, postExecutionThread, activity); | |
} | |
@Provides | |
@PerFragment | |
@Named(GetProfileCase.CASE_NAME) | |
UseCase<UseCaseRequest, UseCaseResponse<User>> provideGetProfileCase(ProfileRepository profileRepository, ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) { | |
return new GetProfileCase(profileRepository, threadExecutor, postExecutionThread); | |
} | |
@Provides | |
@PerFragment | |
@Named(ProfileUpdateCase.CASE_NAME) | |
UseCase<UseCaseRequest, UseCaseResponse<User>> provideGetProfileUpdatesCase(ProfileRepository profileRepository, ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) { | |
return new ProfileUpdateCase(profileRepository, threadExecutor, postExecutionThread); | |
} | |
@Provides | |
@PerFragment | |
@Named(SaveProfileCase.CASE_NAME) | |
UseCase<SaveProfileRequest, UseCaseResponse<Object>> provideSaveProfileCase(ProfileRepository profileRepository, ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) { | |
return new SaveProfileCase(profileRepository, threadExecutor, postExecutionThread); | |
} | |
@Provides | |
@PerFragment | |
@Named(PutVehicleCase.CASE_NAME) | |
UseCase<VehicleRequest, UseCaseResponse<Object>> providePutVehicleCase(ProfileRepository profileRepository, ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) { | |
return new PutVehicleCase(profileRepository, threadExecutor, postExecutionThread); | |
} | |
@Provides | |
@PerFragment | |
@Named(DeleteVehicleCase.CASE_NAME) | |
UseCase<VehicleRequest, UseCaseResponse<Object>> provideDeleteVehicleCase(ProfileRepository profileRepository, ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) { | |
return new DeleteVehicleCase(profileRepository, threadExecutor, postExecutionThread); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.entirec.kindneignbour.kindneighbour.presenter; | |
import java.io.Serializable; | |
import javax.inject.Inject; | |
import javax.inject.Named; | |
import ru.entirec.kindneighbour.domain.entities.User; | |
import ru.entirec.kindneighbour.domain.interactor.DefaultSubscriber; | |
import ru.entirec.kindneighbour.domain.interactor.GetProfileCase; | |
import ru.entirec.kindneighbour.domain.interactor.UseCase; | |
import ru.entirec.kindneighbour.domain.requests.UseCaseRequest; | |
import ru.entirec.kindneighbour.domain.responces.UseCaseResponse; | |
import ru.entirec.kindneignbour.kindneighbour.internal.di.PerFragment; | |
import ru.entirec.kindneignbour.kindneighbour.rx.DefaultViewSubscriber; | |
import ru.entirec.kindneignbour.kindneighbour.view.ProfileView; | |
/** | |
* Created by Arthur Korchagin on 03.02.16 | |
*/ | |
@PerFragment | |
public class ProfilePresenter implements Presenter { | |
/* Use Cases */ | |
private final UseCase<UseCaseRequest, UseCaseResponse<User>> mGetProfileUseCase; | |
/* Main View */ | |
private ProfileView mProfileView; | |
/* Subscribers */ | |
private DefaultSubscriber<UseCaseResponse<User>> mUseCaseSubscriber; | |
private User mUser; | |
@Inject | |
public ProfilePresenter(@Named(GetProfileCase.CASE_NAME) | |
UseCase<UseCaseRequest, UseCaseResponse<User>> getProfileUseCase) { | |
mGetProfileUseCase = getProfileUseCase; | |
} | |
@Override | |
public void start() { | |
mProfileView.showLoading(); | |
mGetProfileUseCase.execute(null, getUseCaseSubscriber()); | |
} | |
@Override | |
public void stop() { | |
mGetProfileUseCase.unsubscribe(); | |
} | |
public void setView(ProfileView view) { | |
this.mProfileView = view; | |
} | |
public Serializable getUser() { | |
return mUser; | |
} | |
private void onProfileLoaded(UseCaseResponse<User> userUseCaseResponse) { | |
mProfileView.hideLoading(); | |
if (userUseCaseResponse.isStatusOk()) { | |
mUser = userUseCaseResponse.getEntity(); | |
mProfileView.renderProfile(mUser); | |
} else { | |
mProfileView.showError(userUseCaseResponse.getPrintMessage()); | |
} | |
} | |
public DefaultSubscriber<UseCaseResponse<User>> getUseCaseSubscriber() { | |
if (mUseCaseSubscriber == null) { | |
mUseCaseSubscriber = new DefaultViewSubscriber<>(mProfileView, this::onProfileLoaded); | |
} | |
return mUseCaseSubscriber; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.entirec.kindneignbour.data.repository; | |
import java.io.File; | |
import javax.inject.Inject; | |
import javax.inject.Singleton; | |
import ru.entirec.kindneighbour.domain.entities.User; | |
import ru.entirec.kindneighbour.domain.entities.Vehicle; | |
import ru.entirec.kindneighbour.domain.entities.utils.UserMode; | |
import ru.entirec.kindneighbour.domain.repository.ProfileRepository; | |
import ru.entirec.kindneighbour.domain.responces.UseCaseResponse; | |
import ru.entirec.kindneignbour.data.cache.PrivateStorage; | |
import ru.entirec.kindneignbour.data.cache.UserStorage; | |
import ru.entirec.kindneignbour.data.repository.datasource.DataSourceFactory; | |
import ru.entirec.kindneignbour.data.response.Response; | |
import ru.entirec.kindneignbour.data.response.UserResponse; | |
import ru.entirec.kindneignbour.data.response.VehicleResponse; | |
import ru.entirec.kindneignbour.data.utils.RxUtils; | |
import ru.entirec.kindneignbour.data.utils.TestUtils; | |
import rx.Observable; | |
import rx.subjects.PublishSubject; | |
/** | |
* Created by Arthur Korchagin on 28.01.16 | |
*/ | |
@Singleton | |
public class ProfileRepositoryImpl implements ProfileRepository { | |
private final DataSourceFactory mTripDataSourceFactory; | |
private final PrivateStorage mPrivateStorage; | |
private final UserStorage mUserStorage; | |
public final PublishSubject<UseCaseResponse<User>> mUpdatesSubject = PublishSubject.create(); | |
private User mCurrentUser; | |
@Inject | |
public ProfileRepositoryImpl(DataSourceFactory tripDataSourceFactory, PrivateStorage privateStorage, UserStorage userStorage) { | |
mTripDataSourceFactory = tripDataSourceFactory; | |
mPrivateStorage = privateStorage; | |
mUserStorage = userStorage; | |
} | |
@Override | |
public Observable<UseCaseResponse<User>> fetchProfileUpdates() { | |
return mUpdatesSubject; | |
} | |
/** | |
* As first fetch user from storage and emit it, | |
* next receive user from network, | |
* if entity changed emit user again | |
**/ | |
@Override | |
public Observable<UseCaseResponse<User>> fetchProfile() { | |
return Observable.merge(mUserStorage.fetchUserObservable() | |
.doOnNext(this::setUser) | |
.map(UseCaseResponse::buildSuccessResponse), | |
mTripDataSourceFactory.getApiService().fetchUser(getToken()) | |
.map(UserResponse::transform) | |
.filter(resp -> mCurrentUser == null || !mCurrentUser.equals(resp.getEntity())) | |
.doOnNext(resp -> putUser(resp.getEntity())) | |
.doOnNext(mUpdatesSubject::onNext) | |
.compose(RxUtils.processErrors())); | |
} | |
/** | |
* As first fetch user from network, save in local storage and emit it, | |
* if cannot receive user from network, fetch from local storage | |
**/ | |
@Override | |
public Observable<UseCaseResponse<User>> fetchFreshProfile() { | |
return | |
mTripDataSourceFactory.getApiService().fetchUser(getToken()) | |
.map(UserResponse::transform) | |
.doOnNext(resp -> putUser(resp.getEntity())) | |
.doOnNext(mUpdatesSubject::onNext) | |
.onErrorResumeNext(mUserStorage.fetchUserObservable() | |
.map(UseCaseResponse::buildSuccessResponse)) | |
.doOnNext(userUseCaseResponse -> TestUtils.addVehicleImages(userUseCaseResponse.getEntity())); // TODO: 09.02.16 Only for test) | |
} | |
@Override | |
public Observable<UseCaseResponse<User>> saveProfile(User user) { | |
return mTripDataSourceFactory.getApiService().saveProfile(getToken(), user) | |
.map(UserResponse::transform) | |
.compose(RxUtils.processErrors()); | |
} | |
@Override | |
public Observable<UseCaseResponse<Vehicle>> putVehicle(Vehicle vehicle) { | |
return mTripDataSourceFactory.getApiService().putVehicle(getToken(), vehicle) | |
.map(VehicleResponse::transform) | |
.compose(RxUtils.processErrors()); | |
} | |
@Override | |
public Observable<UseCaseResponse<Object>> deleteVehicle(Vehicle vehicle) { | |
return mTripDataSourceFactory.getApiService().deleteVehicle(getToken(), vehicle) | |
.map(VehicleResponse::transform) | |
.compose(RxUtils.processErrors()); | |
} | |
@Override | |
public Observable<UseCaseResponse<Object>> uploadAvatar(File avatarFile) { | |
return mTripDataSourceFactory.getApiService().uploadAvatar(getToken(), avatarFile) | |
.map(Response::transform) | |
.compose(RxUtils.processErrors()); | |
} | |
@Override | |
public Observable<UseCaseResponse<Object>> uploadVehiclePhoto(int vehicleId, File photo) { | |
return mTripDataSourceFactory.getApiService().uploadVehiclePhoto(getToken(), vehicleId, photo) | |
.map(Response::transform) | |
.compose(RxUtils.processErrors()); | |
} | |
public synchronized String getToken() { | |
return mPrivateStorage.fetchToken(); | |
} | |
public synchronized void putUser(User user) { | |
mPrivateStorage.putUser(user); | |
} | |
public synchronized void setUser(User user) { | |
this.mCurrentUser = user; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.entirec.kindneignbour.kindneighbour.internal.di.components; | |
import dagger.Component; | |
import ru.entirec.kindneignbour.kindneighbour.internal.di.PerFragment; | |
import ru.entirec.kindneignbour.kindneighbour.internal.di.modules.ProfileModule; | |
import ru.entirec.kindneignbour.kindneighbour.internal.di.modules.StorageModule; | |
import ru.entirec.kindneignbour.kindneighbour.internal.di.modules.UIModule; | |
import ru.entirec.kindneignbour.kindneighbour.view.custom.NavigationHeaderView; | |
import ru.entirec.kindneignbour.kindneighbour.view.fragments.PhotoPickerDialog; | |
import ru.entirec.kindneignbour.kindneighbour.view.fragments.ProfileEditFragment; | |
import ru.entirec.kindneignbour.kindneighbour.view.fragments.ProfileFragment; | |
import ru.entirec.kindneignbour.kindneighbour.view.fragments.TripsPagerFragment; | |
import ru.entirec.kindneignbour.kindneighbour.view.fragments.UserFragment; | |
import ru.entirec.kindneignbour.kindneighbour.view.fragments.VehicleFragment; | |
/** | |
* A scope {@link ru.entirec.kindneignbour.kindneighbour.internal.di.PerActivity} component. | |
* Injects user specific Fragments. | |
*/ | |
@PerFragment | |
@Component(dependencies = ActivityComponent.class, modules = {ProfileModule.class, StorageModule.class, UIModule.class}) | |
public interface ProfilesComponent { | |
void inject(NavigationHeaderView navigationHeaderView); | |
void inject(ProfileFragment profileFragment); | |
void inject(ProfileEditFragment profileFragment); | |
void inject(VehicleFragment vehicleFragment); | |
void inject(TripsPagerFragment tripsPagerFragment); | |
void inject(PhotoPickerDialog photoPickerDialog); | |
void inject(UserFragment userFragment); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment