diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/fanfou/Fanfou.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/fanfou/Fanfou.java index 4f2d6b60a..1dd017593 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/fanfou/Fanfou.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/fanfou/Fanfou.java @@ -1,5 +1,8 @@ package org.mariotaku.twidere.api.fanfou; +import org.mariotaku.twidere.api.fanfou.api.BlocksResources; +import org.mariotaku.twidere.api.fanfou.api.FavoritesResources; +import org.mariotaku.twidere.api.fanfou.api.FriendshipsResources; import org.mariotaku.twidere.api.fanfou.api.PhotosResources; import org.mariotaku.twidere.api.fanfou.api.SearchResources; import org.mariotaku.twidere.api.fanfou.api.TimelineResources; @@ -8,5 +11,6 @@ import org.mariotaku.twidere.api.fanfou.api.UsersResources; /** * Created by mariotaku on 16/3/10. */ -public interface Fanfou extends TimelineResources, SearchResources, UsersResources, PhotosResources { +public interface Fanfou extends TimelineResources, SearchResources, UsersResources, PhotosResources, + FriendshipsResources, BlocksResources, FavoritesResources { } diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/fanfou/api/BlocksResources.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/fanfou/api/BlocksResources.java new file mode 100644 index 000000000..e74416476 --- /dev/null +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/fanfou/api/BlocksResources.java @@ -0,0 +1,19 @@ +package org.mariotaku.twidere.api.fanfou.api; + +import org.mariotaku.restfu.annotation.method.POST; +import org.mariotaku.restfu.annotation.param.Param; +import org.mariotaku.restfu.http.BodyType; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.User; + +/** + * Created by mariotaku on 16/3/11. + */ +public interface BlocksResources { + + @POST("/blocks/create.json") + User createFanfouBlock(@Param("id") String userId) throws TwitterException; + + @POST("/blocks/destroy.json") + User destroyFanfouBlock(@Param("id") String userId) throws TwitterException; +} diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/fanfou/api/FavoritesResources.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/fanfou/api/FavoritesResources.java new file mode 100644 index 000000000..cde83a2a7 --- /dev/null +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/fanfou/api/FavoritesResources.java @@ -0,0 +1,18 @@ +package org.mariotaku.twidere.api.fanfou.api; + +import org.mariotaku.restfu.annotation.method.POST; +import org.mariotaku.restfu.annotation.param.Path; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.Status; + +/** + * Created by mariotaku on 16/3/11. + */ +public interface FavoritesResources { + + @POST("/favorites/create/{id}.json") + Status createFanfouFavorite(@Path("id") String id) throws TwitterException; + + @POST("/favorites/destroy/{id}.json") + Status destroyFanfouFavorite(@Path("id") String id) throws TwitterException; +} diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/fanfou/api/FriendshipsResources.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/fanfou/api/FriendshipsResources.java new file mode 100644 index 000000000..3fa382068 --- /dev/null +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/fanfou/api/FriendshipsResources.java @@ -0,0 +1,32 @@ +package org.mariotaku.twidere.api.fanfou.api; + +import org.mariotaku.restfu.annotation.method.GET; +import org.mariotaku.restfu.annotation.method.POST; +import org.mariotaku.restfu.annotation.param.Param; +import org.mariotaku.restfu.annotation.param.Query; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.Paging; +import org.mariotaku.twidere.api.twitter.model.ResponseList; +import org.mariotaku.twidere.api.twitter.model.User; + +/** + * Created by mariotaku on 16/3/11. + */ +public interface FriendshipsResources { + + @POST("/friendships/create.json") + User createFanfouFriendship(@Param("id") String id) throws TwitterException; + + @POST("/friendships/destroy.json") + User destroyFanfouFriendship(@Param("id") String id) throws TwitterException; + + @POST("/friendships/accept.json") + User acceptFanfouFriendship(@Param("id") String id) throws TwitterException; + + @POST("/friendships/deny.json") + User denyFanfouFriendship(@Param("id") String id) throws TwitterException; + + @GET("/friendships/requests.json") + ResponseList getFriendshipsRequests(@Query Paging paging) throws TwitterException; + +} diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/TwitterException.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/TwitterException.java index e33d7f892..ea4d06c11 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/TwitterException.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/TwitterException.java @@ -258,6 +258,9 @@ public class TwitterException extends Exception implements TwitterResponse, Http return getMessage(); } + public String getErrorMessage() { + return errorMessage; + } void setNested() { nested = true; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/FavoritesResources.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/FavoritesResources.java index 619b2d7aa..ef357d985 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/FavoritesResources.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/FavoritesResources.java @@ -42,11 +42,9 @@ import org.mariotaku.twidere.api.twitter.model.Status; public interface FavoritesResources { @POST("/favorites/create.json") - @BodyType(BodyType.FORM) Status createFavorite(@Param("id") String id) throws TwitterException; @POST("/favorites/destroy.json") - @BodyType(BodyType.FORM) Status destroyFavorite(@Param("id") String id) throws TwitterException; @GET("/favorites/list.json") diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/UsersResources.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/UsersResources.java index b59bc822b..90345960b 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/UsersResources.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/UsersResources.java @@ -46,35 +46,27 @@ import org.mariotaku.twidere.api.twitter.model.User; public interface UsersResources { @POST("/blocks/create.json") - @BodyType(BodyType.FORM) User createBlock(@Param("user_id") String userId) throws TwitterException; @POST("/blocks/create.json") - @BodyType(BodyType.FORM) User createBlockByScreenName(@Query("screen_name") String screenName) throws TwitterException; @POST("/mutes/users/create.json") - @BodyType(BodyType.FORM) User createMute(@Param("user_id") String userId) throws TwitterException; @POST("/mutes/users/create.json") - @BodyType(BodyType.FORM) User createMuteByScreenName(@Query("screen_name") String screenName) throws TwitterException; @POST("/blocks/destroy.json") - @BodyType(BodyType.FORM) User destroyBlock(@Param("user_id") String userId) throws TwitterException; @POST("/blocks/destroy.json") - @BodyType(BodyType.FORM) User destroyBlockByScreenName(@Query("screen_name") String screenName) throws TwitterException; @POST("/mutes/users/destroy.json") - @BodyType(BodyType.FORM) User destroyMute(@Param("user_id") String userId) throws TwitterException; @POST("/mutes/users/destroy.json") - @BodyType(BodyType.FORM) User destroyMuteByScreenName(@Query("screen_name") String screenName) throws TwitterException; @GET("/account/settings.json") diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUser.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUser.java index 7aace443d..1374a9147 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUser.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUser.java @@ -102,6 +102,10 @@ public class ParcelableUser implements Parcelable, Comparable { @CursorField(CachedUsers.PROFILE_BANNER_URL) public String profile_banner_url; @ParcelableThisPlease + @JsonField(name = "profile_background_url") + @CursorField(CachedUsers.PROFILE_BACKGROUND_URL) + public String profile_background_url; + @ParcelableThisPlease @JsonField(name = "url") @CursorField(CachedUsers.URL) public String url; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java index bd73ef12b..a0c42e217 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java @@ -263,6 +263,8 @@ public interface TwidereDataStore { String PROFILE_BANNER_URL = "profile_banner_url"; + String PROFILE_BACKGROUND_URL = "profile_background_url"; + String FOLLOWERS_COUNT = "followers_count"; String FRIENDS_COUNT = "friends_count"; @@ -301,18 +303,19 @@ public interface TwidereDataStore { String USER_HOST = "user_host"; String[] COLUMNS = {_ID, USER_KEY, CREATED_AT, NAME, SCREEN_NAME, DESCRIPTION_PLAIN, LOCATION, - URL, PROFILE_IMAGE_URL, PROFILE_BANNER_URL, IS_PROTECTED, IS_VERIFIED, IS_FOLLOWING, - FOLLOWERS_COUNT, FRIENDS_COUNT, STATUSES_COUNT, FAVORITES_COUNT, LISTED_COUNT, - MEDIA_COUNT, DESCRIPTION_HTML, DESCRIPTION_EXPANDED, URL_EXPANDED, BACKGROUND_COLOR, - LINK_COLOR, TEXT_COLOR, LAST_SEEN, DESCRIPTION_UNESCAPED, EXTRAS, USER_HOST}; + URL, PROFILE_IMAGE_URL, PROFILE_BANNER_URL, PROFILE_BACKGROUND_URL, IS_PROTECTED, + IS_VERIFIED, IS_FOLLOWING, FOLLOWERS_COUNT, FRIENDS_COUNT, STATUSES_COUNT, + FAVORITES_COUNT, LISTED_COUNT, MEDIA_COUNT, DESCRIPTION_HTML, DESCRIPTION_EXPANDED, + URL_EXPANDED, BACKGROUND_COLOR, LINK_COLOR, TEXT_COLOR, LAST_SEEN, + DESCRIPTION_UNESCAPED, EXTRAS, USER_HOST}; String[] BASIC_COLUMNS = {_ID, USER_KEY, NAME, SCREEN_NAME, PROFILE_IMAGE_URL}; String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_TEXT_NOT_NULL, TYPE_INT, TYPE_TEXT, TYPE_TEXT, - TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_BOOLEAN, TYPE_BOOLEAN, - TYPE_BOOLEAN, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_TEXT, - TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, - TYPE_TEXT}; + TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_BOOLEAN, + TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, + TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, + TYPE_TEXT, TYPE_TEXT, TYPE_TEXT}; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/Constants.java b/twidere/src/main/java/org/mariotaku/twidere/Constants.java index 64b40640c..4d4a62a51 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/Constants.java +++ b/twidere/src/main/java/org/mariotaku/twidere/Constants.java @@ -34,7 +34,7 @@ import static org.mariotaku.twidere.annotation.PreferenceType.STRING; public interface Constants extends TwidereConstants { String DATABASES_NAME = "twidere.sqlite"; - int DATABASES_VERSION = 132; + int DATABASES_VERSION = 133; int MENU_GROUP_STATUS_EXTENSION = 10; int MENU_GROUP_COMPOSE_EXTENSION = 11; diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java index 5579acb67..535deaa53 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java @@ -75,12 +75,13 @@ import org.mariotaku.twidere.fragment.support.AccountsDashboardFragment; import org.mariotaku.twidere.fragment.support.DirectMessagesFragment; import org.mariotaku.twidere.fragment.support.TrendsSuggestionsFragment; import org.mariotaku.twidere.graphic.EmptyDrawable; -import org.mariotaku.twidere.model.UserKey; import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.SupportTabSpec; +import org.mariotaku.twidere.model.UserKey; import org.mariotaku.twidere.model.message.TaskStateChangedEvent; import org.mariotaku.twidere.model.message.UnreadCountUpdatedEvent; import org.mariotaku.twidere.provider.TwidereDataStore.Accounts; +import org.mariotaku.twidere.provider.TwidereDataStore.Activities; import org.mariotaku.twidere.provider.TwidereDataStore.Statuses; import org.mariotaku.twidere.service.StreamingService; import org.mariotaku.twidere.task.AbstractTask; @@ -929,7 +930,7 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen true, ReadPositionTag.HOME_TIMELINE, accountKeys); final long position = mReadStateManager.getPosition(tagWithAccounts); final int count = DataStoreUtils.getStatusesCount(mContext, Statuses.CONTENT_URI, - position, accountKeys); + position, Statuses.STATUS_TIMESTAMP, accountKeys); result.put(i, count); publishProgress(new TabBadge(i, count)); break; @@ -940,7 +941,7 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen true, ReadPositionTag.ACTIVITIES_ABOUT_ME, accountIds); final long position = mReadStateManager.getPosition(tagWithAccounts); final int count = DataStoreUtils.getInteractionsCount(mContext, spec.args, - accountIds, position); + accountIds, position, Activities.TIMESTAMP); publishProgress(new TabBadge(i, count)); result.put(i, count); break; diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableUsersAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableUsersAdapter.java index 1e0838835..bfcebe072 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableUsersAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableUsersAdapter.java @@ -20,9 +20,9 @@ package org.mariotaku.twidere.adapter; import android.content.Context; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; -import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -52,6 +52,7 @@ public class ParcelableUsersAdapter extends LoadMoreSupportAdapter mData; private UserAdapterListener mUserAdapterListener; private RequestClickListener mRequestClickListener; + private FollowClickListener mFollowClickListener; public ParcelableUsersAdapter(Context context) { @@ -131,11 +132,11 @@ public class ParcelableUsersAdapter extends LoadMoreSupportAdapter extends IContentCardAdapter { RequestClickListener getRequestClickListener(); + FollowClickListener getFollowClickListener(); + boolean shouldShowAccountsColor(); @NonNull @@ -65,4 +67,8 @@ public interface IUsersAdapter extends IContentCardAdapter { void onDenyClicked(UserViewHolder holder, int position); } + + interface FollowClickListener { + void onFollowClicked(UserViewHolder holder, int position); + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsActivitiesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsActivitiesFragment.java index 047186219..2e2c0ba7e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsActivitiesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsActivitiesFragment.java @@ -445,7 +445,7 @@ public abstract class AbsActivitiesFragment extends AbsContentListRecyclerViewFr } @Override - public void afterExecute(RecyclerView recyclerView, Boolean result) { + public void afterExecute(RecyclerView recyclerView, Object params, Boolean result) { if (result) { recyclerView.addOnScrollListener(mActiveHotMobiScrollTracker = mHotMobiScrollTracker); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java index 885a5597e..aa350418d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java @@ -441,7 +441,7 @@ public abstract class AbsStatusesFragment extends AbsContentListRecyclerViewFrag } @Override - public void afterExecute(RecyclerView recyclerView, Boolean result) { + public void afterExecute(RecyclerView recyclerView, Object params, Boolean result) { if (result) { recyclerView.addOnScrollListener(mActiveHotMobiScrollTracker = mHotMobiScrollTracker); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java index 4694b0dbb..eae6cc441 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java @@ -91,11 +91,11 @@ import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.SupportTabSpec; import org.mariotaku.twidere.model.UserKey; import org.mariotaku.twidere.model.util.ParcelableAccountUtils; +import org.mariotaku.twidere.model.util.ParcelableUserUtils; import org.mariotaku.twidere.provider.TwidereDataStore.Accounts; import org.mariotaku.twidere.util.CompareUtils; import org.mariotaku.twidere.util.DataStoreUtils; import org.mariotaku.twidere.util.IntentUtils; -import org.mariotaku.twidere.util.InternalTwitterContentUtils; import org.mariotaku.twidere.util.KeyboardShortcutsHandler; import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback; import org.mariotaku.twidere.util.ListViewUtils; @@ -734,10 +734,15 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo final Resources res = getResources(); final int defWidth = res.getDisplayMetrics().widthPixels; final int width = bannerWidth > 0 ? bannerWidth : defWidth; - final String bannerUrl = InternalTwitterContentUtils.getBestBannerUrl(account.profile_banner_url, width); + String bannerUrl = account.profile_banner_url; + if (bannerUrl == null && ParcelableAccount.Type.FANFOU.equals(account.account_type)) { + if (account.account_user != null) { + bannerUrl = ParcelableUserUtils.getProfileBannerUrl(account.account_user); + } + } final ImageView bannerView = mAccountProfileBannerView; if (bannerView.getDrawable() == null || !CompareUtils.objectEquals(bannerUrl, bannerView.getTag())) { - mMediaLoader.displayProfileBanner(mAccountProfileBannerView, bannerUrl, this); + mMediaLoader.displayProfileBanner(mAccountProfileBannerView, bannerUrl, width, this); } else { mMediaLoader.cancelDisplayTask(mAccountProfileBannerView); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportFragment.java index e197ad294..398081162 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportFragment.java @@ -40,7 +40,6 @@ import com.squareup.otto.Bus; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.activity.iface.IThemedActivity; -import org.mariotaku.twidere.activity.support.BaseAppCompatActivity; import org.mariotaku.twidere.fragment.iface.IBaseFragment; import org.mariotaku.twidere.util.AsyncTaskManager; import org.mariotaku.twidere.util.AsyncTwitterWrapper; @@ -84,7 +83,7 @@ public class BaseSupportFragment extends Fragment implements IBaseFragment, Cons @Inject protected ErrorInfoStore mErrorInfoStore; @Inject - TwidereValidator mValidator; + protected TwidereValidator mValidator; private final ActionHelper mActionHelper = new ActionHelper(this); @@ -123,13 +122,6 @@ public class BaseSupportFragment extends Fragment implements IBaseFragment, Cons activity.registerReceiver(receiver, filter); } - public void setProgressBarIndeterminateVisibility(final boolean visible) { - final Activity activity = getActivity(); - if (activity instanceof BaseAppCompatActivity) { - activity.setProgressBarIndeterminateVisibility(visible); - } - } - public void unregisterReceiver(final BroadcastReceiver receiver) { final Activity activity = getActivity(); if (activity == null) return; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CreateUserBlockDialogFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CreateUserBlockDialogFragment.java index e24c07dd3..c7f04dc2e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CreateUserBlockDialogFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CreateUserBlockDialogFragment.java @@ -44,7 +44,7 @@ public class CreateUserBlockDialogFragment extends BaseSupportDialogFragment imp final ParcelableUser user = getUser(); final AsyncTwitterWrapper twitter = mTwitterWrapper; if (user == null || twitter == null) return; - twitter.createBlockAsync(user.account_key, user.key.getId()); + twitter.createBlockAsync(user.account_key, user.key); break; default: break; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CreateUserMuteDialogFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CreateUserMuteDialogFragment.java index 20f5646a0..910ef8eff 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CreateUserMuteDialogFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CreateUserMuteDialogFragment.java @@ -44,7 +44,7 @@ public class CreateUserMuteDialogFragment extends BaseSupportDialogFragment impl final ParcelableUser user = getUser(); final AsyncTwitterWrapper twitter = mTwitterWrapper; if (user == null || twitter == null) return; - twitter.createMuteAsync(user.account_key, user.key.getId()); + twitter.createMuteAsync(user.account_key, user.key); break; default: break; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DestroyFriendshipDialogFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DestroyFriendshipDialogFragment.java index 5a989d54c..9014ec9c7 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DestroyFriendshipDialogFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DestroyFriendshipDialogFragment.java @@ -45,7 +45,7 @@ public class DestroyFriendshipDialogFragment extends BaseSupportDialogFragment i final ParcelableUser user = getUser(); final AsyncTwitterWrapper twitter = mTwitterWrapper; if (user == null || twitter == null) return; - twitter.destroyFriendshipAsync(user.account_key, user.key.getId()); + twitter.destroyFriendshipAsync(user.account_key, user.key); break; default: break; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/IncomingFriendshipsFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/IncomingFriendshipsFragment.java index e5819d1fd..f019c9080 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/IncomingFriendshipsFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/IncomingFriendshipsFragment.java @@ -23,38 +23,26 @@ import android.content.Context; import android.os.Bundle; import android.support.annotation.NonNull; -import com.squareup.otto.Subscribe; - import org.mariotaku.twidere.adapter.ParcelableUsersAdapter; import org.mariotaku.twidere.adapter.iface.IUsersAdapter; import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader; import org.mariotaku.twidere.loader.support.IncomingFriendshipsLoader; -import org.mariotaku.twidere.loader.support.UserFriendsLoader; -import org.mariotaku.twidere.model.UserKey; import org.mariotaku.twidere.model.ParcelableUser; -import org.mariotaku.twidere.model.message.FollowRequestTaskEvent; +import org.mariotaku.twidere.model.UserKey; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; import org.mariotaku.twidere.view.holder.UserViewHolder; -public class IncomingFriendshipsFragment extends CursorSupportUsersListFragment implements IUsersAdapter.RequestClickListener { - @Override - public void onStart() { - super.onStart(); - mBus.register(this); - } - - @Override - public void onStop() { - mBus.unregister(this); - super.onStop(); - } +public class IncomingFriendshipsFragment extends CursorSupportUsersListFragment implements + IUsersAdapter.RequestClickListener { @Override public CursorSupportUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, - final boolean fromUser) { + final boolean fromUser) { final UserKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY); final IncomingFriendshipsLoader loader = new IncomingFriendshipsLoader(context, accountKey, getData(), fromUser); loader.setCursor(getNextCursor()); + loader.setPage(getNextPage()); return loader; } @@ -82,14 +70,16 @@ public class IncomingFriendshipsFragment extends CursorSupportUsersListFragment mTwitterWrapper.denyFriendshipAsync(user.account_key, user.key); } - @Subscribe - public void onFollowRequestTaskEvent(FollowRequestTaskEvent event) { - final ParcelableUsersAdapter adapter = getAdapter(); - final int position = adapter.findPosition(event.getAccountKey(), event.getUserId()); - if (event.isFinished() && event.isSucceeded()) { - adapter.removeUserAt(position); - } else { - adapter.notifyItemChanged(position); + @Override + protected boolean shouldRemoveUser(int position, FriendshipTaskEvent event) { + if (!event.isSucceeded()) return false; + switch (event.getAction()) { + case FriendshipTaskEvent.Action.BLOCK: + case FriendshipTaskEvent.Action.ACCEPT: + case FriendshipTaskEvent.Action.DENY: { + return true; + } } + return false; } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MutesUsersListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MutesUsersListFragment.java index 8e6117e68..78a77372b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MutesUsersListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MutesUsersListFragment.java @@ -37,6 +37,7 @@ public class MutesUsersListFragment extends CursorSupportUsersListFragment { final UserKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY); final MutesUsersLoader loader = new MutesUsersLoader(context, accountKey, getData(), fromUser); loader.setCursor(getNextCursor()); + loader.setPage(getNextPage()); return loader; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableUsersFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableUsersFragment.java index 4d11259f1..b451fd8cd 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableUsersFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableUsersFragment.java @@ -33,26 +33,68 @@ import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.KeyEvent; +import com.squareup.otto.Subscribe; + import org.mariotaku.twidere.adapter.ParcelableUsersAdapter; import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition; +import org.mariotaku.twidere.adapter.iface.IUsersAdapter; import org.mariotaku.twidere.adapter.iface.IUsersAdapter.UserAdapterListener; import org.mariotaku.twidere.loader.iface.IExtendedLoader; import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.UserKey; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; import org.mariotaku.twidere.model.util.UserKeyUtils; +import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.IntentUtils; import org.mariotaku.twidere.util.KeyboardShortcutsHandler; import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback; import org.mariotaku.twidere.util.LinkCreator; +import org.mariotaku.twidere.util.ParcelUtils; import org.mariotaku.twidere.util.RecyclerViewNavigationHelper; import org.mariotaku.twidere.view.holder.UserViewHolder; import java.util.List; public abstract class ParcelableUsersFragment extends AbsContentListRecyclerViewFragment - implements LoaderCallbacks>, UserAdapterListener, KeyboardShortcutCallback { + implements LoaderCallbacks>, UserAdapterListener, KeyboardShortcutCallback, + IUsersAdapter.FollowClickListener { + + @NonNull + private final Object mUsersBusCallback; private RecyclerViewNavigationHelper mNavigationHelper; + protected ParcelableUsersFragment() { + mUsersBusCallback = createMessageBusCallback(); + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + final ParcelableUsersAdapter adapter = getAdapter(); + final RecyclerView recyclerView = getRecyclerView(); + final LinearLayoutManager layoutManager = getLayoutManager(); + adapter.setUserAdapterListener(this); + + mNavigationHelper = new RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter, + this); + final Bundle loaderArgs = new Bundle(getArguments()); + loaderArgs.putBoolean(EXTRA_FROM_USER, true); + getLoaderManager().initLoader(0, loaderArgs, this); + } + + @Override + public void onStart() { + super.onStart(); + mBus.register(mUsersBusCallback); + } + + @Override + public void onStop() { + mBus.unregister(mUsersBusCallback); + super.onStop(); + } + @Override public boolean isRefreshing() { if (getContext() == null || isDetached()) return false; @@ -63,7 +105,9 @@ public abstract class ParcelableUsersFragment extends AbsContentListRecyclerView @NonNull @Override protected ParcelableUsersAdapter onCreateAdapter(Context context, boolean compact) { - return new ParcelableUsersAdapter(context); + final ParcelableUsersAdapter adapter = new ParcelableUsersAdapter(context); + adapter.setFollowClickListener(this); + return adapter; } @NonNull @@ -72,10 +116,7 @@ public abstract class ParcelableUsersFragment extends AbsContentListRecyclerView return super.getAdapter(); } - protected boolean hasMoreData(List data) { - return data == null || !data.isEmpty(); - } - + @Override public void onLoadFinished(Loader> loader, List data) { final ParcelableUsersAdapter adapter = getAdapter(); adapter.setData(data); @@ -92,14 +133,6 @@ public abstract class ParcelableUsersFragment extends AbsContentListRecyclerView setLoadMoreIndicatorPosition(IndicatorPosition.NONE); } - protected void removeUsers(String... ids) { - //TODO remove from adapter - } - - public final List getData() { - return getAdapter().getData(); - } - @Override public boolean handleKeyboardShortcutSingle(@NonNull KeyboardShortcutsHandler handler, int keyCode, @NonNull KeyEvent event, int metaState) { return mNavigationHelper.handleKeyboardShortcutSingle(handler, keyCode, event, metaState); @@ -115,21 +148,6 @@ public abstract class ParcelableUsersFragment extends AbsContentListRecyclerView return mNavigationHelper.isKeyboardShortcutHandled(handler, keyCode, event, metaState); } - @Override - public void onActivityCreated(@Nullable Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - final ParcelableUsersAdapter adapter = getAdapter(); - final RecyclerView recyclerView = getRecyclerView(); - final LinearLayoutManager layoutManager = getLayoutManager(); - adapter.setUserAdapterListener(this); - - mNavigationHelper = new RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter, - this); - final Bundle loaderArgs = new Bundle(getArguments()); - loaderArgs.putBoolean(EXTRA_FROM_USER, true); - getLoaderManager().initLoader(0, loaderArgs, this); - } - @Override public final Loader> onCreateLoader(int id, Bundle args) { final boolean fromUser = args.getBoolean(EXTRA_FROM_USER); @@ -161,6 +179,20 @@ public abstract class ParcelableUsersFragment extends AbsContentListRecyclerView } } + @Override + public void onFollowClicked(UserViewHolder holder, int position) { + final AsyncTwitterWrapper twitter = mTwitterWrapper; + final ParcelableUsersAdapter adapter = getAdapter(); + final ParcelableUser user = adapter.getUser(position); + if (user == null || twitter == null) return; + if (twitter.isUpdatingRelationship(user.account_key, user.key)) return; + if (user.is_following) { + DestroyFriendshipDialogFragment.show(getFragmentManager(), user); + } else { + twitter.createFriendshipAsync(user.account_key, user.key); + } + } + @UserFragment.Referral protected String getUserReferral() { return null; @@ -179,4 +211,55 @@ public abstract class ParcelableUsersFragment extends AbsContentListRecyclerView protected void setupRecyclerView(Context context, boolean compact) { super.setupRecyclerView(context, true); } + + private int findPosition(ParcelableUsersAdapter adapter, UserKey accountKey, UserKey userKey) { + return adapter.findPosition(accountKey, userKey); + } + + protected boolean shouldRemoveUser(int position, FriendshipTaskEvent event) { + return false; + } + + protected boolean hasMoreData(List data) { + return data == null || !data.isEmpty(); + } + + protected void removeUsers(String... ids) { + //TODO remove from adapter + } + + public final List getData() { + return getAdapter().getData(); + } + + @NonNull + protected Object createMessageBusCallback() { + return new UsersBusCallback(); + } + + protected class UsersBusCallback { + + @Subscribe + public void onFriendshipTaskEvent(FriendshipTaskEvent event) { + final ParcelableUsersAdapter adapter = getAdapter(); + final int position = findPosition(adapter, event.getAccountKey(), event.getUserKey()); + final List data = adapter.getData(); + if (shouldRemoveUser(position, event)) { + data.remove(position); + adapter.notifyItemRemoved(position); + } else { + ParcelableUser adapterUser = data.get(position); + ParcelableUser eventUser = event.getUser(); + if (eventUser != null) { + if (adapterUser.account_key.equals(eventUser.account_key)) { + ParcelableUser clone = ParcelUtils.clone(eventUser); + clone.position = adapterUser.position; + data.set(position, clone); + } + } + adapter.notifyItemChanged(position); + } + } + + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ReportSpamDialogFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ReportSpamDialogFragment.java index 26d6160ed..2e1c60ec9 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ReportSpamDialogFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ReportSpamDialogFragment.java @@ -44,7 +44,7 @@ public class ReportSpamDialogFragment extends BaseSupportDialogFragment implemen final ParcelableUser user = getUser(); final AsyncTwitterWrapper twitter = mTwitterWrapper; if (user == null || twitter == null) return; - twitter.reportSpamAsync(user.account_key, user.key.getId()); + twitter.reportSpamAsync(user.account_key, user.key); break; default: break; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFavoritersListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFavoritersListFragment.java index 5896732bc..4db80d431 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFavoritersListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFavoritersListFragment.java @@ -37,6 +37,7 @@ public class StatusFavoritersListFragment extends CursorSupportUsersListFragment final StatusFavoritersLoader loader = new StatusFavoritersLoader(context, accountKey, statusId, getData(), false); loader.setCursor(getNextCursor()); + loader.setPage(getNextPage()); return loader; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusRetweetersListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusRetweetersListFragment.java index 6dfd1afe8..68ff29803 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusRetweetersListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusRetweetersListFragment.java @@ -39,6 +39,7 @@ public class StatusRetweetersListFragment extends CursorSupportUsersListFragment final StatusRetweetersLoader loader = new StatusRetweetersLoader(context, accountKey, statusId, getData(), fromUser); loader.setCursor(getNextCursor()); + loader.setPage(getNextPage()); return loader; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserBlocksListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserBlocksListFragment.java index 4dc9fbc6e..b7e7508c4 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserBlocksListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserBlocksListFragment.java @@ -26,6 +26,7 @@ import android.support.annotation.NonNull; import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader; import org.mariotaku.twidere.loader.support.UserBlocksLoader; import org.mariotaku.twidere.model.UserKey; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; public class UserBlocksListFragment extends CursorSupportUsersListFragment { @@ -36,7 +37,20 @@ public class UserBlocksListFragment extends CursorSupportUsersListFragment { final UserKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY); final UserBlocksLoader loader = new UserBlocksLoader(context, accountKey, getData(), fromUser); loader.setCursor(getNextCursor()); + loader.setPage(getNextPage()); return loader; } + @Override + protected boolean shouldRemoveUser(int position, FriendshipTaskEvent event) { + if (!event.isSucceeded()) return false; + switch (event.getAction()) { + case FriendshipTaskEvent.Action.FOLLOW: + case FriendshipTaskEvent.Action.UNBLOCK: { + return true; + } + } + return false; + } + } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFollowersFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFollowersFragment.java index 37a73745e..e7c3b72b9 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFollowersFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFollowersFragment.java @@ -22,32 +22,14 @@ package org.mariotaku.twidere.fragment.support; import android.content.Context; import android.os.Bundle; import android.support.annotation.NonNull; -import android.text.TextUtils; - -import com.squareup.otto.Subscribe; import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader; import org.mariotaku.twidere.loader.support.UserFollowersLoader; -import org.mariotaku.twidere.loader.support.UserFriendsLoader; import org.mariotaku.twidere.model.UserKey; -import org.mariotaku.twidere.model.message.UsersBlockedEvent; - -import static org.mariotaku.twidere.util.DataStoreUtils.getAccountScreenName; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; public class UserFollowersFragment extends CursorSupportUsersListFragment { - @Override - public void onStart() { - super.onStart(); - mBus.register(this); - } - - @Override - public void onStop() { - mBus.unregister(this); - super.onStop(); - } - @Override public CursorSupportUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, @@ -62,16 +44,15 @@ public class UserFollowersFragment extends CursorSupportUsersListFragment { return loader; } - @Subscribe - public void onUsersBlocked(UsersBlockedEvent event) { - final UserKey accountKey = event.getAccountKey(); - final String screenName = getAccountScreenName(getActivity(), accountKey); - final Bundle args = getArguments(); - if (args == null) return; - if (accountKey != null && TextUtils.equals(accountKey.getId(), args.getString(EXTRA_USER_ID)) - || screenName != null && screenName.equalsIgnoreCase(args.getString(EXTRA_SCREEN_NAME))) { - removeUsers(event.getUserIds()); + @Override + protected boolean shouldRemoveUser(int position, FriendshipTaskEvent event) { + if (!event.isSucceeded()) return false; + switch (event.getAction()) { + case FriendshipTaskEvent.Action.BLOCK: { + return true; + } } + return false; } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java index 540f942c1..dc21f6191 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java @@ -111,12 +111,13 @@ import org.mariotaku.twidere.model.ParcelableUserValuesCreator; import org.mariotaku.twidere.model.SingleResponse; import org.mariotaku.twidere.model.SupportTabSpec; import org.mariotaku.twidere.model.UserKey; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; import org.mariotaku.twidere.model.message.FriendshipUpdatedEvent; -import org.mariotaku.twidere.model.message.FriendshipUserUpdatedEvent; import org.mariotaku.twidere.model.message.ProfileUpdatedEvent; import org.mariotaku.twidere.model.message.TaskStateChangedEvent; import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils; import org.mariotaku.twidere.model.util.ParcelableMediaUtils; +import org.mariotaku.twidere.model.util.ParcelableUserUtils; import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships; import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers; import org.mariotaku.twidere.provider.TwidereDataStore.Filters; @@ -127,6 +128,7 @@ import org.mariotaku.twidere.util.ContentValuesCreator; import org.mariotaku.twidere.util.DataStoreUtils; import org.mariotaku.twidere.util.HtmlSpanBuilder; import org.mariotaku.twidere.util.IntentUtils; +import org.mariotaku.twidere.util.InternalTwitterContentUtils; import org.mariotaku.twidere.util.KeyboardShortcutsHandler; import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback; import org.mariotaku.twidere.util.LinkCreator; @@ -271,9 +273,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener mHeaderErrorTextView.setVisibility(View.GONE); setListShown(false); } - setProgressBarIndeterminateVisibility(true); final ParcelableUser user = mUser; - final boolean loadFromCache = user == null || !user.is_cache && userId != user.key.getId(); + final boolean loadFromCache = user == null || !user.is_cache && user.key.check(userId, null); return new ParcelableUserLoader(getActivity(), accountKey, userId, screenName, getArguments(), omitIntentExtra, loadFromCache); } @@ -317,7 +318,6 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener mHeaderErrorContainer.setVisibility(View.VISIBLE); mProgressContainer.setVisibility(View.GONE); } - setProgressBarIndeterminateVisibility(false); } }; @@ -569,10 +569,11 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener } final int defWidth = resources.getDisplayMetrics().widthPixels; final int width = mBannerWidth > 0 ? mBannerWidth : defWidth; - if (ObjectUtils.notEqual(mProfileBannerView.getTag(), user.profile_banner_url) || + final String bannerUrl = ParcelableUserUtils.getProfileBannerUrl(user); + if (ObjectUtils.notEqual(mProfileBannerView.getTag(), bannerUrl) || mProfileBannerView.getDrawable() == null) { - mProfileBannerView.setTag(user.profile_banner_url); - mMediaLoader.displayProfileBanner(mProfileBannerView, user.profile_banner_url, width); + mProfileBannerView.setTag(bannerUrl); + mMediaLoader.displayProfileBanner(mProfileBannerView, bannerUrl, width); } final UserRelationship relationship = mRelationship; if (relationship == null) { @@ -646,9 +647,9 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener } @Subscribe - public void notifyFriendshipUserUpdated(FriendshipUserUpdatedEvent event) { + public void notifyFriendshipUserUpdated(FriendshipTaskEvent event) { final ParcelableUser user = getUser(); - if (user == null || !event.user.equals(user)) return; + if (user == null || !event.isSucceeded() || !event.isUser(user)) return; getFriendship(); } @@ -661,7 +662,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener @Subscribe public void notifyTaskStateChanged(TaskStateChangedEvent event) { - updateRefreshState(); + invalidateOptionsMenu(); } @Override @@ -977,7 +978,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener case R.id.block: { if (userRelationship == null) return true; if (userRelationship.relationship.isSourceBlockingTarget()) { - twitter.destroyBlockAsync(user.account_key, user.key.getId()); + twitter.destroyBlockAsync(user.account_key, user.key); } else { CreateUserBlockDialogFragment.show(getFragmentManager(), user); } @@ -1004,7 +1005,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener case R.id.mute_user: { if (userRelationship == null) return true; if (userRelationship.relationship.isSourceMutingTarget()) { - twitter.destroyMuteAsync(user.account_key, user.key.getId()); + twitter.destroyMuteAsync(user.account_key, user.key); } else { CreateUserMuteDialogFragment.show(getFragmentManager(), user); } @@ -1066,15 +1067,13 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener case R.id.follow: { if (userRelationship == null) return true; final boolean isFollowing = userRelationship.relationship.isSourceFollowingTarget(); - final boolean isCreatingFriendship = twitter.isCreatingFriendship(user.account_key, - user.key.getId()); - final boolean isDestroyingFriendship = twitter.isDestroyingFriendship(user.account_key, - user.key.getId()); - if (!isCreatingFriendship && !isDestroyingFriendship) { + final boolean updatingRelationship = twitter.isUpdatingRelationship(user.account_key, + user.key); + if (!updatingRelationship) { if (isFollowing) { DestroyFriendshipDialogFragment.show(getFragmentManager(), user); } else { - twitter.createFriendshipAsync(user.account_key, user.key.getId()); + twitter.createFriendshipAsync(user.account_key, user.key); } } return true; @@ -1293,11 +1292,11 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener final AsyncTwitterWrapper twitter = mTwitterWrapper; if (userRelationship == null || twitter == null) return; if (userRelationship.relationship.isSourceBlockingTarget()) { - twitter.destroyBlockAsync(user.account_key, user.key.getId()); + twitter.destroyBlockAsync(user.account_key, user.key); } else if (userRelationship.relationship.isSourceFollowingTarget()) { DestroyFriendshipDialogFragment.show(getFragmentManager(), user); } else { - twitter.createFriendshipAsync(user.account_key, user.key.getId()); + twitter.createFriendshipAsync(user.account_key, user.key); } break; } @@ -1310,8 +1309,10 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener break; } case R.id.profile_banner: { - if (user.profile_banner_url == null) return; - final String url = user.profile_banner_url + "/ipad_retina"; + final String bannerUrl = ParcelableUserUtils.getProfileBannerUrl(user); + if (bannerUrl == null) return; + final String url = InternalTwitterContentUtils.getBestBannerUrl(bannerUrl, + Integer.MAX_VALUE); ParcelableMedia profileBanner = ParcelableMediaUtils.image(url); profileBanner.type = ParcelableMedia.Type.IMAGE; final ParcelableMedia[] media = {profileBanner}; @@ -1564,11 +1565,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener final LoaderManager lm = getLoaderManager(); final boolean loadingRelationship = lm.getLoader(LOADER_ID_FRIENDSHIP) != null; final UserKey accountKey = user.account_key; - final boolean creatingFriendship = twitter.isCreatingFriendship(accountKey, user.key.getId()); - final boolean destroyingFriendship = twitter.isDestroyingFriendship(accountKey, user.key.getId()); - final boolean creatingBlock = twitter.isCreatingFriendship(accountKey, user.key.getId()); - final boolean destroyingBlock = twitter.isDestroyingFriendship(accountKey, user.key.getId()); - if (loadingRelationship || creatingFriendship || destroyingFriendship || creatingBlock || destroyingBlock) { + final boolean updatingRelationship = twitter.isUpdatingRelationship(accountKey, user.key); + if (loadingRelationship || updatingRelationship) { mFollowButton.setVisibility(View.GONE); mFollowProgress.setVisibility(View.VISIBLE); } else if (mRelationship != null) { @@ -1580,17 +1578,6 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener } } - private void updateRefreshState() { - final ParcelableUser user = getUser(); - final AsyncTwitterWrapper twitter = mTwitterWrapper; - if (user == null || twitter == null) return; - final UserKey accountKey = user.account_key; - final boolean isCreatingFriendship = twitter.isCreatingFriendship(accountKey, user.key.getId()); - final boolean destroyingFriendship = twitter.isDestroyingFriendship(accountKey, user.key.getId()); - setProgressBarIndeterminateVisibility(isCreatingFriendship || destroyingFriendship); - invalidateOptionsMenu(); - } - private void updateScrollOffset(int offset) { final View space = mProfileBannerSpace; final ProfileBannerImageView profileBannerView = mProfileBannerView; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFriendsFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFriendsFragment.java index 876c8d430..570c60147 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFriendsFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFriendsFragment.java @@ -26,6 +26,7 @@ import android.support.annotation.NonNull; import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader; import org.mariotaku.twidere.loader.support.UserFriendsLoader; import org.mariotaku.twidere.model.UserKey; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; public class UserFriendsFragment extends CursorSupportUsersListFragment { @@ -38,7 +39,19 @@ public class UserFriendsFragment extends CursorSupportUsersListFragment { final UserFriendsLoader loader = new UserFriendsLoader(context, accountKey, userId, screenName, getData(), fromUser); loader.setCursor(getNextCursor()); + loader.setPage(getNextPage()); return loader; } + @Override + protected boolean shouldRemoveUser(int position, FriendshipTaskEvent event) { + if (!event.isSucceeded()) return false; + switch (event.getAction()) { + case FriendshipTaskEvent.Action.UNFOLLOW: + case FriendshipTaskEvent.Action.BLOCK: { + return true; + } + } + return false; + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java index 316837f32..1d197f9f6 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java @@ -363,7 +363,6 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList @Override public Loader> onCreateLoader(final int id, final Bundle args) { - setProgressBarIndeterminateVisibility(true); final UserKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY); final String userId = args.getString(EXTRA_USER_ID); final long listId = args.getLong(EXTRA_LIST_ID, -1); @@ -384,7 +383,6 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList displayUserList(list); } else if (data.hasException()) { } - setProgressBarIndeterminateVisibility(false); } @Override diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListMembersFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListMembersFragment.java index ecfa8551c..2126a60b2 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListMembersFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListMembersFragment.java @@ -70,6 +70,7 @@ public class UserListMembersFragment extends CursorSupportUsersListFragment { final UserListMembersLoader loader = new UserListMembersLoader(context, accountId, listId, userId, screenName, listName, getData(), fromUser); loader.setCursor(getNextCursor()); + loader.setPage(getNextPage()); return loader; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListSubscribersFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListSubscribersFragment.java index 6ba5faf7d..e6a8992c4 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListSubscribersFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListSubscribersFragment.java @@ -40,6 +40,7 @@ public class UserListSubscribersFragment extends CursorSupportUsersListFragment final UserListSubscribersLoader loader = new UserListSubscribersLoader(context, accountKey, listId, userId, screenName, listName, getData(), fromUser); loader.setCursor(getNextCursor()); + loader.setPage(getNextPage()); return loader; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java index 35bd284e0..b1003b277 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java @@ -63,7 +63,7 @@ import org.mariotaku.twidere.model.SingleResponse; import org.mariotaku.twidere.model.UserKey; import org.mariotaku.twidere.model.util.ParcelableUserUtils; import org.mariotaku.twidere.util.AsyncTaskUtils; -import org.mariotaku.twidere.util.AsyncTwitterWrapper.UpdateProfileBannerImageTask; +import org.mariotaku.twidere.task.UpdateProfileBannerImageTask; import org.mariotaku.twidere.util.AsyncTwitterWrapper.UpdateProfileImageTask; import org.mariotaku.twidere.util.HtmlEscapeHelper; import org.mariotaku.twidere.util.KeyboardShortcutsHandler; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/card/CardPollFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/card/CardPollFragment.java index f1898e03c..7c165a4b1 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/card/CardPollFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/card/CardPollFragment.java @@ -169,7 +169,7 @@ public class CardPollFragment extends BaseSupportFragment implements = new AbstractTask() { @Override - public void afterExecute(CardPollFragment handler, ParcelableCardEntity result) { + public void afterExecute(CardPollFragment handler, CardDataMap params, ParcelableCardEntity result) { handler.displayAndReloadPoll(result, status); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/CursorSupportUsersLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/CursorSupportUsersLoader.java index 9a6569b02..9a3a14c8e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/CursorSupportUsersLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/CursorSupportUsersLoader.java @@ -90,6 +90,13 @@ public abstract class CursorSupportUsersLoader extends TwitterAPIUsersLoader if (cursor == null) return; mNextCursor = cursor.getNextCursor(); mPrevCursor = cursor.getPreviousCursor(); + } + + protected final void incrementPage(ResponseList users) { + if (users.isEmpty()) return; + if (mPage == -1) { + mPage = 1; + } mNextPage = mPage + 1; } @@ -122,17 +129,19 @@ public abstract class CursorSupportUsersLoader extends TwitterAPIUsersLoader } else if (getPage() > 1) { paging.setPage(getPage()); } + final ResponseList users; if (useIDs(credentials)) { final IDs ids = getIDs(twitter, credentials, paging); setCursors(ids); - return twitter.lookupUsers(ids.getIDs()); + users = twitter.lookupUsers(ids.getIDs()); } else { - final List users = getCursoredUsers(twitter, credentials, paging); + users = getCursoredUsers(twitter, credentials, paging); if (users instanceof CursorSupport) { setCursors(((CursorSupport) users)); } - return users; } + incrementPage(users); + return users; } protected boolean useIDs(@NonNull ParcelableCredentials credentials) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/IncomingFriendshipsLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/IncomingFriendshipsLoader.java index 7215e407e..ce0003cf9 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/IncomingFriendshipsLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/IncomingFriendshipsLoader.java @@ -26,9 +26,13 @@ import org.mariotaku.twidere.api.twitter.Twitter; import org.mariotaku.twidere.api.twitter.TwitterException; import org.mariotaku.twidere.api.twitter.model.IDs; import org.mariotaku.twidere.api.twitter.model.Paging; +import org.mariotaku.twidere.api.twitter.model.ResponseList; +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.ParcelableCredentials; -import org.mariotaku.twidere.model.UserKey; import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.UserKey; +import org.mariotaku.twidere.model.util.ParcelableAccountUtils; import java.util.List; @@ -45,8 +49,19 @@ public class IncomingFriendshipsLoader extends CursorSupportUsersLoader { return twitter.getIncomingFriendships(paging); } + @NonNull + @Override + protected ResponseList getCursoredUsers(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, @NonNull Paging paging) throws TwitterException { + return twitter.getFriendshipsRequests(paging); + } + @Override protected boolean useIDs(@NonNull ParcelableCredentials credentials) { + switch (ParcelableAccountUtils.getAccountType(credentials)) { + case ParcelableAccount.Type.FANFOU: { + return false; + } + } return true; } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/message/FollowRequestTaskEvent.java b/twidere/src/main/java/org/mariotaku/twidere/model/message/FollowRequestTaskEvent.java deleted file mode 100644 index f521ccc58..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/model/message/FollowRequestTaskEvent.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.mariotaku.twidere.model.message; - -import android.support.annotation.IntDef; - -import org.mariotaku.twidere.model.UserKey; - -/** - * Created by mariotaku on 16/2/15. - */ -public class FollowRequestTaskEvent { - - @Action - private int action; - private boolean finished; - private boolean succeeded; - private UserKey mAccountKey; - private String userId; - - public FollowRequestTaskEvent(@Action int action, UserKey accountKey, String userId) { - this.action = action; - this.mAccountKey = accountKey; - this.userId = userId; - } - - @Action - public int getAction() { - return action; - } - - public boolean isFinished() { - return finished; - } - - public void setFinished(boolean finished) { - this.finished = finished; - } - - public UserKey getAccountKey() { - return mAccountKey; - } - - public String getUserId() { - return userId; - } - - public boolean isSucceeded() { - return succeeded; - } - - public void setSucceeded(boolean succeeded) { - this.succeeded = succeeded; - } - - @Override - public String toString() { - return "FollowRequestTaskEvent{" + - "action=" + action + - ", finished=" + finished + - ", mAccountKey=" + mAccountKey + - ", userId=" + userId + - '}'; - } - - @IntDef({Action.ACCEPT, Action.DENY}) - public @interface Action { - int ACCEPT = 1; - int DENY = 2; - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/message/FriendshipTaskEvent.java b/twidere/src/main/java/org/mariotaku/twidere/model/message/FriendshipTaskEvent.java new file mode 100644 index 000000000..a2b982969 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/model/message/FriendshipTaskEvent.java @@ -0,0 +1,95 @@ +package org.mariotaku.twidere.model.message; + +import android.support.annotation.IntDef; +import android.support.annotation.NonNull; + +import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.UserKey; + +/** + * Created by mariotaku on 16/2/15. + */ +public class FriendshipTaskEvent { + + @Action + private int action; + private boolean finished; + private boolean succeeded; + @NonNull + private UserKey accountKey; + @NonNull + private UserKey userKey; + private ParcelableUser user; + + public FriendshipTaskEvent(@Action int action, @NonNull UserKey accountKey, @NonNull UserKey userKey) { + this.action = action; + this.accountKey = accountKey; + this.userKey = userKey; + } + + @Action + public int getAction() { + return action; + } + + public boolean isFinished() { + return finished; + } + + public void setFinished(boolean finished) { + this.finished = finished; + } + + @NonNull + public UserKey getAccountKey() { + return accountKey; + } + + @NonNull + public UserKey getUserKey() { + return userKey; + } + + public boolean isSucceeded() { + return succeeded; + } + + public void setSucceeded(boolean succeeded) { + this.succeeded = succeeded; + } + + public ParcelableUser getUser() { + return user; + } + + public void setUser(ParcelableUser user) { + this.user = user; + } + + public final boolean isUser(@NonNull ParcelableUser user) { + return userKey.equals(user.key); + } + + @Override + public String toString() { + return "FriendshipTaskEvent{" + + "action=" + action + + ", finished=" + finished + + ", mAccountKey=" + accountKey + + ", userId=" + userKey + + '}'; + } + + @IntDef({Action.ACCEPT, Action.DENY, Action.FOLLOW, Action.UNFOLLOW, Action.BLOCK, + Action.UNBLOCK, Action.MUTE, Action.UNMUTE}) + public @interface Action { + int ACCEPT = 1; + int DENY = 2; + int FOLLOW = 3; + int UNFOLLOW = 4; + int BLOCK = 5; + int UNBLOCK = 6; + int MUTE = 7; + int UNMUTE = 8; + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/message/FriendshipUserUpdatedEvent.java b/twidere/src/main/java/org/mariotaku/twidere/model/message/FriendshipUserUpdatedEvent.java deleted file mode 100644 index 7d0f8023c..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/model/message/FriendshipUserUpdatedEvent.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.model.message; - -import android.support.annotation.NonNull; - -import org.mariotaku.twidere.model.ParcelableUser; - -/** - * Created by mariotaku on 14/12/7. - */ -public class FriendshipUserUpdatedEvent { - - @NonNull - public final ParcelableUser user; - - public FriendshipUserUpdatedEvent(@NonNull ParcelableUser user) { - this.user = user; - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableAccountUtils.java b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableAccountUtils.java index 4814f68b7..de723b651 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableAccountUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableAccountUtils.java @@ -8,9 +8,9 @@ import android.support.annotation.Nullable; import org.mariotaku.sqliteqb.library.ArgsArray; import org.mariotaku.sqliteqb.library.Columns; import org.mariotaku.sqliteqb.library.Expression; -import org.mariotaku.twidere.model.UserKey; import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.ParcelableAccountCursorIndices; +import org.mariotaku.twidere.model.UserKey; import org.mariotaku.twidere.provider.TwidereDataStore.Accounts; import org.mariotaku.twidere.util.DataStoreUtils; import org.mariotaku.twidere.util.TwidereArrayUtils; @@ -96,7 +96,7 @@ public class ParcelableAccountUtils { @NonNull @ParcelableAccount.Type - public static String getAccountType(ParcelableAccount account) { + public static String getAccountType(@NonNull ParcelableAccount account) { if (account.account_type == null) return ParcelableAccount.Type.TWITTER; return account.account_type; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableUserUtils.java b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableUserUtils.java index afeacfe9b..2ee200d84 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableUserUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableUserUtils.java @@ -3,6 +3,7 @@ package org.mariotaku.twidere.model.util; import android.database.Cursor; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.text.TextUtils; import org.mariotaku.twidere.TwidereConstants; import org.mariotaku.twidere.api.twitter.model.UrlEntity; @@ -44,6 +45,10 @@ public class ParcelableUserUtils implements TwidereConstants { obj.location = user.getLocation(); obj.profile_image_url = TwitterContentUtils.getProfileImageUrl(user); obj.profile_banner_url = user.getProfileBannerImageUrl(); + obj.profile_background_url = user.getProfileBackgroundImageUrlHttps(); + if (TextUtils.isEmpty(obj.profile_background_url)) { + obj.profile_background_url = user.getProfileBackgroundImageUrl(); + } obj.url = user.getUrl(); if (obj.url != null && urlEntities != null && urlEntities.length > 0) { obj.url_expanded = urlEntities[0].getExpandedUrl(); @@ -56,9 +61,9 @@ public class ParcelableUserUtils implements TwidereConstants { obj.listed_count = user.getListedCount(); obj.media_count = user.getMediaCount(); obj.is_following = user.isFollowing(); - obj.background_color = ParseUtils.parseColor("#" + user.getProfileBackgroundColor(), 0); - obj.link_color = ParseUtils.parseColor("#" + user.getProfileLinkColor(), 0); - obj.text_color = ParseUtils.parseColor("#" + user.getProfileTextColor(), 0); + obj.background_color = parseColor(user.getProfileBackgroundColor()); + obj.link_color = parseColor(user.getProfileLinkColor()); + obj.text_color = parseColor(user.getProfileTextColor()); obj.is_cache = false; obj.is_basic = false; @@ -93,4 +98,21 @@ public class ParcelableUserUtils implements TwidereConstants { } return result; } + + private static int parseColor(@Nullable String colorString) { + if (colorString == null) return 0; + if (!colorString.startsWith("#")) { + colorString = "#" + colorString; + } + return ParseUtils.parseColor(colorString, 0); + } + + @Nullable + public static String getProfileBannerUrl(@NonNull ParcelableUser user) { + if (!TextUtils.isEmpty(user.profile_banner_url)) return user.profile_banner_url; + if (USER_TYPE_FANFOU_COM.equals(user.key.getHost())) { + return user.profile_background_url; + } + return null; + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/AbsFriendshipOperationTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/AbsFriendshipOperationTask.java new file mode 100644 index 000000000..024e21612 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/task/AbsFriendshipOperationTask.java @@ -0,0 +1,126 @@ +package org.mariotaku.twidere.task; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.squareup.otto.Bus; + +import org.mariotaku.twidere.Constants; +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.ParcelableCredentials; +import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.SingleResponse; +import org.mariotaku.twidere.model.UserKey; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; +import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils; +import org.mariotaku.twidere.model.util.ParcelableUserUtils; +import org.mariotaku.twidere.util.AsyncTwitterWrapper; +import org.mariotaku.twidere.util.SharedPreferencesWrapper; +import org.mariotaku.twidere.util.TwitterAPIFactory; +import org.mariotaku.twidere.util.UserColorNameManager; +import org.mariotaku.twidere.util.dagger.GeneralComponentHelper; + +import javax.inject.Inject; + +/** + * Created by mariotaku on 16/3/11. + */ +public abstract class AbsFriendshipOperationTask extends AbstractTask, Object> implements Constants { + + protected final Context context; + @FriendshipTaskEvent.Action + protected final int action; + @Inject + protected Bus bus; + @Inject + protected AsyncTwitterWrapper twitter; + @Inject + protected SharedPreferencesWrapper preferences; + @Inject + protected UserColorNameManager manager; + + public AbsFriendshipOperationTask(Context context, @FriendshipTaskEvent.Action int action) { + this.context = context; + this.action = action; + GeneralComponentHelper.build(context).inject(this); + } + + + @Override + protected final void beforeExecute(Arguments params) { + twitter.addUpdatingRelationshipId(params.accountKey, params.userKey); + final FriendshipTaskEvent event = new FriendshipTaskEvent(action, params.accountKey, + params.userKey); + event.setFinished(false); + bus.post(event); + } + + @Override + protected final void afterExecute(Arguments params, SingleResponse result) { + twitter.removeUpdatingRelationshipId(params.accountKey, params.userKey); + final FriendshipTaskEvent event = new FriendshipTaskEvent(action, params.accountKey, + params.userKey); + event.setFinished(true); + if (result.hasData()) { + final ParcelableUser user = result.getData(); + showSucceededMessage(params, user); + event.setSucceeded(true); + event.setUser(result.getData()); + } else { + showErrorMessage(params, result.getException()); + } + bus.post(event); + } + + @Override + public final SingleResponse doLongOperation(final Arguments args) { + final ParcelableCredentials credentials = ParcelableCredentialsUtils.getCredentials(context, + args.accountKey); + if (credentials == null) return SingleResponse.getInstance(); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, credentials, false, false); + if (twitter == null) return SingleResponse.getInstance(); + try { + final User user = perform(twitter, credentials, args); + final ParcelableUser parcelableUser = ParcelableUserUtils.fromUser(user, args.accountKey); + succeededWorker(twitter, credentials, args, parcelableUser); + return SingleResponse.getInstance(parcelableUser, null); + } catch (final TwitterException e) { + return SingleResponse.getInstance(null, e); + } + } + + @NonNull + protected abstract User perform(@NonNull Twitter twitter, + @NonNull ParcelableCredentials credentials, + @NonNull Arguments args) throws TwitterException; + + protected abstract void succeededWorker(@NonNull Twitter twitter, + @NonNull ParcelableCredentials credentials, + @NonNull Arguments args, + @NonNull ParcelableUser user); + + protected abstract void showSucceededMessage(@NonNull Arguments params, @NonNull ParcelableUser user); + + protected abstract void showErrorMessage(@NonNull Arguments params, @Nullable Exception exception); + + public final void setup(@NonNull UserKey accountKey, @NonNull UserKey userKey) { + setParams(new Arguments(accountKey, userKey)); + } + + protected static class Arguments { + @NonNull + protected final UserKey accountKey; + @NonNull + protected final UserKey userKey; + + protected Arguments(@NonNull UserKey accountKey, @NonNull UserKey userKey) { + this.accountKey = accountKey; + this.userKey = userKey; + } + } + +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/AbstractTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/AbstractTask.java index 068fa46d3..f96df7568 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/task/AbstractTask.java +++ b/twidere/src/main/java/org/mariotaku/twidere/task/AbstractTask.java @@ -16,17 +16,17 @@ public abstract class AbstractTask { protected abstract Result doLongOperation(Params params); @MainThread - protected void beforeExecute() { + protected void beforeExecute(Params params) { } @MainThread - protected void afterExecute(Result result) { + protected void afterExecute(Params params, Result result) { } @MainThread - protected void afterExecute(Callback callback, Result result) { + protected void afterExecute(Callback callback, Params params, Result result) { } @@ -42,9 +42,9 @@ public abstract class AbstractTask { @MainThread public void invokeAfterExecute(Result result) { if (mCallback != null) { - afterExecute(mCallback, result); + afterExecute(mCallback, mParams, result); } else { - afterExecute(result); + afterExecute(mParams, result); } } @@ -53,6 +53,6 @@ public abstract class AbstractTask { } public void invokeBeforeExecute() { - beforeExecute(); + beforeExecute(mParams); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/AcceptFriendshipTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/AcceptFriendshipTask.java new file mode 100644 index 000000000..2ae641bc2 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/task/AcceptFriendshipTask.java @@ -0,0 +1,56 @@ +package org.mariotaku.twidere.task; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import org.mariotaku.twidere.R; +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableCredentials; +import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; +import org.mariotaku.twidere.model.util.ParcelableAccountUtils; +import org.mariotaku.twidere.util.Utils; + +/** + * Created by mariotaku on 16/3/11. + */ +public class AcceptFriendshipTask extends AbsFriendshipOperationTask { + + public AcceptFriendshipTask(final Context context) { + super(context, FriendshipTaskEvent.Action.ACCEPT); + } + + @NonNull + @Override + protected User perform(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, @NonNull Arguments args) throws TwitterException { + switch (ParcelableAccountUtils.getAccountType(credentials)) { + case ParcelableAccount.Type.FANFOU: { + return twitter.acceptFanfouFriendship(args.userKey.getId()); + } + } + return twitter.acceptFriendship(args.userKey.getId()); + } + + @Override + protected void succeededWorker(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, @NonNull Arguments args, @NonNull ParcelableUser user) { + Utils.setLastSeen(context, user.key, System.currentTimeMillis()); + } + + @Override + protected void showErrorMessage(@NonNull Arguments params, @Nullable Exception exception) { + Utils.showErrorMessage(context, R.string.action_accepting_follow_request, exception, false); + } + + @Override + protected void showSucceededMessage(@NonNull Arguments params, @NonNull ParcelableUser user) { + final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST); + final String message = context.getString(R.string.accepted_users_follow_request, + manager.getDisplayName(user, nameFirst, true)); + Utils.showOkMessage(context, message, false); + } + +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/CreateFriendshipTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/CreateFriendshipTask.java new file mode 100644 index 000000000..f8415a2c8 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/task/CreateFriendshipTask.java @@ -0,0 +1,73 @@ +package org.mariotaku.twidere.task; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.TextUtils; + +import org.mariotaku.twidere.R; +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableCredentials; +import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; +import org.mariotaku.twidere.model.util.ParcelableAccountUtils; +import org.mariotaku.twidere.util.Utils; + +/** + * Created by mariotaku on 16/3/11. + */ +public class CreateFriendshipTask extends AbsFriendshipOperationTask { + + public CreateFriendshipTask(final Context context) { + super(context, FriendshipTaskEvent.Action.FOLLOW); + } + + @NonNull + @Override + protected User perform(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, @NonNull Arguments args) throws TwitterException { + switch (ParcelableAccountUtils.getAccountType(credentials)) { + case ParcelableAccount.Type.FANFOU: { + return twitter.createFanfouFriendship(args.userKey.getId()); + } + } + return twitter.createFriendship(args.userKey.getId()); + } + + @Override + protected void succeededWorker(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, @NonNull Arguments args, @NonNull ParcelableUser user) { + Utils.setLastSeen(context, user.key, System.currentTimeMillis()); + } + + @Override + protected void showErrorMessage(@NonNull Arguments params, @Nullable Exception exception) { + if (USER_TYPE_FANFOU_COM.equals(params.accountKey.getHost())) { + // Fanfou returns 403 for follow request + if (exception instanceof TwitterException) { + TwitterException te = (TwitterException) exception; + if (te.getStatusCode() == 403 && !TextUtils.isEmpty(te.getErrorMessage())) { + Utils.showErrorMessage(context, te.getErrorMessage(), false); + return; + } + } + } + Utils.showErrorMessage(context, R.string.action_following, exception, false); + } + + @Override + protected void showSucceededMessage(@NonNull Arguments params, @NonNull ParcelableUser user) { + final String message; + final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST); + if (user.is_protected) { + message = context.getString(R.string.sent_follow_request_to_user, + manager.getDisplayName(user, nameFirst, true)); + } else { + message = context.getString(R.string.followed_user, + manager.getDisplayName(user, nameFirst, true)); + } + Utils.showOkMessage(context, message, false); + } + +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/CreateUserBlockTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/CreateUserBlockTask.java new file mode 100644 index 000000000..d7f838688 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/task/CreateUserBlockTask.java @@ -0,0 +1,82 @@ +package org.mariotaku.twidere.task; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.net.Uri; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import org.mariotaku.sqliteqb.library.Expression; +import org.mariotaku.twidere.R; +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableCredentials; +import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; +import org.mariotaku.twidere.model.util.ParcelableAccountUtils; +import org.mariotaku.twidere.provider.TwidereDataStore; +import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships; +import org.mariotaku.twidere.util.Utils; + +/** + * Created by mariotaku on 16/3/11. + */ +public class CreateUserBlockTask extends AbsFriendshipOperationTask { + public CreateUserBlockTask(Context context) { + super(context, FriendshipTaskEvent.Action.BLOCK); + } + + @NonNull + @Override + protected User perform(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, + @NonNull Arguments args) throws TwitterException { + switch (ParcelableAccountUtils.getAccountType(credentials)) { + case ParcelableAccount.Type.FANFOU: { + return twitter.createFanfouBlock(args.userKey.getId()); + } + } + return twitter.createBlock(args.userKey.getId()); + } + + @Override + protected void succeededWorker(@NonNull Twitter twitter, + @NonNull ParcelableCredentials credentials, + @NonNull Arguments args, @NonNull ParcelableUser user) { + final ContentResolver resolver = context.getContentResolver(); + Utils.setLastSeen(context, args.userKey, -1); + for (final Uri uri : TwidereDataStore.STATUSES_URIS) { + final Expression where = Expression.and( + Expression.equalsArgs(TwidereDataStore.AccountSupportColumns.ACCOUNT_KEY), + Expression.equalsArgs(TwidereDataStore.Statuses.USER_ID) + ); + final String[] whereArgs = {args.accountKey.toString(), args.userKey.toString()}; + resolver.delete(uri, where.getSQL(), whereArgs); + + } + // I bet you don't want to see this user in your auto complete list. + final ContentValues values = new ContentValues(); + values.put(CachedRelationships.ACCOUNT_KEY, args.accountKey.toString()); + values.put(CachedRelationships.USER_ID, args.userKey.toString()); + values.put(CachedRelationships.BLOCKING, true); + values.put(CachedRelationships.FOLLOWING, false); + values.put(CachedRelationships.FOLLOWED_BY, false); + resolver.insert(CachedRelationships.CONTENT_URI, values); + } + + @Override + protected void showSucceededMessage(@NonNull Arguments params, @NonNull ParcelableUser user) { + final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST); + final String message = context.getString(R.string.blocked_user, manager.getDisplayName(user, + nameFirst, true)); + Utils.showInfoMessage(context, message, false); + + } + + @Override + protected void showErrorMessage(@NonNull Arguments params, @Nullable Exception exception) { + Utils.showErrorMessage(context, R.string.action_blocking, exception, true); + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/CreateUserMuteTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/CreateUserMuteTask.java new file mode 100644 index 000000000..0253095d9 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/task/CreateUserMuteTask.java @@ -0,0 +1,74 @@ +package org.mariotaku.twidere.task; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.net.Uri; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import org.mariotaku.sqliteqb.library.Expression; +import org.mariotaku.twidere.R; +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.ParcelableCredentials; +import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; +import org.mariotaku.twidere.provider.TwidereDataStore; +import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships; +import org.mariotaku.twidere.provider.TwidereDataStore.Statuses; +import org.mariotaku.twidere.util.Utils; + +/** + * Created by mariotaku on 16/3/11. + */ +public class CreateUserMuteTask extends AbsFriendshipOperationTask { + public CreateUserMuteTask(Context context) { + super(context, FriendshipTaskEvent.Action.MUTE); + } + + @NonNull + @Override + protected User perform(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, + @NonNull Arguments args) throws TwitterException { + return twitter.createMute(args.userKey.getId()); + } + + @Override + protected void succeededWorker(@NonNull Twitter twitter, + @NonNull ParcelableCredentials credentials, + @NonNull Arguments args, @NonNull ParcelableUser user) { + final ContentResolver resolver = context.getContentResolver(); + Utils.setLastSeen(context, args.userKey, -1); + for (final Uri uri : TwidereDataStore.STATUSES_URIS) { + final Expression where = Expression.and( + Expression.equalsArgs(Statuses.ACCOUNT_KEY), + Expression.equalsArgs(Statuses.USER_ID) + ); + final String[] whereArgs = {args.accountKey.toString(), args.userKey.toString()}; + resolver.delete(uri, where.getSQL(), whereArgs); + + } + // I bet you don't want to see this user in your auto complete list. + final ContentValues values = new ContentValues(); + values.put(CachedRelationships.ACCOUNT_KEY, args.accountKey.toString()); + values.put(CachedRelationships.USER_ID, args.userKey.toString()); + values.put(CachedRelationships.MUTING, true); + resolver.insert(CachedRelationships.CONTENT_URI, values); + } + + @Override + protected void showSucceededMessage(@NonNull Arguments params, @NonNull ParcelableUser user) { + final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST); + final String message = context.getString(R.string.muted_user, manager.getDisplayName(user, + nameFirst, true)); + Utils.showInfoMessage(context, message, false); + + } + + @Override + protected void showErrorMessage(@NonNull Arguments params, @Nullable Exception exception) { + Utils.showErrorMessage(context, R.string.action_muting, exception, true); + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/DenyFriendshipTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/DenyFriendshipTask.java new file mode 100644 index 000000000..f572d27b8 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/task/DenyFriendshipTask.java @@ -0,0 +1,56 @@ +package org.mariotaku.twidere.task; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import org.mariotaku.twidere.R; +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableCredentials; +import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; +import org.mariotaku.twidere.model.util.ParcelableAccountUtils; +import org.mariotaku.twidere.util.Utils; + +/** + * Created by mariotaku on 16/3/11. + */ +public class DenyFriendshipTask extends AbsFriendshipOperationTask { + + public DenyFriendshipTask(final Context context) { + super(context, FriendshipTaskEvent.Action.DENY); + } + + @NonNull + @Override + protected User perform(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, @NonNull Arguments args) throws TwitterException { + switch (ParcelableAccountUtils.getAccountType(credentials)) { + case ParcelableAccount.Type.FANFOU: { + return twitter.denyFanfouFriendship(args.userKey.getId()); + } + } + return twitter.denyFriendship(args.userKey.getId()); + } + + @Override + protected void succeededWorker(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, @NonNull Arguments args, @NonNull ParcelableUser user) { + Utils.setLastSeen(context, user.key, -1); + } + + @Override + protected void showErrorMessage(@NonNull Arguments params, @Nullable Exception exception) { + Utils.showErrorMessage(context, R.string.action_denying_follow_request, exception, false); + } + + @Override + protected void showSucceededMessage(@NonNull Arguments params, @NonNull ParcelableUser user) { + final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST); + final String message = context.getString(R.string.denied_users_follow_request, + manager.getDisplayName(user, nameFirst, true)); + Utils.showOkMessage(context, message, false); + } + +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/DestroyFriendshipTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/DestroyFriendshipTask.java new file mode 100644 index 000000000..ec891481c --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/task/DestroyFriendshipTask.java @@ -0,0 +1,66 @@ +package org.mariotaku.twidere.task; + +import android.content.ContentResolver; +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import org.mariotaku.sqliteqb.library.Expression; +import org.mariotaku.twidere.R; +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableCredentials; +import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; +import org.mariotaku.twidere.model.util.ParcelableAccountUtils; +import org.mariotaku.twidere.provider.TwidereDataStore; +import org.mariotaku.twidere.util.Utils; + +/** + * Created by mariotaku on 16/3/11. + */ +public class DestroyFriendshipTask extends AbsFriendshipOperationTask { + + public DestroyFriendshipTask(final Context context) { + super(context, FriendshipTaskEvent.Action.UNFOLLOW); + } + + @NonNull + @Override + protected User perform(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, @NonNull Arguments args) throws TwitterException { + switch (ParcelableAccountUtils.getAccountType(credentials)) { + case ParcelableAccount.Type.FANFOU: { + return twitter.destroyFanfouFriendship(args.userKey.getId()); + } + } + return twitter.destroyFriendship(args.userKey.getId()); + } + + @Override + protected void succeededWorker(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, @NonNull Arguments args, @NonNull ParcelableUser user) { + Utils.setLastSeen(context, user.key, -1); + final Expression where = Expression.and(Expression.equalsArgs(TwidereDataStore.Statuses.ACCOUNT_KEY), + Expression.or(Expression.equalsArgs(TwidereDataStore.Statuses.USER_ID), + Expression.equalsArgs(TwidereDataStore.Statuses.RETWEETED_BY_USER_ID))); + final String[] whereArgs = {args.userKey.toString(), args.userKey.toString(), + args.userKey.toString()}; + final ContentResolver resolver = context.getContentResolver(); + resolver.delete(TwidereDataStore.Statuses.CONTENT_URI, where.getSQL(), whereArgs); + } + + @Override + protected void showErrorMessage(@NonNull Arguments params, @Nullable Exception exception) { + Utils.showErrorMessage(context, R.string.action_unfollowing, exception, false); + } + + @Override + protected void showSucceededMessage(@NonNull Arguments params, @NonNull ParcelableUser user) { + final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST); + final String message = context.getString(R.string.unfollowed_user, + manager.getDisplayName(user, nameFirst, true)); + Utils.showInfoMessage(context, message, false); + } + +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/DestroyUserBlockTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/DestroyUserBlockTask.java new file mode 100644 index 000000000..49dad0936 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/task/DestroyUserBlockTask.java @@ -0,0 +1,69 @@ +package org.mariotaku.twidere.task; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import org.mariotaku.twidere.R; +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableCredentials; +import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; +import org.mariotaku.twidere.model.util.ParcelableAccountUtils; +import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships; +import org.mariotaku.twidere.util.Utils; + +/** + * Created by mariotaku on 16/3/11. + */ +public class DestroyUserBlockTask extends AbsFriendshipOperationTask { + public DestroyUserBlockTask(Context context) { + super(context, FriendshipTaskEvent.Action.UNBLOCK); + } + + @NonNull + @Override + protected User perform(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, + @NonNull Arguments args) throws TwitterException { + switch (ParcelableAccountUtils.getAccountType(credentials)) { + case ParcelableAccount.Type.FANFOU: { + return twitter.destroyFanfouBlock(args.userKey.getId()); + } + } + return twitter.destroyBlock(args.userKey.getId()); + } + + @Override + protected void succeededWorker(@NonNull Twitter twitter, + @NonNull ParcelableCredentials credentials, + @NonNull Arguments args, @NonNull ParcelableUser user) { + final ContentResolver resolver = context.getContentResolver(); + // I bet you don't want to see this user in your auto complete list. + final ContentValues values = new ContentValues(); + values.put(CachedRelationships.ACCOUNT_KEY, args.accountKey.toString()); + values.put(CachedRelationships.USER_ID, args.userKey.toString()); + values.put(CachedRelationships.BLOCKING, false); + values.put(CachedRelationships.FOLLOWING, false); + values.put(CachedRelationships.FOLLOWED_BY, false); + resolver.insert(CachedRelationships.CONTENT_URI, values); + } + + @Override + protected void showSucceededMessage(@NonNull Arguments params, @NonNull ParcelableUser user) { + final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST); + final String message = context.getString(R.string.unblocked_user, manager.getDisplayName(user, + nameFirst, true)); + Utils.showInfoMessage(context, message, false); + + } + + @Override + protected void showErrorMessage(@NonNull Arguments params, @Nullable Exception exception) { + Utils.showErrorMessage(context, R.string.action_unblocking, exception, true); + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/DestroyUserMuteTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/DestroyUserMuteTask.java new file mode 100644 index 000000000..f76d70468 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/task/DestroyUserMuteTask.java @@ -0,0 +1,60 @@ +package org.mariotaku.twidere.task; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import org.mariotaku.twidere.R; +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.ParcelableCredentials; +import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.message.FriendshipTaskEvent; +import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships; +import org.mariotaku.twidere.util.Utils; + +/** + * Created by mariotaku on 16/3/11. + */ +public class DestroyUserMuteTask extends AbsFriendshipOperationTask { + public DestroyUserMuteTask(Context context) { + super(context, FriendshipTaskEvent.Action.UNMUTE); + } + + @NonNull + @Override + protected User perform(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, + @NonNull Arguments args) throws TwitterException { + return twitter.destroyMute(args.userKey.getId()); + } + + @Override + protected void succeededWorker(@NonNull Twitter twitter, + @NonNull ParcelableCredentials credentials, + @NonNull Arguments args, @NonNull ParcelableUser user) { + final ContentResolver resolver = context.getContentResolver(); + // I bet you don't want to see this user in your auto complete list. + final ContentValues values = new ContentValues(); + values.put(CachedRelationships.ACCOUNT_KEY, args.accountKey.toString()); + values.put(CachedRelationships.USER_ID, args.userKey.toString()); + values.put(CachedRelationships.MUTING, false); + resolver.insert(CachedRelationships.CONTENT_URI, values); + } + + @Override + protected void showSucceededMessage(@NonNull Arguments params, @NonNull ParcelableUser user) { + final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST); + final String message = context.getString(R.string.unmuted_user, manager.getDisplayName(user, + nameFirst, true)); + Utils.showInfoMessage(context, message, false); + + } + + @Override + protected void showErrorMessage(@NonNull Arguments params, @Nullable Exception exception) { + Utils.showErrorMessage(context, R.string.action_unmuting, exception, true); + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/GetActivitiesAboutMeTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/GetActivitiesAboutMeTask.java index 07896bd8a..4d9892727 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/task/GetActivitiesAboutMeTask.java +++ b/twidere/src/main/java/org/mariotaku/twidere/task/GetActivitiesAboutMeTask.java @@ -37,13 +37,18 @@ public class GetActivitiesAboutMeTask extends GetActivitiesTask { } @Override - protected void saveReadPosition(@NonNull UserKey accountId, @NonNull Twitter twitter) { - try { - CursorTimestampResponse response = twitter.getActivitiesAboutMeUnread(true); - final String tag = Utils.getReadPositionTagWithAccounts(ReadPositionTag.ACTIVITIES_ABOUT_ME, accountId); - readStateManager.setPosition(tag, response.getCursor(), false); - } catch (TwitterException e) { - // Ignore + protected void saveReadPosition(@NonNull UserKey accountId, ParcelableCredentials credentials, @NonNull Twitter twitter) { + if (ParcelableAccount.Type.TWITTER.equals(ParcelableAccountUtils.getAccountType(credentials))) { + if (Utils.isOfficialCredentials(context, credentials)) { + try { + CursorTimestampResponse response = twitter.getActivitiesAboutMeUnread(true); + final String tag = Utils.getReadPositionTagWithAccounts(ReadPositionTag.ACTIVITIES_ABOUT_ME, + accountId); + readStateManager.setPosition(tag, response.getCursor(), false); + } catch (TwitterException e) { + // Ignore + } + } } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/GetDirectMessagesTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/GetDirectMessagesTask.java index 2b9c96491..7e044a773 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/task/GetDirectMessagesTask.java +++ b/twidere/src/main/java/org/mariotaku/twidere/task/GetDirectMessagesTask.java @@ -139,12 +139,12 @@ public abstract class GetDirectMessagesTask extends AbstractTask result) { + protected void afterExecute(RefreshTaskParam params, List result) { bus.post(new GetMessagesTaskEvent(getDatabaseUri(), false, AsyncTwitterWrapper.getException(result))); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/ReportSpamAndBlockTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/ReportSpamAndBlockTask.java new file mode 100644 index 000000000..881298729 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/task/ReportSpamAndBlockTask.java @@ -0,0 +1,26 @@ +package org.mariotaku.twidere.task; + +import android.content.Context; +import android.support.annotation.NonNull; + +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.ParcelableCredentials; + +/** + * Created by mariotaku on 16/3/11. + */ +public class ReportSpamAndBlockTask extends CreateUserBlockTask { + public ReportSpamAndBlockTask(Context context) { + super(context); + } + + + @NonNull + @Override + protected User perform(@NonNull Twitter twitter, @NonNull ParcelableCredentials credentials, + @NonNull Arguments args) throws TwitterException { + return twitter.reportSpam(args.userKey.getId()); + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/UpdateProfileBannerImageTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/UpdateProfileBannerImageTask.java new file mode 100644 index 000000000..c3f2bd453 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/task/UpdateProfileBannerImageTask.java @@ -0,0 +1,74 @@ +package org.mariotaku.twidere.task; + +import android.content.Context; +import android.net.Uri; +import android.util.Log; + +import org.mariotaku.twidere.R; +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.SingleResponse; +import org.mariotaku.twidere.model.UserKey; +import org.mariotaku.twidere.model.message.ProfileUpdatedEvent; +import org.mariotaku.twidere.model.util.ParcelableUserUtils; +import org.mariotaku.twidere.util.TwitterAPIFactory; +import org.mariotaku.twidere.util.TwitterWrapper; +import org.mariotaku.twidere.util.Utils; + +import java.io.FileNotFoundException; + +/** + * Created by mariotaku on 16/3/11. + */ +public class UpdateProfileBannerImageTask extends ManagedAsyncTask> { + + private final UserKey mAccountKey; + private final Uri mImageUri; + private final boolean mDeleteImage; + private final Context mContext; + + public UpdateProfileBannerImageTask(final Context context, final UserKey accountKey, + final Uri imageUri, final boolean deleteImage) { + super(context); + mContext = context; + mAccountKey = accountKey; + mImageUri = imageUri; + mDeleteImage = deleteImage; + } + + @Override + protected void onPostExecute(final SingleResponse result) { + super.onPostExecute(result); + if (result.hasData()) { + Utils.showOkMessage(mContext, R.string.profile_banner_image_updated, false); + bus.post(new ProfileUpdatedEvent(result.getData())); + } else { + Utils.showErrorMessage(mContext, R.string.action_updating_profile_banner_image, result.getException(), + true); + } + } + + @Override + protected SingleResponse doInBackground(final Object... params) { + try { + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountKey, + true); + TwitterWrapper.updateProfileBannerImage(mContext, twitter, mImageUri, mDeleteImage); + // Wait for 5 seconds, see + // https://dev.twitter.com/docs/api/1.1/post/account/update_profile_image + try { + Thread.sleep(5000L); + } catch (InterruptedException e) { + Log.w(LOGTAG, e); + } + final User user = TwitterWrapper.tryShowUser(twitter, mAccountKey.getId(), null); + return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountKey)); + } catch (TwitterException | FileNotFoundException e) { + return SingleResponse.getInstance(e); + } + } + + +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/twitter/GetActivitiesTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/twitter/GetActivitiesTask.java index d2388746a..f21ee7e8a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/task/twitter/GetActivitiesTask.java +++ b/twidere/src/main/java/org/mariotaku/twidere/task/twitter/GetActivitiesTask.java @@ -106,7 +106,7 @@ public abstract class GetActivitiesTask extends AbstractTask activities = getActivities(twitter, credentials, paging); storeActivities(cr, loadItemLimit, accountKey, noItemsBefore, activities, sinceId, maxId); if (saveReadPosition) { - saveReadPosition(accountKey, twitter); + saveReadPosition(accountKey,credentials, twitter); } errorInfoStore.remove(getErrorInfoKey(), accountKey); } catch (TwitterException e) { @@ -180,7 +180,7 @@ public abstract class GetActivitiesTask extends AbstractTask getActivities(@NonNull final Twitter twitter, @NonNull final ParcelableCredentials credentials, @@ -188,7 +188,7 @@ public abstract class GetActivitiesTask extends AbstractTask result) { + public void afterExecute(RefreshTaskParam params, List result) { bus.post(new GetStatusesTaskEvent(getContentUri(), false, AsyncTwitterWrapper.getException(result))); } @@ -222,7 +222,7 @@ public abstract class GetStatusesTask extends AbstractTask 0 && ArrayUtils.contains(statusIds, maxId); final boolean noRowsDeleted = rowsDeleted == 0; final boolean insertGap = minIdx != -1 && (noRowsDeleted || deletedOldGap) && !noItemsBefore - && !hasIntersection && statuses.size() >= loadItemLimit; + && !hasIntersection; if (insertGap) { values[minIdx].put(Statuses.IS_GAP, true); } @@ -230,6 +230,14 @@ public abstract class GetStatusesTask extends AbstractTask> mDestroyingFavoriteIds = new CompactHashSet<>(); private Set> mCreatingRetweetIds = new CompactHashSet<>(); private Set> mDestroyingStatusIds = new CompactHashSet<>(); - private IntList mProcessingFriendshipRequestIds = new ArrayIntList(); + private IntList mUpdatingRelationshipIds = new ArrayIntList(); private final LongList mSendingDraftIds = new ArrayLongList(); @@ -135,9 +141,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { mAsyncTaskManager = asyncTaskManager; } - public int acceptFriendshipAsync(final UserKey accountKey, final UserKey userId) { - final AcceptFriendshipTask task = new AcceptFriendshipTask(mContext, accountKey, userId); - return mAsyncTaskManager.add(task, true); + public void acceptFriendshipAsync(final UserKey accountKey, final UserKey userKey) { + final AcceptFriendshipTask task = new AcceptFriendshipTask(mContext); + task.setup(accountKey, userKey); + TaskStarter.execute(task); } public void addSendingDraftId(long id) { @@ -174,9 +181,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { AsyncTaskUtils.executeTask(task); } - public int createBlockAsync(final UserKey accountKey, final String userId) { - final CreateBlockTask task = new CreateBlockTask(accountKey, userId); - return mAsyncTaskManager.add(task, true); + public void createBlockAsync(final UserKey accountKey, final UserKey userKey) { + final CreateUserBlockTask task = new CreateUserBlockTask(mContext); + task.setup(accountKey, userKey); + TaskStarter.execute(task); } public int createFavoriteAsync(final UserKey accountKey, final String statusId) { @@ -184,9 +192,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { return mAsyncTaskManager.add(task, true); } - public int createFriendshipAsync(final UserKey accountKey, final String userId) { - final CreateFriendshipTask task = new CreateFriendshipTask(accountKey, userId); - return mAsyncTaskManager.add(task, true); + public void createFriendshipAsync(final UserKey accountKey, final UserKey userKey) { + final CreateFriendshipTask task = new CreateFriendshipTask(mContext); + task.setup(accountKey, userKey); + TaskStarter.execute(task); } public int createMultiBlockAsync(final UserKey accountKey, final String[] userIds) { @@ -194,9 +203,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { return mAsyncTaskManager.add(task, true); } - public int createMuteAsync(final UserKey accountKey, final String userId) { - final CreateMuteTask task = new CreateMuteTask(accountKey, userId); - return mAsyncTaskManager.add(task, true); + public void createMuteAsync(final UserKey accountKey, final UserKey userKey) { + final CreateUserMuteTask task = new CreateUserMuteTask(mContext); + task.setup(accountKey, userKey); + TaskStarter.execute(task); } public int createSavedSearchAsync(final UserKey accountKey, final String query) { @@ -221,14 +231,16 @@ public class AsyncTwitterWrapper extends TwitterWrapper { return mAsyncTaskManager.add(task, true); } - public int denyFriendshipAsync(final UserKey accountKey, final UserKey userId) { - final DenyFriendshipTask task = new DenyFriendshipTask(mContext, accountKey, userId); - return mAsyncTaskManager.add(task, true); + public void denyFriendshipAsync(final UserKey accountKey, final UserKey userKey) { + final DenyFriendshipTask task = new DenyFriendshipTask(mContext); + task.setup(accountKey, userKey); + TaskStarter.execute(task); } - public int destroyBlockAsync(final UserKey accountKey, final String userId) { - final DestroyBlockTask task = new DestroyBlockTask(accountKey, userId); - return mAsyncTaskManager.add(task, true); + public void destroyBlockAsync(final UserKey accountKey, final UserKey userKey) { + final DestroyUserBlockTask task = new DestroyUserBlockTask(mContext); + task.setup(accountKey, userKey); + TaskStarter.execute(task); } public int destroyDirectMessageAsync(final UserKey accountKey, final String messageId) { @@ -246,14 +258,16 @@ public class AsyncTwitterWrapper extends TwitterWrapper { return mAsyncTaskManager.add(task, true); } - public int destroyFriendshipAsync(final UserKey accountKey, final String userId) { - final DestroyFriendshipTask task = new DestroyFriendshipTask(accountKey, userId); - return mAsyncTaskManager.add(task, true); + public void destroyFriendshipAsync(final UserKey accountKey, final UserKey userKey) { + final DestroyFriendshipTask task = new DestroyFriendshipTask(mContext); + task.setup(accountKey, userKey); + TaskStarter.execute(task); } - public int destroyMuteAsync(final UserKey accountKey, final String userId) { - final DestroyMuteTask task = new DestroyMuteTask(accountKey, userId); - return mAsyncTaskManager.add(task, true); + public void destroyMuteAsync(final UserKey accountKey, final UserKey userKey) { + final DestroyUserMuteTask task = new DestroyUserMuteTask(mContext); + task.setup(accountKey, userKey); + TaskStarter.execute(task); } public int destroySavedSearchAsync(final UserKey accountKey, final long searchId) { @@ -320,11 +334,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper { return mCreatingFavoriteIds.contains(Pair.create(accountId, statusId)); } - public boolean isCreatingFriendship(final UserKey accountKey, final String userId) { - // TODO implementation - return false; - } - public boolean isCreatingRetweet(final UserKey accountKey, final String statusId) { return mCreatingRetweetIds.contains(Pair.create(accountKey, statusId)); } @@ -333,19 +342,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper { return mDestroyingFavoriteIds.contains(Pair.create(accountKey, statusId)); } - public boolean isDestroyingFriendship(final UserKey accountKey, final String userId) { - for (final ManagedAsyncTask task : mAsyncTaskManager.getTaskSpecList()) { - if (task instanceof DestroyFriendshipTask) { - final DestroyFriendshipTask destroyFriendshipTask = (DestroyFriendshipTask) task; - if (destroyFriendshipTask.getStatus() == AsyncTask.Status.RUNNING - && destroyFriendshipTask.getAccountKey().equals(accountKey) - && destroyFriendshipTask.getUserId().equals(userId)) - return true; - } - } - return false; - } - public boolean isDestroyingStatus(final UserKey accountId, final String statusId) { return mDestroyingStatusIds.contains(Pair.create(accountId, statusId)); } @@ -449,9 +445,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { // TODO implementation } - public int reportSpamAsync(final UserKey accountKey, final String userId) { - final ReportSpamTask task = new ReportSpamTask(accountKey, userId); - return mAsyncTaskManager.add(task, true); + public void reportSpamAsync(final UserKey accountKey, final UserKey userKey) { + final ReportSpamAndBlockTask task = new ReportSpamAndBlockTask(mContext); + task.setup(accountKey, userKey); + TaskStarter.execute(task); } public int retweetStatusAsync(final UserKey accountKey, final String statusId) { @@ -500,7 +497,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } @Override - public void afterExecute(Bus handler, SingleResponse result) { + public void afterExecute(Bus handler, Object params, SingleResponse result) { if (result.hasData()) { handler.post(new FriendshipUpdatedEvent(accountKey, userId, result.getData())); } else if (result.hasException()) { @@ -540,67 +537,16 @@ public class AsyncTwitterWrapper extends TwitterWrapper { TaskStarter.execute(task); } - private void addProcessingFriendshipRequestId(UserKey accountKey, UserKey userId) { - mProcessingFriendshipRequestIds.add(ParcelableUser.calculateHashCode(accountKey, userId)); + public void addUpdatingRelationshipId(UserKey accountKey, UserKey userId) { + mUpdatingRelationshipIds.add(ParcelableUser.calculateHashCode(accountKey, userId)); } - private void removeProcessingFriendshipRequestId(UserKey accountKey, UserKey userId) { - mProcessingFriendshipRequestIds.removeElement(ParcelableUser.calculateHashCode(accountKey, userId)); + public void removeUpdatingRelationshipId(UserKey accountKey, UserKey userId) { + mUpdatingRelationshipIds.removeElement(ParcelableUser.calculateHashCode(accountKey, userId)); } - public boolean isProcessingFollowRequest(UserKey accountId, UserKey userId) { - return mProcessingFriendshipRequestIds.contains(ParcelableUser.calculateHashCode(accountId, userId)); - } - - public static class UpdateProfileBannerImageTask extends ManagedAsyncTask> { - - private final UserKey mAccountKey; - private final Uri mImageUri; - private final boolean mDeleteImage; - private final Context mContext; - - public UpdateProfileBannerImageTask(final Context context, final UserKey accountKey, - final Uri imageUri, final boolean deleteImage) { - super(context); - mContext = context; - mAccountKey = accountKey; - mImageUri = imageUri; - mDeleteImage = deleteImage; - } - - @Override - protected void onPostExecute(final SingleResponse result) { - super.onPostExecute(result); - if (result.hasData()) { - Utils.showOkMessage(mContext, R.string.profile_banner_image_updated, false); - bus.post(new ProfileUpdatedEvent(result.getData())); - } else { - Utils.showErrorMessage(mContext, R.string.action_updating_profile_banner_image, result.getException(), - true); - } - } - - @Override - protected SingleResponse doInBackground(final Object... params) { - try { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountKey, - true); - TwitterWrapper.updateProfileBannerImage(mContext, twitter, mImageUri, mDeleteImage); - // Wait for 5 seconds, see - // https://dev.twitter.com/docs/api/1.1/post/account/update_profile_image - try { - Thread.sleep(5000L); - } catch (InterruptedException e) { - Log.w(LOGTAG, e); - } - final User user = TwitterWrapper.tryShowUser(twitter, mAccountKey.getId(), null); - return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountKey)); - } catch (TwitterException | FileNotFoundException e) { - return SingleResponse.getInstance(e); - } - } - - + public boolean isUpdatingRelationship(UserKey accountId, UserKey userId) { + return mUpdatingRelationshipIds.contains(ParcelableUser.calculateHashCode(accountId, userId)); } public static class UpdateProfileImageTask extends ManagedAsyncTask> { @@ -651,73 +597,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } - static class AcceptFriendshipTask extends ManagedAsyncTask> { - - private final UserKey mAccountKey; - private final UserKey mUserId; - - public AcceptFriendshipTask(final Context context, final UserKey accountKey, final UserKey userId) { - super(context); - mAccountKey = accountKey; - mUserId = userId; - } - - public UserKey getAccountKey() { - return mAccountKey; - } - - public UserKey getUserId() { - return mUserId; - } - - @Override - protected void onPreExecute() { - final FollowRequestTaskEvent event = new FollowRequestTaskEvent(FollowRequestTaskEvent.Action.ACCEPT, - mAccountKey, mUserId.getId()); - event.setFinished(false); - bus.post(event); - mAsyncTwitterWrapper.addProcessingFriendshipRequestId(mAccountKey, mUserId); - super.onPreExecute(); - } - - - @Override - protected SingleResponse doInBackground(final Object... params) { - - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountKey, false); - if (twitter == null) return SingleResponse.getInstance(); - try { - final User user = twitter.acceptFriendship(mUserId.getId()); - return SingleResponse.getInstance(user, null); - } catch (final TwitterException e) { - return SingleResponse.getInstance(null, e); - } - } - - @Override - protected void onPostExecute(final SingleResponse result) { - final FollowRequestTaskEvent event = new FollowRequestTaskEvent(FollowRequestTaskEvent.Action.ACCEPT, - mAccountKey, mUserId.getId()); - event.setFinished(true); - if (result.hasData()) { - final User user = result.getData(); - final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST); - final String message = getContext().getString(R.string.accepted_users_follow_request, - mUserColorNameManager.getDisplayName(user, nameFirst, true)); - Utils.showOkMessage(getContext(), message, false); - event.setSucceeded(true); - } else { - Utils.showErrorMessage(getContext(), R.string.action_accepting_follow_request, - result.getException(), false); - event.setSucceeded(false); - } - mAsyncTwitterWrapper.removeProcessingFriendshipRequestId(mAccountKey, mUserId); - bus.post(event); - super.onPostExecute(result); - } - - } - class AddUserListMembersTask extends ManagedAsyncTask> { private final UserKey mAccountKey; @@ -807,64 +686,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } - class CreateBlockTask extends ManagedAsyncTask> { - - @NonNull - private final UserKey mAccountKey; - private final String mUserId; - - public CreateBlockTask(@NonNull final UserKey accountKey, final String userId) { - super(mContext); - this.mAccountKey = accountKey; - this.mUserId = userId; - } - - @Override - protected SingleResponse doInBackground(final Object... params) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountKey, false); - if (twitter == null) return SingleResponse.getInstance(); - try { - final User user = twitter.createBlock(mUserId); - Utils.setLastSeen(mContext, UserKeyUtils.fromUser(user), -1); - for (final Uri uri : TwidereDataStore.STATUSES_URIS) { - final Expression where = Expression.and( - Expression.equalsArgs(AccountSupportColumns.ACCOUNT_KEY), - Expression.equalsArgs(Statuses.USER_ID) - ); - final String[] whereArgs = {mAccountKey.toString(), String.valueOf(mUserId)}; - mResolver.delete(uri, where.getSQL(), whereArgs); - - } - // I bet you don't want to see this user in your auto complete list. - final ContentValues values = new ContentValues(); - values.put(CachedRelationships.ACCOUNT_KEY, mAccountKey.toString()); - values.put(CachedRelationships.USER_ID, mUserId); - values.put(CachedRelationships.BLOCKING, true); - mResolver.insert(CachedRelationships.CONTENT_URI, values); - return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountKey), null); - } catch (final TwitterException e) { - return SingleResponse.getInstance(null, e); - } - } - - @Override - protected void onPostExecute(final SingleResponse result) { - if (result.hasData()) { - final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST); - final String message = mContext.getString(R.string.blocked_user, - mUserColorNameManager.getDisplayName(result.getData(), nameFirst, true)); - Utils.showInfoMessage(mContext, message, false); - - - bus.post(new FriendshipUserUpdatedEvent(result.getData())); - } else { - Utils.showErrorMessage(mContext, R.string.action_blocking, result.getException(), true); - } - super.onPostExecute(result); - } - - } - class CreateFavoriteTask extends ManagedAsyncTask> { private final UserKey mAccountKey; @@ -881,14 +702,14 @@ public class AsyncTwitterWrapper extends TwitterWrapper { final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountKey, true); if (twitter == null) return SingleResponse.getInstance(); try { - final ParcelableStatus status = ParcelableStatusUtils.fromStatus(twitter.createFavorite(mStatusId), + final ParcelableStatus result = ParcelableStatusUtils.fromStatus(twitter.createFavorite(mStatusId), mAccountKey, false); - Utils.setLastSeen(mContext, status.mentions, System.currentTimeMillis()); + Utils.setLastSeen(mContext, result.mentions, System.currentTimeMillis()); final ContentValues values = new ContentValues(); values.put(Statuses.IS_FAVORITE, true); - values.put(Statuses.REPLY_COUNT, status.reply_count); - values.put(Statuses.RETWEET_COUNT, status.retweet_count); - values.put(Statuses.FAVORITE_COUNT, status.favorite_count); + values.put(Statuses.REPLY_COUNT, result.reply_count); + values.put(Statuses.RETWEET_COUNT, result.retweet_count); + values.put(Statuses.FAVORITE_COUNT, result.favorite_count); final Expression where = Expression.and( Expression.equalsArgs(AccountSupportColumns.ACCOUNT_KEY), Expression.or( @@ -901,7 +722,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { for (final Uri uri : TwidereDataStore.STATUSES_URIS) { mResolver.update(uri, values, where.getSQL(), whereArgs); } - return SingleResponse.getInstance(status); + return SingleResponse.getInstance(result); } catch (final TwitterException e) { if (BuildConfig.DEBUG) { Log.w(LOGTAG, e); @@ -943,64 +764,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } - class CreateFriendshipTask extends ManagedAsyncTask> { - - private final UserKey mAccountKey; - private final String mUserId; - - public CreateFriendshipTask(final UserKey accountKey, final String userId) { - super(mContext); - this.mAccountKey = accountKey; - this.mUserId = userId; - } - - public UserKey getAccountKey() { - return mAccountKey; - } - - public String getUserId() { - return mUserId; - } - - @Override - protected SingleResponse doInBackground(final Object... params) { - - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountKey, false); - if (twitter == null) return SingleResponse.getInstance(); - try { - final User user = twitter.createFriendship(mUserId); - Utils.setLastSeen(mContext, UserKeyUtils.fromUser(user), System.currentTimeMillis()); - return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountKey), null); - } catch (final TwitterException e) { - return SingleResponse.getInstance(null, e); - } - } - - @Override - protected void onPostExecute(final SingleResponse result) { - if (result.hasData()) { - final ParcelableUser user = result.getData(); - final String message; - final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST); - if (user.is_protected) { - message = mContext.getString(R.string.sent_follow_request_to_user, - mUserColorNameManager.getDisplayName(user, nameFirst, true)); - } else { - message = mContext.getString(R.string.followed_user, - mUserColorNameManager.getDisplayName(user, nameFirst, true)); - } - Utils.showOkMessage(mContext, message, false); - - - bus.post(new FriendshipUserUpdatedEvent(result.getData())); - } else { - Utils.showErrorMessage(mContext, R.string.action_following, result.getException(), false); - } - super.onPostExecute(result); - } - - } - class CreateMultiBlockTask extends ManagedAsyncTask> { private final UserKey mAccountKey; @@ -1062,53 +825,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } - class CreateMuteTask extends ManagedAsyncTask> { - - private final UserKey mAccountKey; - private final String mUserId; - - public CreateMuteTask(final UserKey accountKey, final String userId) { - super(mContext); - this.mAccountKey = accountKey; - this.mUserId = userId; - } - - @Override - protected SingleResponse doInBackground(final Object... params) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountKey, false); - if (twitter == null) return SingleResponse.getInstance(); - try { - final User user = twitter.createMute(mUserId); - Utils.setLastSeen(mContext, UserKeyUtils.fromUser(user), -1); - final Expression where = Expression.and(Expression.equalsArgs(Statuses.ACCOUNT_KEY), - Expression.equalsArgs(Statuses.USER_ID)); - final String[] whereArgs = {mAccountKey.toString(), mUserId}; - mResolver.delete(Statuses.CONTENT_URI, where.getSQL(), whereArgs); - - return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountKey), null); - } catch (final TwitterException e) { - return SingleResponse.getInstance(null, e); - } - } - - @Override - protected void onPostExecute(final SingleResponse result) { - if (result.hasData()) { - final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST); - final String message = mContext.getString(R.string.muted_user, - mUserColorNameManager.getDisplayName(result.getData(), nameFirst, true)); - Utils.showInfoMessage(mContext, message, false); - - - bus.post(new FriendshipUserUpdatedEvent(result.getData())); - } else { - Utils.showErrorMessage(mContext, R.string.action_muting, result.getException(), true); - } - super.onPostExecute(result); - } - - } - class CreateSavedSearchTask extends ManagedAsyncTask> { private final UserKey mAccountKey; @@ -1300,106 +1016,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } - class DenyFriendshipTask extends ManagedAsyncTask> { - - private final UserKey mAccountKey; - private final UserKey mUserId; - - public DenyFriendshipTask(final Context context, final UserKey accountKey, final UserKey userId) { - super(context); - mAccountKey = accountKey; - mUserId = userId; - } - - @Override - protected SingleResponse doInBackground(final Object... params) { - - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountKey, - false); - if (twitter == null) return SingleResponse.getInstance(); - try { - final User user = twitter.denyFriendship(mUserId.getId()); - return SingleResponse.getInstance(user, null); - } catch (final TwitterException e) { - return SingleResponse.getInstance(null, e); - } - } - - @Override - protected void onPreExecute() { - addProcessingFriendshipRequestId(mAccountKey, mUserId); - final FollowRequestTaskEvent event = new FollowRequestTaskEvent(FollowRequestTaskEvent.Action.ACCEPT, - mAccountKey, mUserId.getId()); - event.setFinished(false); - bus.post(event); - super.onPreExecute(); - } - - @Override - protected void onPostExecute(final SingleResponse result) { - final FollowRequestTaskEvent event = new FollowRequestTaskEvent(FollowRequestTaskEvent.Action.ACCEPT, - mAccountKey, mUserId.getId()); - event.setFinished(true); - if (result.hasData()) { - final User user = result.getData(); - final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST); - final String message = mContext.getString(R.string.denied_users_follow_request, - mUserColorNameManager.getDisplayName(user, nameFirst, true)); - Utils.showOkMessage(mContext, message, false); - event.setSucceeded(true); - } else { - Utils.showErrorMessage(mContext, R.string.action_denying_follow_request, result.getException(), false); - event.setSucceeded(false); - } - super.onPostExecute(result); - removeProcessingFriendshipRequestId(mAccountKey, mUserId); - bus.post(event); - } - - } - - class DestroyBlockTask extends ManagedAsyncTask> { - - private final UserKey mAccountKey; - private final String mUserId; - - public DestroyBlockTask(final UserKey accountKey, final String userId) { - super(mContext); - mAccountKey = accountKey; - mUserId = userId; - } - - @Override - protected SingleResponse doInBackground(final Object... params) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountKey, false); - if (twitter == null) return SingleResponse.getInstance(); - try { - final User user = twitter.destroyBlock(mUserId); - Utils.setLastSeen(mContext, UserKeyUtils.fromUser(user), -1); - return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountKey), null); - } catch (final TwitterException e) { - return SingleResponse.getInstance(null, e); - } - - } - - @Override - protected void onPostExecute(final SingleResponse result) { - if (result.hasData()) { - final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST); - final String message = mContext.getString(R.string.unblocked_user, - mUserColorNameManager.getDisplayName(result.getData(), nameFirst, true)); - Utils.showInfoMessage(mContext, message, false); - - - bus.post(new FriendshipUserUpdatedEvent(result.getData())); - } else { - Utils.showErrorMessage(mContext, R.string.action_unblocking, result.getException(), true); - } - super.onPostExecute(result); - } - - } class DestroyDirectMessageTask extends ManagedAsyncTask> { @@ -1593,111 +1209,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } - class DestroyFriendshipTask extends ManagedAsyncTask> { - - private final UserKey mAccountKey; - private final String mUserId; - - public DestroyFriendshipTask(final UserKey accountKey, final String userId) { - super(mContext); - mAccountKey = accountKey; - mUserId = userId; - } - - public UserKey getAccountKey() { - return mAccountKey; - } - - public String getUserId() { - return mUserId; - } - - @Override - protected SingleResponse doInBackground(final Object... params) { - - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountKey, false); - if (twitter != null) { - try { - final User user = twitter.destroyFriendship(mUserId); - // remove user tweets and retweets - Utils.setLastSeen(mContext, UserKeyUtils.fromUser(user), -1); - final Expression where = Expression.and( - Expression.equalsArgs(AccountSupportColumns.ACCOUNT_KEY), - Expression.or( - Expression.equalsArgs(Statuses.USER_ID), - Expression.equalsArgs(Statuses.RETWEETED_BY_USER_ID) - ) - ); - final String[] whereArgs = {mAccountKey.toString(), String.valueOf(mUserId), - String.valueOf(mUserId)}; - mResolver.delete(Statuses.CONTENT_URI, where.getSQL(), whereArgs); - return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountKey), null); - } catch (final TwitterException e) { - return SingleResponse.getInstance(null, e); - } - } - return SingleResponse.getInstance(); - } - - @Override - protected void onPostExecute(final SingleResponse result) { - if (result.hasData()) { - final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST); - final String message = mContext.getString(R.string.unfollowed_user, - mUserColorNameManager.getDisplayName(result.getData(), nameFirst, true)); - Utils.showInfoMessage(mContext, message, false); - bus.post(new FriendshipUserUpdatedEvent(result.getData())); - } else { - Utils.showErrorMessage(mContext, R.string.action_unfollowing, result.getException(), true); - } - super.onPostExecute(result); - } - - } - - class DestroyMuteTask extends ManagedAsyncTask> { - - private final UserKey mAccountKey; - private final String mUserId; - - public DestroyMuteTask(final UserKey accountKey, final String userId) { - super(mContext); - mAccountKey = accountKey; - mUserId = userId; - } - - @Override - protected SingleResponse doInBackground(final Object... params) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountKey, false); - if (twitter == null) return SingleResponse.getInstance(); - try { - final User user = twitter.destroyMute(mUserId); - Utils.setLastSeen(mContext, UserKeyUtils.fromUser(user), -1); - return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountKey), null); - } catch (final TwitterException e) { - return SingleResponse.getInstance(null, e); - } - - } - - @Override - protected void onPostExecute(final SingleResponse result) { - if (result.hasData()) { - final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST); - final String message = mContext.getString(R.string.unmuted_user, - mUserColorNameManager.getDisplayName(result.getData(), nameFirst, true)); - Utils.showInfoMessage(mContext, message, false); - - - bus.post(new FriendshipUserUpdatedEvent(result.getData())); - } else { - Utils.showErrorMessage(mContext, R.string.action_unmuting, result.getException(), true); - } - super.onPostExecute(result); - } - - } - class DestroySavedSearchTask extends ManagedAsyncTask> { private final UserKey mAccountKey; @@ -1904,10 +1415,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } @Override - public void beforeExecute() { + public void beforeExecute(RefreshTaskParam params) { final Intent intent = new Intent(BROADCAST_RESCHEDULE_DIRECT_MESSAGES_REFRESHING); context.sendBroadcast(intent); - super.beforeExecute(); + super.beforeExecute(params); } } @@ -1955,47 +1466,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } - class ReportSpamTask extends ManagedAsyncTask> { - - private final UserKey mAccountKey; - private final String mUserId; - - public ReportSpamTask(final UserKey accountKey, final String userId) { - super(mContext); - this.mAccountKey = accountKey; - this.mUserId = userId; - } - - @Override - protected SingleResponse doInBackground(final Object... params) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountKey, false); - if (twitter != null) { - try { - final User user = twitter.reportSpam(mUserId); - return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountKey), null); - } catch (final TwitterException e) { - return SingleResponse.getInstance(null, e); - } - } - return SingleResponse.getInstance(); - } - - @Override - protected void onPostExecute(final SingleResponse result) { - if (result.hasData()) { - // TODO delete cached status - Utils.showInfoMessage(mContext, R.string.reported_user_for_spam, false); - - - bus.post(new FriendshipUserUpdatedEvent(result.getData())); - } else { - Utils.showErrorMessage(mContext, R.string.action_reporting_for_spam, result.getException(), true); - } - super.onPostExecute(result); - } - - } - class RetweetStatusTask extends ManagedAsyncTask> { private final UserKey mAccountKey; diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/DataStoreUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/DataStoreUtils.java index eaffc5e10..9371228cc 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/DataStoreUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/DataStoreUtils.java @@ -463,28 +463,28 @@ public class DataStoreUtils implements Constants { } } - public static int getStatusesCount(final Context context, final Uri uri, final long sinceId, - UserKey... accountKeys) { + public static int getStatusesCount(final Context context, final Uri uri, final long since, + String sinceColumn, UserKey... accountKeys) { if (context == null) return 0; if (accountKeys == null) { accountKeys = getActivatedAccountKeys(context); } final Expression selection = Expression.and( Expression.inArgs(new Column(Statuses.ACCOUNT_KEY), accountKeys.length), - Expression.greaterThanArgs(Statuses.STATUS_ID), + Expression.greaterThanArgs(sinceColumn), buildStatusFilterWhereClause(getTableNameByUri(uri), null) ); final String[] whereArgs = new String[accountKeys.length + 1]; for (int i = 0; i < accountKeys.length; i++) { whereArgs[i] = accountKeys[i].toString(); } - whereArgs[accountKeys.length] = String.valueOf(sinceId); + whereArgs[accountKeys.length] = String.valueOf(since); return queryCount(context, uri, selection.getSQL(), whereArgs); } public static int getActivitiesCount(@NonNull final Context context, final Uri uri, final Expression extraWhere, final String[] extraWhereArgs, - final long sinceTimestamp, boolean followingOnly, + final long since, String sinceColumn, boolean followingOnly, @Nullable UserKey[] accountKeys) { if (accountKeys == null) { accountKeys = getActivatedAccountKeys(context); @@ -497,7 +497,7 @@ public class DataStoreUtils implements Constants { expressions = new Expression[3]; } expressions[0] = Expression.inArgs(new Column(Activities.ACCOUNT_KEY), accountKeys.length); - expressions[1] = Expression.greaterThanArgs(Activities.TIMESTAMP); + expressions[1] = Expression.greaterThanArgs(sinceColumn); expressions[2] = buildActivityFilterWhereClause(getTableNameByUri(uri), null); final Expression selection = Expression.and(expressions); String[] selectionArgs; @@ -511,7 +511,7 @@ public class DataStoreUtils implements Constants { for (int i = 0; i < accountKeys.length; i++) { selectionArgs[i] = accountKeys[i].toString(); } - selectionArgs[accountKeys.length] = String.valueOf(sinceTimestamp); + selectionArgs[accountKeys.length] = String.valueOf(since); // If followingOnly option is on, we have to iterate over items if (followingOnly) { final ContentResolver resolver = context.getContentResolver(); @@ -1069,7 +1069,7 @@ public class DataStoreUtils implements Constants { } public static int getInteractionsCount(@NonNull final Context context, @Nullable final Bundle extraArgs, - final UserKey[] accountIds, final long position) { + final UserKey[] accountIds, final long since,final String sinceColumn) { Expression extraWhere = null; String[] extraWhereArgs = null; boolean followingOnly = false; @@ -1088,7 +1088,7 @@ public class DataStoreUtils implements Constants { } } return getActivitiesCount(context, Activities.AboutMe.CONTENT_URI, extraWhere, extraWhereArgs, - position, followingOnly, accountIds); + since, sinceColumn, followingOnly, accountIds); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/MediaLoaderWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/MediaLoaderWrapper.java index b84d852f4..3716b7160 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/MediaLoaderWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/MediaLoaderWrapper.java @@ -130,6 +130,12 @@ public class MediaLoaderWrapper implements Constants { mImageLoader.displayImage(url, view, mBannerDisplayOptions, listener); } + public void displayProfileBanner(final ImageView view, final String url, final int width, + final ImageLoadingListener listener) { + mImageLoader.displayImage(getBestBannerUrl(url, width), view, mBannerDisplayOptions, + listener); + } + public void displayProfileBanner(final ImageView view, final String url) { displayProfileBanner(view, url, null); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ParcelUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/ParcelUtils.java index b6f7359e8..22dee90ba 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/ParcelUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/ParcelUtils.java @@ -2,6 +2,7 @@ package org.mariotaku.twidere.util; import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import java.lang.reflect.Field; @@ -11,9 +12,7 @@ import java.lang.reflect.Field; */ public class ParcelUtils { - @Nullable - public static T clone(@Nullable T object) { - if (object == null) return null; + public static T clone(@NonNull T object) { final Parcel parcel = Parcel.obtain(); try { object.writeToParcel(parcel, 0); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ThemeUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/ThemeUtils.java index 1bb5988e9..81c57ca27 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/ThemeUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/ThemeUtils.java @@ -314,6 +314,16 @@ public class ThemeUtils implements Constants { return colors[0]; } + + public static int getContrastColor(int color, int darkColor, int lightColor) { + if (TwidereColorUtils.getYIQLuminance(color) <= ACCENT_COLOR_THRESHOLD) { + //return light text color + return lightColor; + } + //return dark text color + return darkColor; + } + public static int getContrastActionBarItemColor(Context context) { return getColorFromAttribute(context, android.R.attr.colorForeground, 0); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/dagger/GeneralComponent.java b/twidere/src/main/java/org/mariotaku/twidere/util/dagger/GeneralComponent.java index 9ea711ca5..93332f4f2 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/dagger/GeneralComponent.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/dagger/GeneralComponent.java @@ -50,6 +50,7 @@ import org.mariotaku.twidere.provider.CacheProvider; import org.mariotaku.twidere.provider.TwidereDataProvider; import org.mariotaku.twidere.service.BackgroundOperationService; import org.mariotaku.twidere.service.RefreshService; +import org.mariotaku.twidere.task.AbsFriendshipOperationTask; import org.mariotaku.twidere.task.GetDirectMessagesTask; import org.mariotaku.twidere.task.ManagedAsyncTask; import org.mariotaku.twidere.task.twitter.GetActivitiesTask; @@ -144,4 +145,6 @@ public interface GeneralComponent { void inject(GetActivitiesTask task); void inject(GetDirectMessagesTask task); + + void inject(AbsFriendshipOperationTask task); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/ActionIconButton.java b/twidere/src/main/java/org/mariotaku/twidere/view/ActionIconButton.java index cee182d21..26d225d5d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/ActionIconButton.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/ActionIconButton.java @@ -1,17 +1,21 @@ package org.mariotaku.twidere.view; import android.content.Context; +import android.content.res.ColorStateList; import android.content.res.TypedArray; +import android.graphics.Color; import android.support.annotation.ColorInt; +import android.support.v4.view.ViewCompat; +import android.support.v7.widget.AppCompatImageButton; import android.util.AttributeSet; -import android.widget.ImageButton; import org.mariotaku.twidere.R; +import org.mariotaku.twidere.util.ThemeUtils; /** * Created by mariotaku on 14/11/5. */ -public class ActionIconButton extends ImageButton { +public class ActionIconButton extends AppCompatImageButton { @ColorInt private int mDefaultColor, mActivatedColor, mDisabledColor; @@ -37,6 +41,14 @@ public class ActionIconButton extends ImageButton { @ColorInt public int getDefaultColor() { + if (mDefaultColor == 0) { + // Return inverse color for background tint + ColorStateList color = ViewCompat.getBackgroundTintList(this); + if (color != null) { + final int currentColor = color.getColorForState(getDrawableState(), 0); + return ThemeUtils.getContrastColor(currentColor, Color.BLACK, Color.WHITE); + } + } return mDefaultColor; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/holder/UserViewHolder.java b/twidere/src/main/java/org/mariotaku/twidere/view/holder/UserViewHolder.java index e1ad256cc..f27e2f5be 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/holder/UserViewHolder.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/holder/UserViewHolder.java @@ -30,6 +30,7 @@ import android.widget.TextView; import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.iface.IUsersAdapter; +import org.mariotaku.twidere.adapter.iface.IUsersAdapter.FollowClickListener; import org.mariotaku.twidere.adapter.iface.IUsersAdapter.RequestClickListener; import org.mariotaku.twidere.adapter.iface.IUsersAdapter.UserAdapterListener; import org.mariotaku.twidere.model.ParcelableUser; @@ -57,12 +58,14 @@ public class UserViewHolder extends ViewHolder implements OnClickListener, OnLon private final TextView descriptionView, locationView, urlView, statusesCountView, followersCountView, friendsCountView; - private final View acceptRequestButton, denyRequestButton; - private final View followRequestContainer; + private final View acceptRequestButton, denyRequestButton, followButton; + private final View actionsProgressContainer; + private final View actionsContainer; private final View processingRequestProgress; private UserAdapterListener userClickListener; private RequestClickListener requestClickListener; + private FollowClickListener followClickListener; public UserViewHolder(final IUsersAdapter adapter, final View itemView) { super(itemView); @@ -78,9 +81,11 @@ public class UserViewHolder extends ViewHolder implements OnClickListener, OnLon statusesCountView = (TextView) itemView.findViewById(R.id.statuses_count); followersCountView = (TextView) itemView.findViewById(R.id.followers_count); friendsCountView = (TextView) itemView.findViewById(R.id.friends_count); - followRequestContainer = itemView.findViewById(R.id.actions_container); + actionsProgressContainer = itemView.findViewById(R.id.actions_progress_container); + actionsContainer = itemView.findViewById(R.id.actions_container); acceptRequestButton = itemView.findViewById(R.id.accept_request); denyRequestButton = itemView.findViewById(R.id.deny_request); + followButton = itemView.findViewById(R.id.follow); processingRequestProgress = itemView.findViewById(R.id.processing_request); } @@ -121,14 +126,12 @@ public class UserViewHolder extends ViewHolder implements OnClickListener, OnLon loader.cancelDisplayTask(profileImageView); } - if (twitter.isProcessingFollowRequest(user.account_key, user.key)) { + if (twitter.isUpdatingRelationship(user.account_key, user.key)) { processingRequestProgress.setVisibility(View.VISIBLE); - acceptRequestButton.setVisibility(View.GONE); - denyRequestButton.setVisibility(View.GONE); + actionsContainer.setVisibility(View.GONE); } else { processingRequestProgress.setVisibility(View.GONE); - acceptRequestButton.setVisibility(View.VISIBLE); - denyRequestButton.setVisibility(View.VISIBLE); + actionsContainer.setVisibility(View.VISIBLE); } if (UserKeyUtils.isSameHost(user.account_key, user.key)) { externalIndicator.setVisibility(View.GONE); @@ -137,6 +140,23 @@ public class UserViewHolder extends ViewHolder implements OnClickListener, OnLon externalIndicator.setText(context.getString(R.string.external_user_host_format, user .key.getHost())); } + + followButton.setActivated(user.is_following); + + final boolean isMySelf = user.account_key.equals(user.key); + + if (requestClickListener != null && !isMySelf) { + acceptRequestButton.setVisibility(View.VISIBLE); + denyRequestButton.setVisibility(View.VISIBLE); + } else { + acceptRequestButton.setVisibility(View.GONE); + denyRequestButton.setVisibility(View.GONE); + } + if (followClickListener != null && !isMySelf) { + followButton.setVisibility(View.VISIBLE); + } else { + followButton.setVisibility(View.GONE); + } } public ImageView getProfileImageView() { @@ -165,6 +185,11 @@ public class UserViewHolder extends ViewHolder implements OnClickListener, OnLon requestClickListener.onDenyClicked(this, getLayoutPosition()); break; } + case R.id.follow: { + if (followClickListener == null) return; + followClickListener.onFollowClicked(this, getLayoutPosition()); + break; + } } } @@ -181,21 +206,24 @@ public class UserViewHolder extends ViewHolder implements OnClickListener, OnLon public void setOnClickListeners() { setUserClickListener(adapter.getUserAdapterListener()); - setRequestClickListener(adapter.getRequestClickListener()); + setActionClickListeners(adapter.getRequestClickListener(), adapter.getFollowClickListener()); } - private void setRequestClickListener(RequestClickListener listener) { - requestClickListener = listener; - if (listener != null) { + private void setActionClickListeners(RequestClickListener requestClickListener, + FollowClickListener followClickListener) { + this.requestClickListener = requestClickListener; + this.followClickListener = followClickListener; + if (requestClickListener != null || followClickListener != null) { nameView.setTwoLine(true); - followRequestContainer.setVisibility(View.VISIBLE); + actionsProgressContainer.setVisibility(View.VISIBLE); } else { nameView.setTwoLine(false); - followRequestContainer.setVisibility(View.GONE); + actionsProgressContainer.setVisibility(View.GONE); } nameView.updateText(); acceptRequestButton.setOnClickListener(this); denyRequestButton.setOnClickListener(this); + followButton.setOnClickListener(this); } public void setTextSize(final float textSize) { diff --git a/twidere/src/main/res/color/color_stateful_follow.xml b/twidere/src/main/res/color/color_stateful_follow.xml new file mode 100644 index 000000000..10a980968 --- /dev/null +++ b/twidere/src/main/res/color/color_stateful_follow.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/twidere/src/main/res/layout/card_item_user_compact.xml b/twidere/src/main/res/layout/card_item_user_compact.xml index 22bb8e6bf..6ec7c203a 100644 --- a/twidere/src/main/res/layout/card_item_user_compact.xml +++ b/twidere/src/main/res/layout/card_item_user_compact.xml @@ -34,14 +34,14 @@ android:id="@+id/profile_image_container" android:layout_width="@dimen/icon_size_card_list_item" android:layout_height="@dimen/icon_size_card_list_item" - android:layout_alignBottom="@+id/actions_container" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" - android:layout_alignTop="@+id/actions_container" + android:layout_alignTop="@+id/actions_progress_container" android:layout_marginEnd="@dimen/element_spacing_normal" android:layout_marginRight="@dimen/element_spacing_normal" - android:clipChildren="false"> + android:clipChildren="false" + tools:visibility="visible"> - + android:minHeight="@dimen/button_size_content_card" + android:minWidth="@dimen/button_size_content_card"> - + android:layout_gravity="center" + android:clipChildren="false" + android:orientation="horizontal" + tools:visibility="visible"> - + + + + + + + + + android:layout_height="wrap_content" + android:layout_gravity="center"/> - +