/* * Copyright (c) 2016 Zhang Hai <Dreaming.in.Code.ZH@Gmail.com> * All Rights Reserved. */ package me.zhanghai.android.douya.profile.content; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import com.android.volley.VolleyError; import java.util.List; import me.zhanghai.android.douya.app.TargetedRetainedFragment; import me.zhanghai.android.douya.broadcast.content.BroadcastListResource; import me.zhanghai.android.douya.diary.content.UserDiaryListResource; import me.zhanghai.android.douya.followship.content.FollowingListResource; import me.zhanghai.android.douya.network.api.info.apiv2.Broadcast; import me.zhanghai.android.douya.network.api.info.apiv2.SimpleUser; import me.zhanghai.android.douya.network.api.info.apiv2.User; import me.zhanghai.android.douya.network.api.info.frodo.Diary; import me.zhanghai.android.douya.network.api.info.frodo.Review; import me.zhanghai.android.douya.network.api.info.frodo.UserItems; import me.zhanghai.android.douya.review.content.UserReviewListResource; import me.zhanghai.android.douya.user.content.UserResource; import me.zhanghai.android.douya.util.FragmentUtils; public class ProfileResource extends TargetedRetainedFragment implements UserResource.Listener, BroadcastListResource.Listener, FollowingListResource.Listener, UserDiaryListResource.Listener, UserItemListResource.Listener, UserReviewListResource.Listener { private static final String KEY_PREFIX = ProfileResource.class.getName() + '.'; private static final String EXTRA_USER_ID_OR_UID = KEY_PREFIX + "user_id_or_uid"; private static final String EXTRA_SIMPLE_USER = KEY_PREFIX + "simple_user"; private static final String EXTRA_USER = KEY_PREFIX + "user"; private String mUserIdOrUid; private SimpleUser mSimpleUser; private User mUser; private UserResource mUserResource; private BroadcastListResource mBroadcastListResource; private FollowingListResource mFollowingListResource; private UserDiaryListResource mDiaryListResource; private UserItemListResource mUserItemListResource; private UserReviewListResource mReviewListResource; private boolean mHasError; private static final String FRAGMENT_TAG_DEFAULT = ProfileResource.class.getName(); private static ProfileResource newInstance(String userIdOrUid, SimpleUser simpleUser, User user) { //noinspection deprecation return new ProfileResource().setArguments(userIdOrUid, simpleUser, user); } public static ProfileResource attachTo(String userIdOrUid, SimpleUser simpleUser, User user, Fragment fragment, String tag, int requestCode) { FragmentActivity activity = fragment.getActivity(); ProfileResource instance = FragmentUtils.findByTag(activity, tag); if (instance == null) { instance = newInstance(userIdOrUid, simpleUser, user); instance.targetAt(fragment, requestCode); FragmentUtils.add(instance, activity, tag); } return instance; } public static ProfileResource attachTo(String userIdOrUid, SimpleUser simpleUser, User user, Fragment fragment) { return attachTo(userIdOrUid, simpleUser, user, fragment, FRAGMENT_TAG_DEFAULT, REQUEST_CODE_INVALID); } /** * @deprecated Use {@code attachTo()} instead. */ public ProfileResource() {} protected ProfileResource setArguments(String userIdOrUid, SimpleUser simpleUser, User user) { Bundle arguments = FragmentUtils.ensureArguments(this); arguments.putString(EXTRA_USER_ID_OR_UID, userIdOrUid); arguments.putParcelable(EXTRA_SIMPLE_USER, simpleUser); arguments.putParcelable(EXTRA_USER, user); return this; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ensureArguments(); mUserResource = UserResource.attachTo(mUserIdOrUid, mSimpleUser, mUser, this); ensureResourcesIfHasSimpleUser(); } @Override public void onDestroy() { super.onDestroy(); mUserResource.detach(); if (mBroadcastListResource != null) { mBroadcastListResource.detach(); } if (mFollowingListResource != null) { mFollowingListResource.detach(); } if (mDiaryListResource != null) { mDiaryListResource.detach(); } if (mUserItemListResource != null) { mUserItemListResource.detach(); } if (mReviewListResource != null) { mReviewListResource.detach(); } Bundle arguments = getArguments(); arguments.putString(EXTRA_USER_ID_OR_UID, mUserIdOrUid); arguments.putParcelable(EXTRA_SIMPLE_USER, mSimpleUser); arguments.putParcelable(EXTRA_USER, mUser); } public String getUserIdOrUid() { ensureArguments(); return mUserIdOrUid; } public SimpleUser getSimpleUser() { // Can be called before onCreate() is called. ensureArguments(); return mSimpleUser; } public boolean hasSimpleUser() { // Can be called before onCreate() is called. ensureArguments(); return mSimpleUser != null; } public User getUser() { // Can be called before onCreate() is called. ensureArguments(); return mUser; } public boolean hasUser() { // Can be called before onCreate() is called. ensureArguments(); return mUser != null; } private void ensureArguments() { if (mUserIdOrUid != null) { return; } Bundle arguments = getArguments(); mUser = arguments.getParcelable(EXTRA_USER); if (mUser != null) { mSimpleUser = mUser; mUserIdOrUid = mUser.getIdOrUid(); } else { mSimpleUser = arguments.getParcelable(EXTRA_SIMPLE_USER); if (mSimpleUser != null) { mUserIdOrUid = mSimpleUser.getIdOrUid(); } else { mUserIdOrUid = arguments.getString(EXTRA_USER_ID_OR_UID); } } } @Override public void onLoadUserStarted(int requestCode) {} @Override public void onLoadUserFinished(int requestCode) {} @Override public void onLoadUserError(int requestCode, VolleyError error) { notifyError(error); } @Override public void onUserChanged(int requestCode, User newUser) { mUser = newUser; mSimpleUser = newUser; mUserIdOrUid = newUser.getIdOrUid(); getListener().onUserChanged(getRequestCode(), newUser); notifyChangedIfLoaded(); ensureResourcesIfHasSimpleUser(); } @Override public void onUserWriteStarted(int requestCode) { getListener().onUserWriteStarted(getRequestCode()); } @Override public void onUserWriteFinished(int requestCode) { getListener().onUserWriteFinished(getRequestCode()); } private void ensureResourcesIfHasSimpleUser() { if (mBroadcastListResource != null || mFollowingListResource != null || mDiaryListResource != null || mUserItemListResource != null || mReviewListResource != null) { return; } if (mSimpleUser == null) { return; } mBroadcastListResource = BroadcastListResource.attachTo(mSimpleUser.getIdOrUid(), null, this); mFollowingListResource = FollowingListResource.attachTo(mSimpleUser.getIdOrUid(), this); mDiaryListResource = UserDiaryListResource.attachTo(mSimpleUser.getIdOrUid(), this); mUserItemListResource = UserItemListResource.attachTo(mSimpleUser.getIdOrUid(), this); mReviewListResource = UserReviewListResource.attachTo(mSimpleUser.getIdOrUid(), this); } @Override public void onLoadBroadcastListStarted(int requestCode) {} @Override public void onLoadBroadcastListFinished(int requestCode) {} @Override public void onLoadBroadcastListError(int requestCode, VolleyError error) { notifyError(error); } @Override public void onBroadcastListChanged(int requestCode, List<Broadcast> newBroadcastList) { notifyChangedIfLoaded(); } @Override public void onBroadcastListAppended(int requestCode, List<Broadcast> appendedBroadcastList) { notifyChangedIfLoaded(); } @Override public void onBroadcastChanged(int requestCode, int position, Broadcast newBroadcast) { notifyChangedIfLoaded(); } @Override public void onBroadcastRemoved(int requestCode, int position) { notifyChangedIfLoaded(); } @Override public void onBroadcastWriteStarted(int requestCode, int position) {} @Override public void onBroadcastWriteFinished(int requestCode, int position) {} @Override public void onLoadUserListStarted(int requestCode) {} @Override public void onLoadUserListFinished(int requestCode) {} @Override public void onLoadUserListError(int requestCode, VolleyError error) { notifyError(error); } @Override public void onUserListChanged(int requestCode, List<SimpleUser> newUserList) { notifyChangedIfLoaded(); } @Override public void onUserListAppended(int requestCode, List<SimpleUser> appendedUserList) { notifyChangedIfLoaded(); } @Override public void onLoadDiaryListStarted(int requestCode) {} @Override public void onLoadDiaryListFinished(int requestCode) {} @Override public void onLoadDiaryListError(int requestCode, VolleyError error) { notifyError(error); } @Override public void onDiaryListChanged(int requestCode, List<Diary> newDiaryList) { notifyChangedIfLoaded(); } @Override public void onDiaryListAppended(int requestCode, List<Diary> appendedDiaryList) { notifyChangedIfLoaded(); } @Override public void onDiaryChanged(int requestCode, int position, Diary newDiary) { notifyChangedIfLoaded(); } @Override public void onDiaryRemoved(int requestCode, int position) { notifyChangedIfLoaded(); } @Override public void onLoadUserItemListStarted(int requestCode) {} @Override public void onLoadUserItemListFinished(int requestCode) {} @Override public void onLoadUserItemListError(int requestCode, VolleyError error) { notifyError(error); } @Override public void onUserItemListChanged(int requestCode, List<UserItems> newUserItemList) { notifyChangedIfLoaded(); } @Override public void onLoadReviewListStarted(int requestCode) {} @Override public void onLoadReviewListFinished(int requestCode) {} @Override public void onLoadReviewListError(int requestCode, VolleyError error) { notifyError(error); } @Override public void onReviewListChanged(int requestCode, List<Review> newReviewList) { notifyChangedIfLoaded(); } @Override public void onReviewListAppended(int requestCode, List<Review> appendedReviewList) { notifyChangedIfLoaded(); } @Override public void onReviewChanged(int requestCode, int position, Review newReview) { notifyChangedIfLoaded(); } @Override public void onReviewRemoved(int requestCode, int position) { notifyChangedIfLoaded(); } public boolean isLoaded() { return hasUser() && mBroadcastListResource != null && mBroadcastListResource.has() && mFollowingListResource != null && mFollowingListResource.has() && mDiaryListResource != null && mDiaryListResource.has() && mUserItemListResource != null && mUserItemListResource.has() && mReviewListResource != null && mReviewListResource.has(); } public void notifyChangedIfLoaded() { if (isLoaded()) { getListener().onChanged(getRequestCode(), getUser(), mBroadcastListResource.get(), mFollowingListResource.get(), mDiaryListResource.get(), mUserItemListResource.get(), mReviewListResource.get()); } } private void notifyError(VolleyError error) { if (!mHasError) { mHasError = true; getListener().onLoadError(getRequestCode(), error); } } private Listener getListener() { return (Listener) getTarget(); } public interface Listener { void onLoadError(int requestCode, VolleyError error); void onUserChanged(int requestCode, User newUser); void onUserWriteStarted(int requestCode); void onUserWriteFinished(int requestCode); void onChanged(int requestCode, User newUser, List<Broadcast> newBroadcastList, List<SimpleUser> newFollowingList, List<Diary> newDiaryList, List<UserItems> newUserItemList, List<Review> newReviewList); } }