/* * Copyright (c) 2016 Zhang Hai <Dreaming.in.Code.ZH@Gmail.com> * All Rights Reserved. */ package me.zhanghai.android.douya.user.content; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import com.android.volley.VolleyError; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import me.zhanghai.android.douya.content.ResourceFragment; import me.zhanghai.android.douya.eventbus.EventBusUtils; import me.zhanghai.android.douya.eventbus.UserUpdatedEvent; import me.zhanghai.android.douya.eventbus.UserWriteFinishedEvent; import me.zhanghai.android.douya.eventbus.UserWriteStartedEvent; import me.zhanghai.android.douya.network.Request; import me.zhanghai.android.douya.network.api.ApiRequests; 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.util.FragmentUtils; public class UserResource extends ResourceFragment<User, User> { // Not static because we are to be subclassed. private final String KEY_PREFIX = getClass().getName() + '.'; private final String EXTRA_USER_ID_OR_UID = KEY_PREFIX + "user_id_or_uid"; private final String EXTRA_SIMPLE_USER = KEY_PREFIX + "simple_user"; private final String EXTRA_USER = KEY_PREFIX + "user"; private String mUserIdOrUid; private SimpleUser mSimpleUser; private User mExtraUser; private static final String FRAGMENT_TAG_DEFAULT = UserResource.class.getName(); private static UserResource newInstance(String userIdOrUid, SimpleUser simpleUser, User user) { //noinspection deprecation return new UserResource().setArguments(userIdOrUid, simpleUser, user); } public static UserResource attachTo(String userIdOrUid, SimpleUser simpleUser, User user, Fragment fragment, String tag, int requestCode) { FragmentActivity activity = fragment.getActivity(); UserResource 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 UserResource 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 UserResource() {} protected UserResource 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; } public String getUserIdOrUid() { ensureArguments(); return mUserIdOrUid; } public SimpleUser getSimpleUser() { // Can be called before onCreate() is called. ensureArguments(); return mSimpleUser; } public boolean hasSimpleUser() { return getSimpleUser() != null; } @Override public User get() { User user = super.get(); if (user == null) { // Can be called before onCreate() is called. ensureArguments(); user = mExtraUser; } return user; } @Override protected void set(User user) { super.set(user); user = get(); if (user != null) { mSimpleUser = user; mUserIdOrUid = user.getIdOrUid(); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ensureArguments(); } private void ensureArguments() { if (mUserIdOrUid != null) { return; } Bundle arguments = getArguments(); mExtraUser = arguments.getParcelable(EXTRA_USER); if (mExtraUser != null) { mSimpleUser = mExtraUser; mUserIdOrUid = mExtraUser.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 onDestroy() { super.onDestroy(); if (has()) { User user = get(); setArguments(user.getIdOrUid(), user, user); } } @Override protected Request<User> onCreateRequest() { return ApiRequests.newUserRequest(mUserIdOrUid); } @Override protected void onLoadStarted() { getListener().onLoadUserStarted(getRequestCode()); } @Override protected void onLoadFinished(boolean successful, User response, VolleyError error) { getListener().onLoadUserFinished(getRequestCode()); if (successful) { set(response); onLoadSuccess(response); getListener().onUserChanged(getRequestCode(), get()); EventBusUtils.postAsync(new UserUpdatedEvent(response, this)); } else { getListener().onLoadUserError(getRequestCode(), error); } } protected void onLoadSuccess(User user) {} @Subscribe(threadMode = ThreadMode.MAIN) public void onUserUpdated(UserUpdatedEvent event) { if (event.isFromMyself(this)) { return; } if (event.mUser.hasIdOrUid(mUserIdOrUid)) { set(event.mUser); getListener().onUserChanged(getRequestCode(), get()); } } @Subscribe(threadMode = ThreadMode.MAIN) public void onUserWriteStarted(UserWriteStartedEvent event) { if (event.isFromMyself(this)) { return; } // Only call listener when we have the data. if (mExtraUser != null && mExtraUser.hasIdOrUid(event.userIdOrUid)) { getListener().onUserWriteStarted(getRequestCode()); } } @Subscribe(threadMode = ThreadMode.MAIN) public void onUserWriteFinished(UserWriteFinishedEvent event) { if (event.isFromMyself(this)) { return; } // Only call listener when we have the data. if (mExtraUser != null && mExtraUser.hasIdOrUid(event.userIdOrUid)) { getListener().onUserWriteFinished(getRequestCode()); } } private Listener getListener() { return (Listener) getTarget(); } public interface Listener { void onLoadUserStarted(int requestCode); void onLoadUserFinished(int requestCode); void onLoadUserError(int requestCode, VolleyError error); void onUserChanged(int requestCode, User newUser); void onUserWriteStarted(int requestCode); void onUserWriteFinished(int requestCode); } }