From cb675ec7bc0ea94ecd66dfad8d08e1baf72562c1 Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Wed, 9 Mar 2016 16:36:07 +0800 Subject: [PATCH] implementing group --- .../twidere/model/ParcelableGroup.java | 16 +- .../twidere/model/ParcelableUserList.java | 5 +- .../fragment/support/UserGroupsFragment.java | 19 ++- .../activity/support/LinkHandlerActivity.java | 4 + .../twidere/adapter/AbsUsersAdapter.java | 156 ----------------- .../adapter/ParcelableGroupsAdapter.java | 85 ++++++++++ .../adapter/ParcelableUsersAdapter.java | 119 ++++++++++++- .../fragment/support/AbsUsersFragment.java | 157 ------------------ .../support/IncomingFriendshipsFragment.java | 5 +- ...ent.java => ParcelableGroupsFragment.java} | 115 ++++++++----- .../support/ParcelableUsersFragment.java | 121 +++++++++++++- .../fragment/support/UserFragment.java | 1 + .../loader/support/BaseGroupsLoader.java | 117 +++++++++++++ .../loader/support/UserGroupsLoader.java | 60 +++++++ .../model/util/ParcelableGroupUtils.java | 42 +++++ .../twidere/model/util/UserKeyUtils.java | 7 +- .../twidere/view/holder/GroupViewHolder.java | 41 +++-- .../res/layout/card_item_group_compact.xml | 123 ++++++++++++++ twidere/src/main/res/values/strings.xml | 1 + 19 files changed, 798 insertions(+), 396 deletions(-) delete mode 100644 twidere/src/main/java/org/mariotaku/twidere/adapter/AbsUsersAdapter.java create mode 100644 twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableGroupsAdapter.java delete mode 100644 twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUsersFragment.java rename twidere/src/main/java/org/mariotaku/twidere/fragment/support/{AbsGroupsFragment.java => ParcelableGroupsFragment.java} (62%) create mode 100644 twidere/src/main/java/org/mariotaku/twidere/loader/support/BaseGroupsLoader.java create mode 100644 twidere/src/main/java/org/mariotaku/twidere/loader/support/UserGroupsLoader.java create mode 100644 twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableGroupUtils.java create mode 100644 twidere/src/main/res/layout/card_item_group_compact.xml diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableGroup.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableGroup.java index 566e6e10a..6dee06fe6 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableGroup.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableGroup.java @@ -2,22 +2,19 @@ package org.mariotaku.twidere.model; import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.NonNull; import com.bluelinelabs.logansquare.annotation.JsonField; import com.bluelinelabs.logansquare.annotation.JsonObject; import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease; import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease; -import org.mariotaku.twidere.api.twitter.util.TwitterDateConverter; - -import java.util.Date; - /** * Created by mariotaku on 16/3/9. */ @ParcelablePlease @JsonObject -public class ParcelableGroup implements Parcelable { +public class ParcelableGroup implements Parcelable, Comparable { @ParcelableThisPlease @JsonField(name = "account_key") @@ -45,6 +42,10 @@ public class ParcelableGroup implements Parcelable { @JsonField(name = "location") public String location; + @ParcelableThisPlease + @JsonField(name = "position") + public long position; + @ParcelableThisPlease @JsonField(name = "created") public long created; @@ -123,4 +124,9 @@ public class ParcelableGroup implements Parcelable { return new ParcelableGroup[size]; } }; + + @Override + public int compareTo(@NonNull ParcelableGroup another) { + return (int) (this.position - another.position); + } } diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUserList.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUserList.java index 190a34279..cfb24ab8a 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUserList.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUserList.java @@ -82,10 +82,7 @@ public class ParcelableUserList implements Parcelable, Comparable Integer.MAX_VALUE) return Integer.MAX_VALUE; - if (diff < Integer.MIN_VALUE) return Integer.MIN_VALUE; - return (int) diff; + return (int) (position - another.position); } @Override diff --git a/twidere/src/google/java/org/mariotaku/twidere/fragment/support/UserGroupsFragment.java b/twidere/src/google/java/org/mariotaku/twidere/fragment/support/UserGroupsFragment.java index a09578eb5..4af368aec 100644 --- a/twidere/src/google/java/org/mariotaku/twidere/fragment/support/UserGroupsFragment.java +++ b/twidere/src/google/java/org/mariotaku/twidere/fragment/support/UserGroupsFragment.java @@ -1,9 +1,24 @@ package org.mariotaku.twidere.fragment.support; -import android.support.v4.app.Fragment; +import android.content.Context; +import android.os.Bundle; +import android.support.v4.content.Loader; + +import org.mariotaku.twidere.loader.support.UserGroupsLoader; +import org.mariotaku.twidere.model.ParcelableGroup; +import org.mariotaku.twidere.model.UserKey; + +import java.util.List; /** * Created by mariotaku on 16/3/9. */ -public class UserGroupsFragment extends Fragment { +public class UserGroupsFragment extends ParcelableGroupsFragment { + @Override + protected Loader> onCreateUserListsLoader(Context context, Bundle args, boolean fromUser) { + final UserKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY); + final long userId = args.getLong(EXTRA_USER_ID, -1); + final String screenName = args.getString(EXTRA_SCREEN_NAME); + return new UserGroupsLoader(context, accountKey, userId, screenName, getData()); + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/LinkHandlerActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/LinkHandlerActivity.java index f86c682de..7073a88be 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/LinkHandlerActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/LinkHandlerActivity.java @@ -429,6 +429,10 @@ public class LinkHandlerActivity extends BaseAppCompatActivity implements System setTitle(R.string.user_lists); break; } + case LINK_ID_USER_GROUPS: { + setTitle(R.string.groups); + break; + } case LINK_ID_USER_LIST_TIMELINE: { setTitle(R.string.list_timeline); break; diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsUsersAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsUsersAdapter.java deleted file mode 100644 index bc26e0d70..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsUsersAdapter.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2015 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.adapter; - -import android.content.Context; -import android.support.annotation.Nullable; -import android.support.v7.widget.RecyclerView.ViewHolder; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import org.mariotaku.twidere.Constants; -import org.mariotaku.twidere.R; -import org.mariotaku.twidere.adapter.iface.IUsersAdapter; -import org.mariotaku.twidere.util.ThemeUtils; -import org.mariotaku.twidere.util.Utils; -import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder; -import org.mariotaku.twidere.view.holder.UserViewHolder; - -public abstract class AbsUsersAdapter extends LoadMoreSupportAdapter implements Constants, - IUsersAdapter { - - public static final int ITEM_VIEW_TYPE_USER = 2; - - private final LayoutInflater mInflater; - - private final int mCardBackgroundColor; - private final int mProfileImageStyle; - private final int mTextSize; - private final boolean mDisplayProfileImage; - private final boolean mShowAbsoluteTime; - private UserAdapterListener mUserAdapterListener; - private RequestClickListener mRequestClickListener; - - public AbsUsersAdapter(final Context context) { - super(context); - mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(context, ThemeUtils.getThemeBackgroundOption(context), ThemeUtils.getUserThemeBackgroundAlpha(context)); - mInflater = LayoutInflater.from(context); - mTextSize = mPreferences.getInt(KEY_TEXT_SIZE, context.getResources().getInteger(R.integer.default_text_size)); - mProfileImageStyle = Utils.getProfileImageStyle(mPreferences.getString(KEY_PROFILE_IMAGE_STYLE, null)); - mDisplayProfileImage = mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE); - mShowAbsoluteTime = mPreferences.getBoolean(KEY_SHOW_ABSOLUTE_TIME); - } - - @Override - public int getProfileImageStyle() { - return mProfileImageStyle; - } - - @Override - public float getTextSize() { - return mTextSize; - } - - @Override - public boolean isProfileImageEnabled() { - return mDisplayProfileImage; - } - - public abstract D getData(); - - public boolean isUser(int position) { - return position < getUserCount(); - } - - @Override - public boolean isShowAbsoluteTime() { - return mShowAbsoluteTime; - } - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - switch (viewType) { - case ITEM_VIEW_TYPE_USER: { - final View view; - view = mInflater.inflate(R.layout.card_item_user_compact, parent, false); - final View itemContent = view.findViewById(R.id.item_content); - itemContent.setBackgroundColor(mCardBackgroundColor); - final UserViewHolder holder = new UserViewHolder(this, view); - holder.setOnClickListeners(); - holder.setupViewOptions(); - return holder; - } - case ITEM_VIEW_TYPE_LOAD_INDICATOR: { - final View view = mInflater.inflate(R.layout.card_item_load_indicator, parent, false); - return new LoadIndicatorViewHolder(view); - } - } - throw new IllegalStateException("Unknown view type " + viewType); - } - - @Override - public void onBindViewHolder(ViewHolder holder, int position) { - switch (holder.getItemViewType()) { - case ITEM_VIEW_TYPE_USER: { - bindUser(((UserViewHolder) holder), position); - break; - } - } - } - - @Override - public int getItemViewType(int position) { - if ((getLoadMoreIndicatorPosition() & IndicatorPosition.START) != 0 && position == 0) { - return ITEM_VIEW_TYPE_LOAD_INDICATOR; - } - if (position == getUserCount()) { - return ITEM_VIEW_TYPE_LOAD_INDICATOR; - } - return ITEM_VIEW_TYPE_USER; - } - - @Nullable - @Override - public UserAdapterListener getUserAdapterListener() { - return mUserAdapterListener; - } - - public void setUserAdapterListener(UserAdapterListener userAdapterListener) { - mUserAdapterListener = userAdapterListener; - } - - @Override - public RequestClickListener getRequestClickListener() { - return mRequestClickListener; - } - - public void setRequestClickListener(RequestClickListener requestClickListener) { - mRequestClickListener = requestClickListener; - } - - @Override - public boolean shouldShowAccountsColor() { - return false; - } - - protected abstract void bindUser(UserViewHolder holder, int position); - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableGroupsAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableGroupsAdapter.java new file mode 100644 index 000000000..1e0c3253c --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableGroupsAdapter.java @@ -0,0 +1,85 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2015 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.adapter; + +import android.content.Context; + +import org.mariotaku.twidere.model.ParcelableGroup; +import org.mariotaku.twidere.view.holder.GroupViewHolder; + +import java.util.List; + +public class ParcelableGroupsAdapter extends AbsGroupsAdapter> { + + private List mData; + + + public ParcelableGroupsAdapter(Context context) { + super(context); + } + + @Override + public List getData() { + return mData; + } + + + @Override + public void setData(List data) { + mData = data; + notifyDataSetChanged(); + } + + @Override + protected void bindGroup(GroupViewHolder holder, int position) { + holder.displayGroup(getGroup(position)); + } + + @Override + public int getItemCount() { + final int position = getLoadMoreIndicatorPosition(); + int count = getGroupsCount(); + if ((position & IndicatorPosition.START) != 0) { + count++; + } + if ((position & IndicatorPosition.END) != 0) { + count++; + } + return count; + } + + @Override + public ParcelableGroup getGroup(int position) { + if (position == getGroupsCount()) return null; + return mData.get(position); + } + + @Override + public long getGroupId(int position) { + if (position == getGroupsCount()) return -1; + return mData.get(position).id; + } + + @Override + public int getGroupsCount() { + if (mData == null) return 0; + return mData.size(); + } +} 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 7ebfd6a38..8ce53c7d9 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableUsersAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableUsersAdapter.java @@ -20,24 +20,51 @@ package org.mariotaku.twidere.adapter; import android.content.Context; +import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; -import org.mariotaku.twidere.model.UserKey; +import org.mariotaku.twidere.Constants; +import org.mariotaku.twidere.R; +import org.mariotaku.twidere.adapter.iface.IUsersAdapter; import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.UserKey; +import org.mariotaku.twidere.util.ThemeUtils; +import org.mariotaku.twidere.util.Utils; +import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder; import org.mariotaku.twidere.view.holder.UserViewHolder; import java.util.List; -public class ParcelableUsersAdapter extends AbsUsersAdapter> { +public class ParcelableUsersAdapter extends LoadMoreSupportAdapter + implements Constants, IUsersAdapter> { + public static final int ITEM_VIEW_TYPE_USER = 2; + private final LayoutInflater mInflater; + private final int mCardBackgroundColor; + private final int mProfileImageStyle; + private final int mTextSize; + private final boolean mDisplayProfileImage; + private final boolean mShowAbsoluteTime; private List mData; + private UserAdapterListener mUserAdapterListener; + private RequestClickListener mRequestClickListener; public ParcelableUsersAdapter(Context context) { super(context); + mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(context, + ThemeUtils.getThemeBackgroundOption(context), + ThemeUtils.getUserThemeBackgroundAlpha(context)); + mInflater = LayoutInflater.from(context); + mTextSize = mPreferences.getInt(KEY_TEXT_SIZE, context.getResources().getInteger(R.integer.default_text_size)); + mProfileImageStyle = Utils.getProfileImageStyle(mPreferences.getString(KEY_PROFILE_IMAGE_STYLE, null)); + mDisplayProfileImage = mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE); + mShowAbsoluteTime = mPreferences.getBoolean(KEY_SHOW_ABSOLUTE_TIME); } - @Override public List getData() { return mData; } @@ -49,7 +76,6 @@ public class ParcelableUsersAdapter extends AbsUsersAdapter notifyDataSetChanged(); } - @Override protected void bindUser(UserViewHolder holder, int position) { holder.displayUser(getUser(position)); } @@ -114,4 +140,89 @@ public class ParcelableUsersAdapter extends AbsUsersAdapter return RecyclerView.NO_POSITION; } + @Override + public int getProfileImageStyle() { + return mProfileImageStyle; + } + + @Override + public float getTextSize() { + return mTextSize; + } + + @Override + public boolean isProfileImageEnabled() { + return mDisplayProfileImage; + } + + @Override + public boolean isShowAbsoluteTime() { + return mShowAbsoluteTime; + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + switch (viewType) { + case ITEM_VIEW_TYPE_USER: { + final View view; + view = mInflater.inflate(R.layout.card_item_user_compact, parent, false); + final View itemContent = view.findViewById(R.id.item_content); + itemContent.setBackgroundColor(mCardBackgroundColor); + final UserViewHolder holder = new UserViewHolder(this, view); + holder.setOnClickListeners(); + holder.setupViewOptions(); + return holder; + } + case ITEM_VIEW_TYPE_LOAD_INDICATOR: { + final View view = mInflater.inflate(R.layout.card_item_load_indicator, parent, false); + return new LoadIndicatorViewHolder(view); + } + } + throw new IllegalStateException("Unknown view type " + viewType); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + switch (holder.getItemViewType()) { + case ITEM_VIEW_TYPE_USER: { + bindUser(((UserViewHolder) holder), position); + break; + } + } + } + + @Override + public int getItemViewType(int position) { + if ((getLoadMoreIndicatorPosition() & IndicatorPosition.START) != 0 && position == 0) { + return ITEM_VIEW_TYPE_LOAD_INDICATOR; + } + if (position == getUserCount()) { + return ITEM_VIEW_TYPE_LOAD_INDICATOR; + } + return ITEM_VIEW_TYPE_USER; + } + + @Nullable + @Override + public UserAdapterListener getUserAdapterListener() { + return mUserAdapterListener; + } + + public void setUserAdapterListener(UserAdapterListener userAdapterListener) { + mUserAdapterListener = userAdapterListener; + } + + @Override + public RequestClickListener getRequestClickListener() { + return mRequestClickListener; + } + + public void setRequestClickListener(RequestClickListener requestClickListener) { + mRequestClickListener = requestClickListener; + } + + @Override + public boolean shouldShowAccountsColor() { + return false; + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUsersFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUsersFragment.java deleted file mode 100644 index 8a92018d3..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUsersFragment.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2015 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.fragment.support; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v4.app.FragmentActivity; -import android.support.v4.app.LoaderManager.LoaderCallbacks; -import android.support.v4.content.Loader; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.KeyEvent; - -import org.mariotaku.twidere.adapter.AbsUsersAdapter; -import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition; -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.util.UserKeyUtils; -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.RecyclerViewNavigationHelper; -import org.mariotaku.twidere.view.holder.UserViewHolder; - -abstract class AbsUsersFragment extends AbsContentListRecyclerViewFragment> - implements LoaderCallbacks, UserAdapterListener, KeyboardShortcutCallback { - - private RecyclerViewNavigationHelper mNavigationHelper; - - public final Data 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); - } - - @Override - public boolean handleKeyboardShortcutRepeat(@NonNull KeyboardShortcutsHandler handler, int keyCode, int repeatCount, @NonNull KeyEvent event, int metaState) { - return mNavigationHelper.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState); - } - - @Override - public boolean isKeyboardShortcutHandled(@NonNull KeyboardShortcutsHandler handler, int keyCode, @NonNull KeyEvent event, int metaState) { - return mNavigationHelper.isKeyboardShortcutHandled(handler, keyCode, event, metaState); - } - - @Override - public void onActivityCreated(@Nullable Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - final AbsUsersAdapter 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); - args.remove(EXTRA_FROM_USER); - return onCreateUsersLoader(getActivity(), args, fromUser); - } - - @Override - public void onLoadFinished(Loader loader, Data data) { - final AbsUsersAdapter adapter = getAdapter(); - adapter.setData(data); - if (!(loader instanceof IExtendedLoader) || ((IExtendedLoader) loader).isFromUser()) { - adapter.setLoadMoreSupportedPosition(hasMoreData(data) ? IndicatorPosition.END : IndicatorPosition.NONE); - setRefreshEnabled(true); - } - if (loader instanceof IExtendedLoader) { - ((IExtendedLoader) loader).setFromUser(false); - } - showContent(); - } - - @Override - public void onLoaderReset(Loader loader) { - if (loader instanceof IExtendedLoader) { - ((IExtendedLoader) loader).setFromUser(false); - } - } - - @Override - public void onUserClick(UserViewHolder holder, int position) { - final ParcelableUser user = getAdapter().getUser(position); - final FragmentActivity activity = getActivity(); - if (UserKeyUtils.isSameHost(user.account_key, user.key)) { - IntentUtils.openUserProfile(activity, user.account_key, user.key.getId(), - user.screen_name, null, true, getUserReferral()); - } else if (user.extras != null && user.extras.statusnet_profile_url != null) { - final Uri uri = Uri.parse(user.extras.statusnet_profile_url); - final Intent intent = new Intent(Intent.ACTION_VIEW, uri); - startActivity(intent); - } else { - final Uri uri = LinkCreator.getTwitterUserLink(user.screen_name); - final Intent intent = new Intent(Intent.ACTION_VIEW, uri); - startActivity(intent); - } - } - - @UserFragment.Referral - protected String getUserReferral() { - return null; - } - - - @Override - public boolean onUserLongClick(UserViewHolder holder, int position) { - - return true; - } - - protected abstract boolean hasMoreData(Data data); - - protected abstract Loader onCreateUsersLoader(final Context context, - @NonNull final Bundle args, - final boolean fromUser); - - - @Override - protected void setupRecyclerView(Context context, boolean compact) { - super.setupRecyclerView(context, true); - } - -} 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 8cc5759aa..1140ba04d 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 @@ -25,7 +25,6 @@ import android.support.annotation.NonNull; import com.squareup.otto.Subscribe; -import org.mariotaku.twidere.adapter.AbsUsersAdapter; import org.mariotaku.twidere.adapter.ParcelableUsersAdapter; import org.mariotaku.twidere.adapter.iface.IUsersAdapter; import org.mariotaku.twidere.loader.support.IDsUsersLoader; @@ -70,7 +69,7 @@ public class IncomingFriendshipsFragment extends CursorSupportUsersListFragment @Override public void onAcceptClicked(UserViewHolder holder, int position) { - final AbsUsersAdapter> adapter = getAdapter(); + final ParcelableUsersAdapter adapter = getAdapter(); final ParcelableUser user = adapter.getUser(position); if (user == null) return; mTwitterWrapper.acceptFriendshipAsync(user.account_key, user.key); @@ -78,7 +77,7 @@ public class IncomingFriendshipsFragment extends CursorSupportUsersListFragment @Override public void onDenyClicked(UserViewHolder holder, int position) { - final AbsUsersAdapter> adapter = getAdapter(); + final ParcelableUsersAdapter adapter = getAdapter(); final ParcelableUser user = adapter.getUser(position); if (user == null) return; mTwitterWrapper.denyFriendshipAsync(user.account_key, user.key); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsGroupsFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableGroupsFragment.java similarity index 62% rename from twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsGroupsFragment.java rename to twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableGroupsFragment.java index e74fc3914..8b7297fb7 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsGroupsFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableGroupsFragment.java @@ -23,35 +23,93 @@ import android.content.Context; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v4.app.LoaderManager.LoaderCallbacks; +import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.KeyEvent; import org.mariotaku.twidere.adapter.AbsGroupsAdapter; -import org.mariotaku.twidere.adapter.AbsUserListsAdapter; +import org.mariotaku.twidere.adapter.ParcelableGroupsAdapter; import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition; import org.mariotaku.twidere.loader.iface.IExtendedLoader; -import org.mariotaku.twidere.loader.support.iface.ICursorSupportLoader; import org.mariotaku.twidere.model.ParcelableGroup; -import org.mariotaku.twidere.model.ParcelableUserList; -import org.mariotaku.twidere.util.IntentUtils; +import org.mariotaku.twidere.model.UserKey; import org.mariotaku.twidere.util.KeyboardShortcutsHandler; -import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback; import org.mariotaku.twidere.util.RecyclerViewNavigationHelper; import org.mariotaku.twidere.view.holder.GroupViewHolder; -import org.mariotaku.twidere.view.holder.UserListViewHolder; -abstract class AbsGroupsFragment extends AbsContentListRecyclerViewFragment> - implements LoaderCallbacks, AbsGroupsAdapter.GroupAdapterListener, KeyboardShortcutCallback { +import java.util.List; + +public abstract class ParcelableGroupsFragment extends AbsContentListRecyclerViewFragment>> + implements LoaderManager.LoaderCallbacks>, AbsGroupsAdapter.GroupAdapterListener, + KeyboardShortcutsHandler.KeyboardShortcutCallback { private RecyclerViewNavigationHelper mNavigationHelper; - private long mNextCursor; private long mPrevCursor; - public final Data getData() { + @Override + public boolean isRefreshing() { + if (getContext() == null || isDetached()) return false; + final LoaderManager lm = getLoaderManager(); + return lm.hasRunningLoaders(); + } + + @NonNull + @Override + protected final ParcelableGroupsAdapter onCreateAdapter(Context context, boolean compact) { + return new ParcelableGroupsAdapter(context); + } + + @Override + protected void setupRecyclerView(Context context, boolean compact) { + super.setupRecyclerView(context, true); + } + + @Nullable + protected UserKey getAccountKey() { + final Bundle args = getArguments(); + return args.getParcelable(EXTRA_ACCOUNT_KEY); + } + + protected boolean hasMoreData(List data) { + return data == null || !data.isEmpty(); + } + + @Override + public void onLoadFinished(Loader> loader, List data) { + final AbsGroupsAdapter> adapter = getAdapter(); + adapter.setData(data); + if (!(loader instanceof IExtendedLoader) || ((IExtendedLoader) loader).isFromUser()) { + adapter.setLoadMoreSupportedPosition(hasMoreData(data) ? IndicatorPosition.END : IndicatorPosition.NONE); + setRefreshEnabled(true); + } + if (loader instanceof IExtendedLoader) { + ((IExtendedLoader) loader).setFromUser(false); + } + setRefreshEnabled(true); + setRefreshing(false); + setLoadMoreIndicatorPosition(IndicatorPosition.NONE); + } + + @Override + public void onLoadMoreContents(@IndicatorPosition int position) { + // Only supports load from end, skip START flag + if ((position & IndicatorPosition.START) != 0) return; + super.onLoadMoreContents(position); + if (position == 0) return; + final Bundle loaderArgs = new Bundle(getArguments()); + loaderArgs.putBoolean(EXTRA_FROM_USER, true); + loaderArgs.putLong(EXTRA_NEXT_CURSOR, getNextCursor()); + getLoaderManager().restartLoader(0, loaderArgs, this); + } + + protected void removeUsers(long... ids) { + //TODO remove from adapter + } + + public final List getData() { return getAdapter().getData(); } @@ -73,7 +131,7 @@ abstract class AbsGroupsFragment extends AbsContentListRecyclerViewFragmen @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - final AbsGroupsAdapter adapter = getAdapter(); + final AbsGroupsAdapter> adapter = getAdapter(); final RecyclerView recyclerView = getRecyclerView(); final LinearLayoutManager layoutManager = getLayoutManager(); adapter.setListener(this); @@ -86,32 +144,14 @@ abstract class AbsGroupsFragment extends AbsContentListRecyclerViewFragmen } @Override - public final Loader onCreateLoader(int id, Bundle args) { + public final Loader> onCreateLoader(int id, Bundle args) { final boolean fromUser = args.getBoolean(EXTRA_FROM_USER); args.remove(EXTRA_FROM_USER); return onCreateUserListsLoader(getActivity(), args, fromUser); } @Override - public void onLoadFinished(Loader loader, Data data) { - final AbsGroupsAdapter adapter = getAdapter(); - adapter.setData(data); - if (!(loader instanceof IExtendedLoader) || ((IExtendedLoader) loader).isFromUser()) { - adapter.setLoadMoreSupportedPosition(hasMoreData(data) ? IndicatorPosition.END : IndicatorPosition.NONE); - setRefreshEnabled(true); - } - if (loader instanceof IExtendedLoader) { - ((IExtendedLoader) loader).setFromUser(false); - } - if (loader instanceof ICursorSupportLoader) { - mNextCursor = ((ICursorSupportLoader) loader).getNextCursor(); - mPrevCursor = ((ICursorSupportLoader) loader).getNextCursor(); - } - showContent(); - } - - @Override - public void onLoaderReset(Loader loader) { + public void onLoaderReset(Loader> loader) { if (loader instanceof IExtendedLoader) { ((IExtendedLoader) loader).setFromUser(false); } @@ -135,14 +175,5 @@ abstract class AbsGroupsFragment extends AbsContentListRecyclerViewFragmen return mNextCursor; } - - protected ParcelableUserList getSelectedUserList() { - //TODO return selected - return null; - } - - protected abstract boolean hasMoreData(Data data); - - protected abstract Loader onCreateUserListsLoader(Context context, Bundle args, boolean fromUser); - + protected abstract Loader> onCreateUserListsLoader(Context context, Bundle args, boolean fromUser); } 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 9e4b76628..01066995b 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 @@ -20,17 +20,37 @@ package org.mariotaku.twidere.fragment.support; import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.KeyEvent; 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.loader.iface.IExtendedLoader; import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.util.UserKeyUtils; +import org.mariotaku.twidere.util.IntentUtils; +import org.mariotaku.twidere.util.KeyboardShortcutsHandler; +import org.mariotaku.twidere.util.LinkCreator; +import org.mariotaku.twidere.util.RecyclerViewNavigationHelper; +import org.mariotaku.twidere.view.holder.UserViewHolder; import java.util.List; -public abstract class ParcelableUsersFragment extends AbsUsersFragment> { +public abstract class ParcelableUsersFragment extends AbsContentListRecyclerViewFragment + implements LoaderManager.LoaderCallbacks>, IUsersAdapter.UserAdapterListener, + KeyboardShortcutsHandler.KeyboardShortcutCallback { + + private RecyclerViewNavigationHelper mNavigationHelper; @Override public boolean isRefreshing() { @@ -48,17 +68,24 @@ public abstract class ParcelableUsersFragment extends AbsUsersFragment data) { return data == null || !data.isEmpty(); } - @Override public void onLoadFinished(Loader> loader, List data) { - super.onLoadFinished(loader, data); + final ParcelableUsersAdapter adapter = getAdapter(); + adapter.setData(data); + if (!(loader instanceof IExtendedLoader) || ((IExtendedLoader) loader).isFromUser()) { + adapter.setLoadMoreSupportedPosition(hasMoreData(data) ? IndicatorPosition.END : IndicatorPosition.NONE); + setRefreshEnabled(true); + } + if (loader instanceof IExtendedLoader) { + ((IExtendedLoader) loader).setFromUser(false); + } + showContent(); setRefreshEnabled(true); setRefreshing(false); setLoadMoreIndicatorPosition(IndicatorPosition.NONE); @@ -68,4 +95,88 @@ public abstract class ParcelableUsersFragment extends AbsUsersFragment 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); + } + + @Override + public boolean handleKeyboardShortcutRepeat(@NonNull KeyboardShortcutsHandler handler, int keyCode, int repeatCount, @NonNull KeyEvent event, int metaState) { + return mNavigationHelper.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState); + } + + @Override + public boolean isKeyboardShortcutHandled(@NonNull KeyboardShortcutsHandler handler, int keyCode, @NonNull KeyEvent event, int metaState) { + 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); + args.remove(EXTRA_FROM_USER); + return onCreateUsersLoader(getActivity(), args, fromUser); + } + + @Override + public void onLoaderReset(Loader> loader) { + if (loader instanceof IExtendedLoader) { + ((IExtendedLoader) loader).setFromUser(false); + } + } + + @Override + public void onUserClick(UserViewHolder holder, int position) { + final ParcelableUser user = getAdapter().getUser(position); + final FragmentActivity activity = getActivity(); + if (UserKeyUtils.isSameHost(user.account_key, user.key)) { + IntentUtils.openUserProfile(activity, user.account_key, user.key.getId(), + user.screen_name, null, true, getUserReferral()); + } else if (user.extras != null && user.extras.statusnet_profile_url != null) { + final Uri uri = Uri.parse(user.extras.statusnet_profile_url); + final Intent intent = new Intent(Intent.ACTION_VIEW, uri); + startActivity(intent); + } else { + final Uri uri = LinkCreator.getTwitterUserLink(user.screen_name); + final Intent intent = new Intent(Intent.ACTION_VIEW, uri); + startActivity(intent); + } + } + + @UserFragment.Referral + protected String getUserReferral() { + return null; + } + + @Override + public boolean onUserLongClick(UserViewHolder holder, int position) { + return true; + } + + protected abstract Loader> onCreateUsersLoader(final Context context, + @NonNull final Bundle args, + final boolean fromUser); + + @Override + protected void setupRecyclerView(Context context, boolean compact) { + super.setupRecyclerView(context, true); + } } 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 ddf7e8427..f525ea044 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 @@ -807,6 +807,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener mProfileImageView.setOnClickListener(this); mProfileBannerView.setOnClickListener(this); mListedContainer.setOnClickListener(this); + mGroupsContainer.setOnClickListener(this); mFollowersContainer.setOnClickListener(this); mFriendsContainer.setOnClickListener(this); mHeaderErrorIcon.setOnClickListener(this); diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/BaseGroupsLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/BaseGroupsLoader.java new file mode 100644 index 000000000..f5f424168 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/BaseGroupsLoader.java @@ -0,0 +1,117 @@ +/* + * 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.loader.support; + +import android.content.Context; +import android.support.v4.content.AsyncTaskLoader; +import android.util.Log; + +import org.mariotaku.twidere.TwidereConstants; +import org.mariotaku.twidere.api.statusnet.model.Group; +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.CursorSupport; +import org.mariotaku.twidere.api.twitter.model.PageableResponseList; +import org.mariotaku.twidere.loader.support.iface.ICursorSupportLoader; +import org.mariotaku.twidere.model.ParcelableGroup; +import org.mariotaku.twidere.model.UserKey; +import org.mariotaku.twidere.model.util.ParcelableGroupUtils; +import org.mariotaku.twidere.util.TwitterAPIFactory; +import org.mariotaku.twidere.util.collection.NoDuplicatesArrayList; + +import java.util.Collections; +import java.util.List; + + +public abstract class BaseGroupsLoader extends AsyncTaskLoader> + implements TwidereConstants, ICursorSupportLoader { + + protected final NoDuplicatesArrayList mData = new NoDuplicatesArrayList<>(); + protected final UserKey mAccountId; + private final long mCursor; + + private long mNextCursor, mPrevCursor; + + public BaseGroupsLoader(final Context context, final UserKey accountKey, final long cursor, + final List data) { + super(context); + if (data != null) { + mData.addAll(data); + } + mCursor = cursor; + mAccountId = accountKey; + } + + @Override + public long getCursor() { + return mCursor; + } + + @Override + public long getNextCursor() { + return mNextCursor; + } + + @Override + public long getPrevCursor() { + return mPrevCursor; + } + + public abstract List getGroups(final Twitter twitter) throws TwitterException; + + @Override + public List loadInBackground() { + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, true); + List listLoaded = null; + try { + listLoaded = getGroups(twitter); + } catch (final TwitterException e) { + Log.w(LOGTAG, e); + } + if (listLoaded != null) { + final int listSize = listLoaded.size(); + if (listLoaded instanceof PageableResponseList) { + mNextCursor = ((CursorSupport) listLoaded).getNextCursor(); + mPrevCursor = ((CursorSupport) listLoaded).getPreviousCursor(); + final int dataSize = mData.size(); + for (int i = 0; i < listSize; i++) { + final Group group = listLoaded.get(i); + mData.add(ParcelableGroupUtils.from(group, mAccountId, dataSize + i, isMember(group))); + } + } else { + for (int i = 0; i < listSize; i++) { + final Group list = listLoaded.get(i); + mData.add(ParcelableGroupUtils.from(listLoaded.get(i), mAccountId, i, isMember(list))); + } + } + } + Collections.sort(mData); + return mData; + } + + @Override + public void onStartLoading() { + forceLoad(); + } + + protected boolean isMember(final Group list) { + return list.isMember(); + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/UserGroupsLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/UserGroupsLoader.java new file mode 100644 index 000000000..e957b1990 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/UserGroupsLoader.java @@ -0,0 +1,60 @@ +/* + * 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.loader.support; + +import android.content.Context; + +import org.mariotaku.twidere.api.statusnet.model.Group; +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.ResponseList; +import org.mariotaku.twidere.api.twitter.model.UserList; +import org.mariotaku.twidere.model.ParcelableGroup; +import org.mariotaku.twidere.model.ParcelableUserList; +import org.mariotaku.twidere.model.UserKey; + +import java.util.List; + +public class UserGroupsLoader extends BaseGroupsLoader { + + private final long mUserId; + private final String mScreenName; + + public UserGroupsLoader(final Context context, final UserKey accountKey, final long userId, + final String screenName, final List data) { + super(context, accountKey, 0, data); + mUserId = userId; + mScreenName = screenName; + } + + @Override + public ResponseList getGroups(final Twitter twitter) throws TwitterException { + if (twitter == null) return null; + if (mUserId > 0) + return twitter.getGroups(mUserId); + else if (mScreenName != null) return twitter.getGroups(mScreenName); + return null; + } + + @Override + protected boolean isMember(final Group list) { + return true; + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableGroupUtils.java b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableGroupUtils.java new file mode 100644 index 000000000..76545b472 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableGroupUtils.java @@ -0,0 +1,42 @@ +package org.mariotaku.twidere.model.util; + +import org.mariotaku.twidere.api.statusnet.model.Group; +import org.mariotaku.twidere.model.ParcelableGroup; +import org.mariotaku.twidere.model.UserKey; + +import java.util.Date; + +/** + * Created by mariotaku on 16/3/9. + */ +public class ParcelableGroupUtils { + public static ParcelableGroup from(Group group, UserKey accountKey, int position, boolean member) { + ParcelableGroup obj = new ParcelableGroup(); + obj.account_key = accountKey; + obj.member = member; + obj.position = position; + obj.id = group.getId(); + obj.nickname = group.getNickname(); + obj.homepage = group.getHomepage(); + obj.fullname = group.getFullname(); + obj.url = group.getUrl(); + obj.description = group.getDescription(); + obj.location = group.getLocation(); + obj.created = getTime(group.getCreated()); + obj.modified = getTime(group.getModified()); + obj.admin_count = group.getAdminCount(); + obj.member_count = group.getMemberCount(); + obj.original_logo = group.getOriginalLogo(); + obj.homepage_logo = group.getHomepageLogo(); + obj.stream_logo = group.getStreamLogo(); + obj.mini_logo = group.getMiniLogo(); + obj.blocked = group.isBlocked(); + obj.id = group.getId(); + return obj; + } + + private static long getTime(Date date) { + if (date == null) return -1; + return date.getTime(); + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/util/UserKeyUtils.java b/twidere/src/main/java/org/mariotaku/twidere/model/util/UserKeyUtils.java index 0727f7d3d..91052c03a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/util/UserKeyUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/util/UserKeyUtils.java @@ -68,8 +68,11 @@ public class UserKeyUtils { } public static boolean isSameHost(UserKey accountKey, UserKey userKey) { - final String a = accountKey.getHost(), b = userKey.getHost(); + return isSameHost(accountKey.getHost(), userKey.getHost()); + } + + public static boolean isSameHost(String a, String b) { if (TextUtils.isEmpty(a) || TextUtils.isEmpty(b)) return true; - return a.equals(b); + return TextUtils.equals(a, b); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/holder/GroupViewHolder.java b/twidere/src/main/java/org/mariotaku/twidere/view/holder/GroupViewHolder.java index e42e2372b..6589aa03a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/holder/GroupViewHolder.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/holder/GroupViewHolder.java @@ -29,9 +29,10 @@ import android.widget.TextView; import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.iface.IGroupsAdapter; import org.mariotaku.twidere.model.ParcelableGroup; +import org.mariotaku.twidere.model.util.UserKeyUtils; import org.mariotaku.twidere.util.MediaLoaderWrapper; -import org.mariotaku.twidere.util.UserColorNameManager; import org.mariotaku.twidere.util.Utils; +import org.mariotaku.twidere.view.NameView; import org.mariotaku.twidere.view.iface.IColorLabelView; import java.util.Locale; @@ -45,11 +46,11 @@ public class GroupViewHolder extends ViewHolder implements View.OnClickListener, private final IColorLabelView itemContent; private final ImageView profileImageView; - private final TextView nameView; - private final TextView createdByView; + private final NameView nameView; + private final TextView externalIndicator; private final TextView descriptionView; private final TextView membersCountView; - private final TextView subscribersCountView; + private final TextView adminsCountView; private IGroupsAdapter.GroupAdapterListener groupClickListener; @@ -58,22 +59,26 @@ public class GroupViewHolder extends ViewHolder implements View.OnClickListener, itemContent = (IColorLabelView) itemView.findViewById(R.id.item_content); this.adapter = adapter; profileImageView = (ImageView) itemView.findViewById(R.id.profile_image); - nameView = (TextView) itemView.findViewById(R.id.name); - createdByView = (TextView) itemView.findViewById(R.id.created_by); + nameView = (NameView) itemView.findViewById(R.id.name); + externalIndicator = (TextView) itemView.findViewById(R.id.external_indicator); descriptionView = (TextView) itemView.findViewById(R.id.description); membersCountView = (TextView) itemView.findViewById(R.id.members_count); - subscribersCountView = (TextView) itemView.findViewById(R.id.subscribers_count); + adminsCountView = (TextView) itemView.findViewById(R.id.admins_count); } public void displayGroup(ParcelableGroup group) { - final Context context = adapter.getContext(); final MediaLoaderWrapper loader = adapter.getMediaLoader(); - final UserColorNameManager manager = adapter.getUserColorNameManager(); - - nameView.setText(group.fullname); - final boolean nameFirst = adapter.isNameFirst(); - + nameView.setName(group.fullname); + nameView.setScreenName("!" + group.nickname); + final String groupHost = UserKeyUtils.getUserHost(group.url); + if (UserKeyUtils.isSameHost(group.account_key.getHost(), groupHost)) { + externalIndicator.setVisibility(View.GONE); + } else { + externalIndicator.setVisibility(View.VISIBLE); + externalIndicator.setText(context.getString(R.string.external_user_host_format, + groupHost)); + } if (adapter.isProfileImageEnabled()) { profileImageView.setVisibility(View.VISIBLE); loader.displayProfileImage(profileImageView, group.homepage_logo); @@ -84,7 +89,7 @@ public class GroupViewHolder extends ViewHolder implements View.OnClickListener, descriptionView.setVisibility(TextUtils.isEmpty(group.description) ? View.GONE : View.VISIBLE); descriptionView.setText(group.description); membersCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), group.member_count)); - subscribersCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), group.admin_count)); + adminsCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), group.admin_count)); } public void setOnClickListeners() { @@ -124,8 +129,12 @@ public class GroupViewHolder extends ViewHolder implements View.OnClickListener, } public void setTextSize(final float textSize) { - nameView.setTextSize(textSize); - createdByView.setTextSize(textSize * 0.75f); + descriptionView.setTextSize(textSize); + externalIndicator.setTextSize(textSize); + nameView.setPrimaryTextSize(textSize); + nameView.setSecondaryTextSize(textSize * 0.75f); + membersCountView.setTextSize(textSize); + adminsCountView.setTextSize(textSize); } } diff --git a/twidere/src/main/res/layout/card_item_group_compact.xml b/twidere/src/main/res/layout/card_item_group_compact.xml new file mode 100644 index 000000000..7fe75b823 --- /dev/null +++ b/twidere/src/main/res/layout/card_item_group_compact.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/twidere/src/main/res/values/strings.xml b/twidere/src/main/res/values/strings.xml index 442412595..6c6f3025a 100644 --- a/twidere/src/main/res/values/strings.xml +++ b/twidere/src/main/res/values/strings.xml @@ -757,4 +757,5 @@ Incompatible media uploader Groups External user at %s + External group at %s \ No newline at end of file