improved notifications timeline

This commit is contained in:
Mariotaku Lee 2015-12-14 10:20:55 +08:00
parent f8bededf33
commit 8bc4953e8f
25 changed files with 239 additions and 180 deletions

View File

@ -85,7 +85,7 @@ public interface IntentConstants {
String BROADCAST_USER_LIST_DELETED = INTENT_PACKAGE_PREFIX + "USER_LIST_DELETED";
String BROADCAST_FILTERS_UPDATED = INTENT_PACKAGE_PREFIX + "FILTERS_UPDATED";
String BROADCAST_REFRESH_HOME_TIMELINE = INTENT_PACKAGE_PREFIX + "REFRESH_HOME_TIMELINE";
String BROADCAST_REFRESH_MENTIONS = INTENT_PACKAGE_PREFIX + "REFRESH_MENTIONS";
String BROADCAST_REFRESH_NOTIFICATIONS = INTENT_PACKAGE_PREFIX + "REFRESH_NOTIFICATIONS";
String BROADCAST_REFRESH_DIRECT_MESSAGES = INTENT_PACKAGE_PREFIX + "REFRESH_DIRECT_MESSAGES";
String BROADCAST_REFRESH_TRENDS = INTENT_PACKAGE_PREFIX + "REFRESH_TRENDS";
String BROADCAST_RESCHEDULE_HOME_TIMELINE_REFRESHING = INTENT_PACKAGE_PREFIX

View File

@ -25,7 +25,8 @@ import com.bluelinelabs.logansquare.typeconverters.StringBasedTypeConverter;
* Created by mariotaku on 15/8/18.
*/
public enum TimelineType {
HOME("home"), INTERACTIONS("interactions"), OTHER("other");
HOME("home"), INTERACTIONS("interactions"), DETAILS("details"), SEARCH("search"), USER("user"),
OTHER("other");
private final String value;

View File

@ -40,9 +40,9 @@ import org.mariotaku.twidere.model.ParcelableActivity;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.MediaLoadingHandler;
import org.mariotaku.twidere.util.OnLinkClickHandler;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.ActivityTitleSummaryViewHolder;
import org.mariotaku.twidere.view.holder.GapViewHolder;
@ -55,7 +55,7 @@ import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder;
* Created by mariotaku on 15/1/3.
*/
public abstract class AbsActivitiesAdapter<Data> extends LoadMoreSupportAdapter<ViewHolder> implements Constants,
IActivitiesAdapter<Data>, IStatusViewHolder.StatusClickListener, OnLinkClickListener,
IActivitiesAdapter<Data>, IStatusViewHolder.StatusClickListener,
ActivityTitleSummaryViewHolder.ActivityClickListener {
public static final int ITEM_VIEW_TYPE_STUB = 0;
@ -81,7 +81,7 @@ public abstract class AbsActivitiesAdapter<Data> extends LoadMoreSupportAdapter<
mInflater = LayoutInflater.from(context);
mLoadingHandler = new MediaLoadingHandler(R.id.media_preview_progress);
mCompactCards = compact;
mLinkify = new TwidereLinkify(this);
mLinkify = new TwidereLinkify(new OnLinkClickHandler(context, null));
mStatusAdapterDelegate.updateOptions();
}
@ -142,7 +142,9 @@ public abstract class AbsActivitiesAdapter<Data> extends LoadMoreSupportAdapter<
@Override
public void onMediaClick(IStatusViewHolder holder, View view, ParcelableMedia media, int position) {
if (mActivityAdapterListener != null) {
mActivityAdapterListener.onMediaClick(holder, view, media, position);
}
}
@Override
@ -193,13 +195,13 @@ public abstract class AbsActivitiesAdapter<Data> extends LoadMoreSupportAdapter<
}
case ITEM_VIEW_TYPE_TITLE_SUMMARY: {
final View view;
if (mCompactCards) {
view = mInflater.inflate(R.layout.card_item_activity_summary_compact, parent, false);
} else {
view = mInflater.inflate(R.layout.card_item_activity_summary, parent, false);
final CardView cardView = (CardView) view.findViewById(R.id.card);
cardView.setCardBackgroundColor(mCardBackgroundColor);
}
// if (mCompactCards) {
view = mInflater.inflate(R.layout.card_item_activity_summary_compact, parent, false);
// } else {
// view = mInflater.inflate(R.layout.card_item_activity_summary, parent, false);
// final CardView cardView = (CardView) view.findViewById(R.id.card);
// cardView.setCardBackgroundColor(mCardBackgroundColor);
// }
final ActivityTitleSummaryViewHolder holder = new ActivityTitleSummaryViewHolder(this, view);
holder.setOnClickListeners();
holder.setTextSize(getTextSize());
@ -323,11 +325,6 @@ public abstract class AbsActivitiesAdapter<Data> extends LoadMoreSupportAdapter<
}
}
@Override
public void onLinkClick(String link, String orig, long accountId, long extraId, int type, boolean sensitive, int start, int end) {
}
public void setListener(ActivityAdapterListener listener) {
mActivityAdapterListener = listener;
}
@ -356,7 +353,10 @@ public abstract class AbsActivitiesAdapter<Data> extends LoadMoreSupportAdapter<
void onStatusMenuClick(IStatusViewHolder holder, View menuView, int position);
void onMediaClick(IStatusViewHolder holder, View view, ParcelableMedia media, int position);
void onStatusClick(IStatusViewHolder holder, int position);
}
private static class StubViewHolder extends ViewHolder {

View File

@ -96,6 +96,7 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration {
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final int childPos = parent.getChildAdapterPosition(child);
if (!isDividerEnabled(childPos)) continue;
final int start = getDecorationStart(), end = getDecorationEnd(parent);
if (start >= 0 && childPos < start || end >= 0 && childPos > end) continue;
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
@ -109,6 +110,10 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration {
}
}
protected boolean isDividerEnabled(int childPos) {
return true;
}
public void drawHorizontal(Canvas c, RecyclerView parent) {
if (mDivider == null) return;
final int top = parent.getPaddingTop();
@ -119,6 +124,7 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration {
final View child = parent.getChildAt(i);
final int childPos = parent.getChildAdapterPosition(child);
final int start = getDecorationStart(), end = getDecorationEnd(parent);
if (!isDividerEnabled(childPos)) continue;
if (start >= 0 && childPos < start || end >= 0 && childPos > end) continue;
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
@ -135,6 +141,7 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration {
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
if (mDivider == null) return;
final int childPos = parent.getChildAdapterPosition(view);
if (!isDividerEnabled(childPos)) return;
final int start = getDecorationStart(), end = getDecorationEnd(parent);
if (start >= 0 && childPos < start || end >= 0 && childPos > end) {
outRect.setEmpty();

View File

@ -31,11 +31,9 @@ import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.PopupMenu.OnMenuItemClickListener;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.OnScrollListener;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import com.desmond.asyncmanager.AsyncManager;
@ -44,9 +42,11 @@ import com.squareup.otto.Subscribe;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.AbsActivitiesAdapter;
import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration;
import org.mariotaku.twidere.api.twitter.model.Activity;
import org.mariotaku.twidere.loader.iface.IExtendedLoader;
import org.mariotaku.twidere.model.ParcelableActivity;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
@ -65,7 +65,9 @@ import java.util.Arrays;
import java.util.List;
import edu.tsinghua.hotmobi.HotMobiLogger;
import edu.tsinghua.hotmobi.model.MediaEvent;
import edu.tsinghua.hotmobi.model.ScrollRecord;
import edu.tsinghua.hotmobi.model.TimelineType;
public abstract class AbsActivitiesFragment<Data> extends AbsContentListRecyclerViewFragment<AbsActivitiesAdapter<Data>>
implements LoaderCallbacks<Data>, AbsActivitiesAdapter.ActivityAdapterListener, KeyboardShortcutCallback {
@ -123,24 +125,6 @@ public abstract class AbsActivitiesFragment<Data> extends AbsContentListRecycler
}
};
private RecyclerViewNavigationHelper mNavigationHelper;
private ParcelableActivity mSelectedActivity;
private OnMenuItemClickListener mOnStatusMenuItemClickListener = new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
// final ParcelableActivity activity = mSelectedActivity;
// if (activity == null) return false;
// if (item.getItemId() == R.id.share) {
// final Intent shareIntent = Utils.createStatusShareIntent(getActivity(), activity);
// final Intent chooser = Intent.createChooser(shareIntent, getString(R.string.share_status));
// Utils.addCopyLinkIntent(getContext(), chooser, LinkCreator.getTwitterStatusLink(activity));
// startActivity(chooser);
// return true;
// }
// return Utils.handleMenuItemClick(getActivity(), AbsActivitiesFragment.this,
// getFragmentManager(), mTwitterWrapper, activity, item);
return false;
}
};
private OnScrollListener mPauseOnScrollListener;
private OnScrollListener mActiveHotMobiScrollTracker;
@ -325,19 +309,22 @@ public abstract class AbsActivitiesFragment<Data> extends AbsContentListRecycler
getActivities(accountIds, maxIds, sinceIds);
}
// @Override
// public void onMediaClick(IStatusViewHolder holder, View view, ParcelableMedia media, int position) {
// final AbsActivitiesAdapter<Data> adapter = getAdapter();
// final ParcelableActivity activity = adapter.getActivity(position);
// if (activity == null) return;
// final Bundle options = Utils.createMediaViewerActivityOption(view);
// Utils.openMedia(getActivity(), activity, media, options);
// // BEGIN HotMobi
// final MediaEvent event = MediaEvent.create(getActivity(), activity, media, TimelineType.OTHER,
// adapter.isMediaPreviewEnabled());
// HotMobiLogger.getInstance(getActivity()).log(activity.account_id, event);
// // END HotMobi
// }
@Override
public void onMediaClick(IStatusViewHolder holder, View view, ParcelableMedia media, int position) {
final AbsActivitiesAdapter<Data> adapter = getAdapter();
final ParcelableStatus status = getActivityStatus(adapter.getActivity(position));
if (status == null) return;
final Bundle options = Utils.createMediaViewerActivityOption(view);
Utils.openMedia(getActivity(), status, media, options);
// BEGIN HotMobi
final MediaEvent event = MediaEvent.create(getActivity(), status, media,
getTimelineType(), adapter.isMediaPreviewEnabled());
HotMobiLogger.getInstance(getActivity()).log(status.account_id, event);
// END HotMobi
}
@NonNull
protected abstract TimelineType getTimelineType();
@Override
public void onStatusActionClick(IStatusViewHolder holder, int id, int position) {
@ -381,7 +368,9 @@ public abstract class AbsActivitiesFragment<Data> extends AbsContentListRecycler
case Activity.ACTION_RETWEET:
case Activity.ACTION_RETWEETED_MEDIA_TAGGED:
case Activity.ACTION_RETWEETED_MENTION:
case Activity.ACTION_RETWEETED_RETWEET: {
case Activity.ACTION_RETWEETED_RETWEET:
case Activity.ACTION_FOLLOW:
case Activity.ACTION_JOINED_TWITTER: {
Utils.openUsers(getActivity(), Arrays.asList(activity.sources));
break;
}
@ -574,6 +563,31 @@ public abstract class AbsActivitiesFragment<Data> extends AbsContentListRecycler
return new Rect(0, paddingVertical, 0, paddingVertical);
}
@Override
protected void setupRecyclerView(Context context, boolean compact) {
if (compact) {
super.setupRecyclerView(context, true);
return;
}
final RecyclerView recyclerView = getRecyclerView();
final AbsActivitiesAdapter<Data> adapter = getAdapter();
recyclerView.addItemDecoration(new DividerItemDecoration(context, getLayoutManager().getOrientation()) {
@Override
protected boolean isDividerEnabled(int childPos) {
if (childPos == RecyclerView.NO_POSITION || childPos == adapter.getItemCount() - 1) {
return false;
}
if (adapter.getItemViewType(childPos) != AbsActivitiesAdapter.ITEM_VIEW_TYPE_STATUS) {
if (adapter.getItemViewType(childPos + 1) != AbsActivitiesAdapter.ITEM_VIEW_TYPE_STATUS) {
return true;
}
}
return false;
}
});
}
private String getCurrentReadPositionTag() {
final String tag = getReadPositionTagWithAccounts();
if (tag == null) return null;

View File

@ -332,12 +332,15 @@ public abstract class AbsStatusesFragment<Data> extends AbsContentListRecyclerVi
final Bundle options = Utils.createMediaViewerActivityOption(view);
Utils.openMedia(getActivity(), status, media, options);
// BEGIN HotMobi
final MediaEvent event = MediaEvent.create(getActivity(), status, media, TimelineType.OTHER,
final MediaEvent event = MediaEvent.create(getActivity(), status, media, getTimelineType(),
adapter.isMediaPreviewEnabled());
HotMobiLogger.getInstance(getActivity()).log(status.account_id, event);
// END HotMobi
}
@NonNull
protected abstract TimelineType getTimelineType();
@Override
public void onStatusActionClick(IStatusViewHolder holder, int id, int position) {
final AbsStatusesAdapter<Data> adapter = getAdapter();

View File

@ -20,11 +20,11 @@
package org.mariotaku.twidere.fragment.support;
import android.net.Uri;
import android.view.View;
import android.support.annotation.NonNull;
import org.mariotaku.twidere.provider.TwidereDataStore.Activities;
import org.mariotaku.twidere.view.holder.ActivityTitleSummaryViewHolder;
import org.mariotaku.twidere.view.holder.StatusViewHolder;
import edu.tsinghua.hotmobi.model.TimelineType;
public class ActivitiesAboutMeFragment extends CursorActivitiesFragment {
@ -34,6 +34,12 @@ public class ActivitiesAboutMeFragment extends CursorActivitiesFragment {
return true;
}
@NonNull
@Override
protected TimelineType getTimelineType() {
return TimelineType.INTERACTIONS;
}
@Override
public Uri getContentUri() {
return Activities.AboutMe.CONTENT_URI;
@ -41,22 +47,22 @@ public class ActivitiesAboutMeFragment extends CursorActivitiesFragment {
@Override
protected int getNotificationType() {
return 0;
return NOTIFICATION_ID_MENTIONS_TIMELINE;
}
@Override
protected boolean isFilterEnabled() {
return false;
return true;
}
@Override
protected void updateRefreshState() {
setRefreshing(mTwitterWrapper.isMentionsTimelineRefreshing());
}
@Override
public boolean isRefreshing() {
return false;
return mTwitterWrapper.isMentionsTimelineRefreshing();
}
}

View File

@ -20,9 +20,12 @@
package org.mariotaku.twidere.fragment.support;
import android.net.Uri;
import android.support.annotation.NonNull;
import org.mariotaku.twidere.provider.TwidereDataStore;
import edu.tsinghua.hotmobi.model.TimelineType;
public class ActivitiesByFriendsFragment extends CursorActivitiesFragment {
@ -31,6 +34,12 @@ public class ActivitiesByFriendsFragment extends CursorActivitiesFragment {
return false;
}
@NonNull
@Override
protected TimelineType getTimelineType() {
return TimelineType.OTHER;
}
@Override
public Uri getContentUri() {

View File

@ -58,7 +58,6 @@ import org.mariotaku.twidere.util.message.StatusRetweetedEvent;
import java.util.List;
import static org.mariotaku.twidere.util.Utils.buildStatusFilterWhereClause;
import static org.mariotaku.twidere.util.Utils.getTableNameByUri;
/**
@ -216,7 +215,7 @@ public abstract class CursorActivitiesFragment extends AbsActivitiesFragment<Lis
protected Expression getFiltersWhere(String table) {
if (!isFilterEnabled()) return null;
return buildStatusFilterWhereClause(table, null);
return Utils.buildActivityFilterWhereClause(table, null);
}
protected long[] getNewestActivityIds(long[] accountIds) {

View File

@ -324,8 +324,7 @@ public class DirectMessagesFragment extends AbsContentListRecyclerViewFragment<M
}
protected void updateRefreshState() {
final AsyncTwitterWrapper twitter = mTwitterWrapper;
setRefreshing(twitter != null && (twitter.isReceivedDirectMessagesRefreshing() || twitter.isSentDirectMessagesRefreshing()));
setRefreshing(mTwitterWrapper.isReceivedDirectMessagesRefreshing() || mTwitterWrapper.isSentDirectMessagesRefreshing());
}
private void addReadPosition(final int firstVisibleItem) {

View File

@ -20,11 +20,14 @@
package org.mariotaku.twidere.fragment.support;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import edu.tsinghua.hotmobi.model.TimelineType;
/**
* Created by mariotaku on 14/12/3.
*/
@ -78,6 +81,12 @@ public class HomeTimelineFragment extends CursorStatusesFragment {
}
}
@NonNull
@Override
protected TimelineType getTimelineType() {
return TimelineType.HOME;
}
@Override
protected String getReadPositionTag() {
return TAB_TYPE_HOME_TIMELINE;

View File

@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.Loader;
import org.mariotaku.twidere.loader.support.RetweetsOfMeLoader;
@ -28,12 +29,14 @@ import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
import edu.tsinghua.hotmobi.model.TimelineType;
public class RetweetsOfMeFragment extends ParcelableStatusesFragment {
@Override
protected Loader<List<ParcelableStatus>> onCreateStatusesLoader(final Context context,
final Bundle args,
final boolean fromUser) {
final Bundle args,
final boolean fromUser) {
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
final long maxId = args.getLong(EXTRA_MAX_ID, -1);
final long sinceId = args.getLong(EXTRA_SINCE_ID, -1);
@ -59,4 +62,10 @@ public class RetweetsOfMeFragment extends ParcelableStatusesFragment {
return new String[]{AUTHORITY_RETWEETS_OF_ME, "account" + account_id};
}
@NonNull
@Override
protected TimelineType getTimelineType() {
return TimelineType.INTERACTIONS;
}
}

View File

@ -337,7 +337,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
final Bundle options = Utils.createMediaViewerActivityOption(view);
Utils.openMedia(getActivity(), status, media, options);
MediaEvent event = MediaEvent.create(getActivity(), status, media, TimelineType.OTHER,
MediaEvent event = MediaEvent.create(getActivity(), status, media, TimelineType.DETAILS,
mStatusAdapter.isMediaPreviewEnabled());
HotMobiLogger.getInstance(getActivity()).log(status.account_id, event);
}

View File

@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.Loader;
import org.mariotaku.twidere.loader.support.StatusRepliesLoader;
@ -28,6 +29,8 @@ import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
import edu.tsinghua.hotmobi.model.TimelineType;
public class StatusRepliesListFragment extends StatusesSearchFragment {
@Override
@ -57,4 +60,10 @@ public class StatusRepliesListFragment extends StatusesSearchFragment {
"status_id" + statusId};
}
@NonNull
@Override
protected TimelineType getTimelineType() {
return TimelineType.DETAILS;
}
}

View File

@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.Loader;
import org.mariotaku.twidere.loader.support.IntentExtrasStatusesLoader;
@ -28,6 +29,8 @@ import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
import edu.tsinghua.hotmobi.model.TimelineType;
public class StatusesListFragment extends ParcelableStatusesFragment {
@Override
@ -56,4 +59,11 @@ public class StatusesListFragment extends ParcelableStatusesFragment {
// return false;
// }
@NonNull
@Override
protected TimelineType getTimelineType() {
return TimelineType.OTHER;
}
}

View File

@ -22,6 +22,7 @@ package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.Loader;
import org.mariotaku.twidere.loader.support.TweetSearchLoader;
@ -29,11 +30,19 @@ import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
import edu.tsinghua.hotmobi.model.TimelineType;
/**
* Created by mariotaku on 14/12/2.
*/
public class StatusesSearchFragment extends ParcelableStatusesFragment {
@NonNull
@Override
protected TimelineType getTimelineType() {
return TimelineType.SEARCH;
}
@Override
protected Loader<List<ParcelableStatus>> onCreateStatusesLoader(final Context context,
final Bundle args,

View File

@ -21,14 +21,16 @@ package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.Loader;
import org.mariotaku.twidere.loader.support.UserFavoritesLoader;
import org.mariotaku.twidere.model.ListResponse;
import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
import edu.tsinghua.hotmobi.model.TimelineType;
/**
* Created by mariotaku on 14/12/2.
*/
@ -59,4 +61,9 @@ public class UserFavoritesFragment extends ParcelableStatusesFragment {
return new String[]{AUTHORITY_USER_FAVORITES, "account" + accountId, "user" + userId, "name" + screenName};
}
@NonNull
@Override
protected TimelineType getTimelineType() {
return TimelineType.OTHER;
}
}

View File

@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.Loader;
import org.mariotaku.twidere.loader.support.UserListTimelineLoader;
@ -28,11 +29,19 @@ import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
import edu.tsinghua.hotmobi.model.TimelineType;
/**
* Created by mariotaku on 14/12/2.
*/
public class UserListTimelineFragment extends ParcelableStatusesFragment {
@NonNull
@Override
protected TimelineType getTimelineType() {
return TimelineType.OTHER;
}
@Override
protected Loader<List<ParcelableStatus>> onCreateStatusesLoader(final Context context,
final Bundle args,

View File

@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.Loader;
import org.mariotaku.twidere.loader.support.UserMentionsLoader;
@ -28,6 +29,8 @@ import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
import edu.tsinghua.hotmobi.model.TimelineType;
public class UserMentionsFragment extends StatusesSearchFragment {
@Override
@ -56,4 +59,10 @@ public class UserMentionsFragment extends StatusesSearchFragment {
return new String[]{AUTHORITY_USER_MENTIONS, "account" + account_id, "screen_name" + screen_name};
}
@NonNull
@Override
protected TimelineType getTimelineType() {
return TimelineType.OTHER;
}
}

View File

@ -21,19 +21,27 @@ package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.Loader;
import org.mariotaku.twidere.loader.support.UserTimelineLoader;
import org.mariotaku.twidere.model.ListResponse;
import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
import edu.tsinghua.hotmobi.model.TimelineType;
/**
* Created by mariotaku on 14/12/2.
*/
public class UserTimelineFragment extends ParcelableStatusesFragment {
@NonNull
@Override
protected TimelineType getTimelineType() {
return TimelineType.USER;
}
@Override
protected Loader<List<ParcelableStatus>> onCreateStatusesLoader(final Context context,
final Bundle args,

View File

@ -35,7 +35,6 @@ import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.model.AccountPreferences;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
import org.mariotaku.twidere.provider.TwidereDataStore.Mentions;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.receiver.PowerStateReceiver;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
@ -53,8 +52,6 @@ import edu.tsinghua.hotmobi.model.ScreenEvent;
import static org.mariotaku.twidere.util.Utils.getAccountIds;
import static org.mariotaku.twidere.util.Utils.getDefaultAccountId;
import static org.mariotaku.twidere.util.DataStoreUtils.getNewestMessageIdsFromDatabase;
import static org.mariotaku.twidere.util.DataStoreUtils.getNewestStatusIdsFromDatabase;
import static org.mariotaku.twidere.util.Utils.hasAutoRefreshAccounts;
import static org.mariotaku.twidere.util.Utils.isBatteryOkay;
import static org.mariotaku.twidere.util.Utils.isNetworkAvailable;
@ -99,14 +96,13 @@ public class RefreshService extends Service implements Constants {
if (!isHomeTimelineRefreshing()) {
getHomeTimeline(refreshIds, null, sinceIds);
}
} else if (BROADCAST_REFRESH_MENTIONS.equals(action)) {
} else if (BROADCAST_REFRESH_NOTIFICATIONS.equals(action)) {
final long[] refreshIds = getRefreshableIds(accountPrefs, new MentionsRefreshableFilter());
final long[] sinceIds = DataStoreUtils.getNewestStatusIdsFromDatabase(context, Mentions.CONTENT_URI, refreshIds);
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, String.format("Auto refreshing mentions for %s", Arrays.toString(refreshIds)));
Log.d(LOGTAG, String.format("Auto refreshing notifications for %s", Arrays.toString(refreshIds)));
}
if (!isMentionsRefreshing()) {
getMentions(refreshIds, null, sinceIds);
if (!isActivitiesAboutMeRefreshing()) {
getActivitiesAboutMe(refreshIds, null, null);
}
} else if (BROADCAST_REFRESH_DIRECT_MESSAGES.equals(action)) {
final long[] refreshIds = getRefreshableIds(accountPrefs, new MessagesRefreshableFilter());
@ -189,13 +185,13 @@ public class RefreshService extends Service implements Constants {
mAlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
mPendingRefreshHomeTimelineIntent = PendingIntent.getBroadcast(this, 0, new Intent(
BROADCAST_REFRESH_HOME_TIMELINE), 0);
mPendingRefreshMentionsIntent = PendingIntent.getBroadcast(this, 0, new Intent(BROADCAST_REFRESH_MENTIONS), 0);
mPendingRefreshMentionsIntent = PendingIntent.getBroadcast(this, 0, new Intent(BROADCAST_REFRESH_NOTIFICATIONS), 0);
mPendingRefreshDirectMessagesIntent = PendingIntent.getBroadcast(this, 0, new Intent(
BROADCAST_REFRESH_DIRECT_MESSAGES), 0);
mPendingRefreshTrendsIntent = PendingIntent.getBroadcast(this, 0, new Intent(BROADCAST_REFRESH_TRENDS), 0);
final IntentFilter refreshFilter = new IntentFilter(BROADCAST_NOTIFICATION_DELETED);
refreshFilter.addAction(BROADCAST_REFRESH_HOME_TIMELINE);
refreshFilter.addAction(BROADCAST_REFRESH_MENTIONS);
refreshFilter.addAction(BROADCAST_REFRESH_NOTIFICATIONS);
refreshFilter.addAction(BROADCAST_REFRESH_DIRECT_MESSAGES);
refreshFilter.addAction(BROADCAST_RESCHEDULE_HOME_TIMELINE_REFRESHING);
refreshFilter.addAction(BROADCAST_RESCHEDULE_MENTIONS_REFRESHING);
@ -245,8 +241,9 @@ public class RefreshService extends Service implements Constants {
return mTwitterWrapper.getLocalTrendsAsync(account_id, woeid);
}
private boolean getMentions(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
return mTwitterWrapper.getMentionsTimelineAsync(accountIds, maxIds, sinceIds);
private boolean getActivitiesAboutMe(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
mTwitterWrapper.getActivitiesAboutMeAsync(accountIds, maxIds, sinceIds);
return true;
}
private int getReceivedDirectMessages(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
@ -281,7 +278,7 @@ public class RefreshService extends Service implements Constants {
return mTwitterWrapper.isLocalTrendsRefreshing();
}
private boolean isMentionsRefreshing() {
private boolean isActivitiesAboutMeRefreshing() {
return mTwitterWrapper.isMentionsTimelineRefreshing();
}

View File

@ -59,7 +59,6 @@ import org.mariotaku.twidere.api.twitter.model.Trends;
import org.mariotaku.twidere.api.twitter.model.User;
import org.mariotaku.twidere.api.twitter.model.UserList;
import org.mariotaku.twidere.api.twitter.model.UserListUpdate;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.model.ListResponse;
import org.mariotaku.twidere.model.ParcelableAccount;
import org.mariotaku.twidere.model.ParcelableActivity;
@ -89,7 +88,6 @@ import org.mariotaku.twidere.task.CacheUsersStatusesTask;
import org.mariotaku.twidere.task.ManagedAsyncTask;
import org.mariotaku.twidere.util.collection.LongSparseMap;
import org.mariotaku.twidere.util.content.ContentResolverUtils;
import org.mariotaku.twidere.util.dagger.ApplicationModule;
import org.mariotaku.twidere.util.message.FavoriteCreatedEvent;
import org.mariotaku.twidere.util.message.FavoriteDestroyedEvent;
import org.mariotaku.twidere.util.message.FriendshipUpdatedEvent;
@ -122,6 +120,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
private final SharedPreferencesWrapper mPreferences;
private final ContentResolver mResolver;
private final Bus mBus;
private final UserColorNameManager mUserColorNameManager;
private int mGetHomeTimelineTaskId, mGetMentionsTaskId;
private int mGetReceivedDirectMessagesTaskId, mGetSentDirectMessagesTaskId;
@ -134,12 +133,15 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
private CopyOnWriteArraySet<Long> mSendingDraftIds = new CopyOnWriteArraySet<>();
public AsyncTwitterWrapper(final Context context, final AsyncTaskManager manager, final SharedPreferencesWrapper preferences, final Bus bus) {
public AsyncTwitterWrapper(final Context context, final AsyncTaskManager manager,
final SharedPreferencesWrapper preferences, final Bus bus,
final UserColorNameManager userColorNameManager) {
mContext = context;
mAsyncTaskManager = manager;
mPreferences = preferences;
mResolver = context.getContentResolver();
mBus = bus;
mUserColorNameManager = userColorNameManager;
}
public int acceptFriendshipAsync(final long accountId, final long userId) {
@ -297,13 +299,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
return mGetLocalTrendsTaskId = mAsyncTaskManager.add(task, true);
}
public boolean getMentionsTimelineAsync(final long[] accountIds, final long[] max_ids, final long[] since_ids) {
mAsyncTaskManager.cancel(mGetMentionsTaskId);
final GetMentionsTask task = new GetMentionsTask(accountIds, max_ids, since_ids);
mGetMentionsTaskId = mAsyncTaskManager.add(task, true);
return true;
}
public int getReceivedDirectMessagesAsync(final long[] accountIds, final long[] max_ids, final long[] since_ids) {
mAsyncTaskManager.cancel(mGetReceivedDirectMessagesTaskId);
final GetReceivedDirectMessagesTask task = new GetReceivedDirectMessagesTask(accountIds, max_ids, since_ids);
@ -425,7 +420,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
protected void onPostExecute(Object[] result) {
getHomeTimelineAsync(accountIds, null, (long[]) result[0]);
if (Boolean.TRUE.equals(result[1])) {
getMentionsTimelineAsync(accountIds, null, (long[]) result[2]);
getActivitiesAboutMeAsync(accountIds, null, null);
}
if (Boolean.TRUE.equals(result[3])) {
@ -539,7 +533,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
public void getActivitiesAboutMeAsync(long[] accountIds, long[] maxIds, long[] sinceIds) {
mAsyncTaskManager.add(new GetActivitiesTask(this, accountIds, maxIds, sinceIds) {
mAsyncTaskManager.add(new GetActivitiesTask(this, TASK_TAG_GET_MENTIONS, accountIds, maxIds, sinceIds) {
@Override
protected ResponseList<Activity> getActivities(long accountId, Twitter twitter, Paging paging) throws TwitterException {
@ -561,7 +555,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
public void getActivitiesByFriendsAsync(long[] accountIds, long[] maxIds, long[] sinceIds) {
mAsyncTaskManager.add(new GetActivitiesTask(this, accountIds, maxIds, sinceIds) {
mAsyncTaskManager.add(new GetActivitiesTask(this, "get_activities_by_friends", accountIds, maxIds, sinceIds) {
@Override
protected ResponseList<Activity> getActivities(long accountId, Twitter twitter, Paging paging) throws TwitterException {
@ -582,8 +576,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
private final long[] maxIds;
private final long[] sinceIds;
public GetActivitiesTask(AsyncTwitterWrapper twitterWrapper, long[] accountIds, long[] maxIds, long[] sinceIds) {
super(twitterWrapper.getContext(), "get_activities");
public GetActivitiesTask(AsyncTwitterWrapper twitterWrapper, String tag, long[] accountIds, long[] maxIds, long[] sinceIds) {
super(twitterWrapper.getContext(), tag);
this.twitterWrapper = twitterWrapper;
this.accountIds = accountIds;
this.maxIds = maxIds;
@ -828,11 +822,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
protected void onPostExecute(final SingleResponse<User> result) {
if (result.hasData()) {
final User user = result.getData();
final TwidereApplication application = TwidereApplication.getInstance(mContext);
final UserColorNameManager manager = ApplicationModule.get(mContext).getUserColorNameManager();
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
final String message = mContext.getString(R.string.accepted_users_follow_request,
manager.getDisplayName(user, nameFirst, true));
mUserColorNameManager.getDisplayName(user, nameFirst, true));
Utils.showOkMessage(mContext, message, false);
} else {
Utils.showErrorMessage(mContext, R.string.action_accepting_follow_request,
@ -883,9 +875,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
final String message;
if (users.length == 1) {
final ParcelableUser user = users[0];
final UserColorNameManager manager = ApplicationModule.get(mContext).getUserColorNameManager();
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
final String displayName = manager.getDisplayName(user.id, user.name, user.screen_name, nameFirst, false);
final String displayName = mUserColorNameManager.getDisplayName(user.id, user.name,
user.screen_name, nameFirst, false);
message = mContext.getString(R.string.added_user_to_list, displayName, result.getData().name);
} else {
final Resources res = mContext.getResources();
@ -973,10 +965,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
@Override
protected void onPostExecute(final SingleResponse<ParcelableUser> result) {
if (result.hasData()) {
final UserColorNameManager manager = ApplicationModule.get(mContext).getUserColorNameManager();
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
final String message = mContext.getString(R.string.blocked_user,
manager.getDisplayName(result.getData(), nameFirst, true));
mUserColorNameManager.getDisplayName(result.getData(), nameFirst, true));
Utils.showInfoMessage(mContext, message, false);
@ -1095,14 +1086,13 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
if (result.hasData()) {
final ParcelableUser user = result.getData();
final String message;
final UserColorNameManager manager = ApplicationModule.get(mContext).getUserColorNameManager();
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
if (user.is_protected) {
message = mContext.getString(R.string.sent_follow_request_to_user,
manager.getDisplayName(user, nameFirst, true));
mUserColorNameManager.getDisplayName(user, nameFirst, true));
} else {
message = mContext.getString(R.string.followed_user,
manager.getDisplayName(user, nameFirst, true));
mUserColorNameManager.getDisplayName(user, nameFirst, true));
}
Utils.showOkMessage(mContext, message, false);
@ -1210,10 +1200,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
@Override
protected void onPostExecute(final SingleResponse<ParcelableUser> result) {
if (result.hasData()) {
final UserColorNameManager manager = ApplicationModule.get(mContext).getUserColorNameManager();
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
final String message = mContext.getString(R.string.muted_user,
manager.getDisplayName(result.getData(), nameFirst, true));
mUserColorNameManager.getDisplayName(result.getData(), nameFirst, true));
Utils.showInfoMessage(mContext, message, false);
@ -1395,10 +1384,11 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
if (succeed) {
if (users.length == 1) {
final ParcelableUser user = users[0];
final UserColorNameManager manager = ApplicationModule.get(mContext).getUserColorNameManager();
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
final String displayName = manager.getDisplayName(user.id, user.name, user.screen_name, nameFirst, false);
message = mContext.getString(R.string.deleted_user_from_list, displayName, result.getData().name);
final String displayName = mUserColorNameManager.getDisplayName(user.id,
user.name, user.screen_name, nameFirst, false);
message = mContext.getString(R.string.deleted_user_from_list, displayName,
result.getData().name);
} else {
final Resources res = mContext.getResources();
message = res.getQuantityString(R.plurals.deleted_N_users_from_list, users.length, users.length,
@ -1453,10 +1443,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
protected void onPostExecute(final SingleResponse<User> result) {
if (result.hasData()) {
final User user = result.getData();
final UserColorNameManager manager = ApplicationModule.get(mContext).getUserColorNameManager();
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
final String message = mContext.getString(R.string.denied_users_follow_request,
manager.getDisplayName(user, nameFirst, true));
mUserColorNameManager.getDisplayName(user, nameFirst, true));
Utils.showOkMessage(mContext, message, false);
} else {
Utils.showErrorMessage(mContext, R.string.action_denying_follow_request, result.getException(), false);
@ -1497,10 +1486,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
@Override
protected void onPostExecute(final SingleResponse<ParcelableUser> result) {
if (result.hasData()) {
final UserColorNameManager manager = ApplicationModule.get(mContext).getUserColorNameManager();
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
final String message = mContext.getString(R.string.unblocked_user,
manager.getDisplayName(result.getData(), nameFirst, true));
mUserColorNameManager.getDisplayName(result.getData(), nameFirst, true));
Utils.showInfoMessage(mContext, message, false);
@ -1738,10 +1726,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
@Override
protected void onPostExecute(final SingleResponse<ParcelableUser> result) {
if (result.hasData()) {
final UserColorNameManager manager = ApplicationModule.get(mContext).getUserColorNameManager();
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
final String message = mContext.getString(R.string.unfollowed_user,
manager.getDisplayName(result.getData(), nameFirst, true));
mUserColorNameManager.getDisplayName(result.getData(), nameFirst, true));
Utils.showInfoMessage(mContext, message, false);
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
} else {
@ -1780,10 +1767,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
@Override
protected void onPostExecute(final SingleResponse<ParcelableUser> result) {
if (result.hasData()) {
final UserColorNameManager manager = ApplicationModule.get(mContext).getUserColorNameManager();
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
final String message = mContext.getString(R.string.unmuted_user,
manager.getDisplayName(result.getData(), nameFirst, true));
mUserColorNameManager.getDisplayName(result.getData(), nameFirst, true));
Utils.showInfoMessage(mContext, message, false);
@ -2154,46 +2140,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
class GetMentionsTask extends GetStatusesTask {
public GetMentionsTask(final long[] account_ids, final long[] max_ids, final long[] since_ids) {
super(account_ids, max_ids, since_ids, TASK_TAG_GET_MENTIONS);
}
@Override
public ResponseList<org.mariotaku.twidere.api.twitter.model.Status> getStatuses(final Twitter twitter, final Paging paging)
throws TwitterException {
return twitter.getMentionsTimeline(paging);
}
@NonNull
@Override
protected Uri getDatabaseUri() {
return Mentions.CONTENT_URI;
}
@Override
protected TimelineType getTimelineType() {
return TimelineType.INTERACTIONS;
}
@Override
protected void onPostExecute(final List<StatusListResponse> result) {
super.onPostExecute(result);
mGetMentionsTaskId = -1;
}
@Override
protected void onPreExecute() {
final Intent intent = new Intent(BROADCAST_RESCHEDULE_MENTIONS_REFRESHING);
mContext.sendBroadcast(intent);
super.onPreExecute();
}
}
class GetReceivedDirectMessagesTask extends GetDirectMessagesTask {
public GetReceivedDirectMessagesTask(final long[] account_ids, final long[] max_ids, final long[] since_ids) {

View File

@ -101,7 +101,6 @@ public class ApplicationModule {
notificationManagerWrapper = new NotificationManagerWrapper(application);
asyncTwitterWrapper = new AsyncTwitterWrapper(application, asyncTaskManager, sharedPreferences, bus);
restHttpClient = TwitterAPIFactory.getDefaultHttpClient(application, dns);
imageDownloader = new TwidereImageDownloader(application, restHttpClient, true);
imageLoader = createImageLoader(application, imageDownloader);
@ -111,6 +110,8 @@ public class ApplicationModule {
userColorNameManager = new UserColorNameManager(application);
keyboardShortcutsHandler = new KeyboardShortcutsHandler(application);
hotMobiLogger = new HotMobiLogger(application);
asyncTwitterWrapper = new AsyncTwitterWrapper(application, asyncTaskManager,
sharedPreferences, bus, userColorNameManager);
}
public static ApplicationModule get(@NonNull Context context) {

View File

@ -46,6 +46,7 @@ import org.mariotaku.twidere.provider.TwidereDataProvider;
import org.mariotaku.twidere.service.BackgroundOperationService;
import org.mariotaku.twidere.service.RefreshService;
import org.mariotaku.twidere.task.ManagedAsyncTask;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.MultiSelectEventHandler;
import org.mariotaku.twidere.view.holder.StatusViewHolder;

View File

@ -17,9 +17,10 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<org.mariotaku.twidere.view.ColorLabelRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<org.mariotaku.twidere.view.ColorLabelRelativeLayout
android:id="@+id/item_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
@ -36,7 +37,7 @@
android:layout_alignRight="@+id/profile_image_space"
android:layout_alignTop="@+id/profile_images_container"
android:scaleType="centerInside"
tools:src="@drawable/ic_indicator_retweet" />
tools:src="@drawable/ic_indicator_retweet"/>
<LinearLayout
android:id="@+id/profile_images_container"
@ -55,7 +56,7 @@
android:layout_width="@dimen/profile_image_size_activity_small"
android:layout_height="@dimen/profile_image_size_activity_small"
android:layout_margin="2dp"
android:contentDescription="@string/profile_image" />
android:contentDescription="@string/profile_image"/>
<org.mariotaku.twidere.view.ShapedImageView
android:id="@+id/activity_profile_image_1"
@ -63,7 +64,7 @@
android:layout_width="@dimen/profile_image_size_activity_small"
android:layout_height="@dimen/profile_image_size_activity_small"
android:layout_margin="2dp"
android:contentDescription="@string/profile_image" />
android:contentDescription="@string/profile_image"/>
<org.mariotaku.twidere.view.ShapedImageView
android:id="@+id/activity_profile_image_2"
@ -71,7 +72,7 @@
android:layout_width="@dimen/profile_image_size_activity_small"
android:layout_height="@dimen/profile_image_size_activity_small"
android:layout_margin="2dp"
android:contentDescription="@string/profile_image" />
android:contentDescription="@string/profile_image"/>
<org.mariotaku.twidere.view.ShapedImageView
android:id="@+id/activity_profile_image_3"
@ -79,7 +80,7 @@
android:layout_width="@dimen/profile_image_size_activity_small"
android:layout_height="@dimen/profile_image_size_activity_small"
android:layout_margin="2dp"
android:contentDescription="@string/profile_image" />
android:contentDescription="@string/profile_image"/>
<org.mariotaku.twidere.view.ShapedImageView
android:id="@+id/activity_profile_image_4"
@ -87,21 +88,17 @@
android:layout_width="@dimen/profile_image_size_activity_small"
android:layout_height="@dimen/profile_image_size_activity_small"
android:layout_margin="2dp"
android:contentDescription="@string/profile_image" />
android:contentDescription="@string/profile_image"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<org.mariotaku.twidere.view.BadgeView
android:id="@+id/activity_profile_image_more_number"
android:layout_width="0dp"
android:layout_height="wrap_content"
style="?profileImageStyle"
android:layout_width="@dimen/profile_image_size_activity_small"
android:layout_height="@dimen/profile_image_size_activity_small"
android:layout_margin="2dp"
android:layout_weight="1"
android:gravity="center"
android:minHeight="@dimen/profile_image_size_activity_small"
android:minWidth="@dimen/profile_image_size_activity_small"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold"
tools:text="11" />
tools:text="11"/>
</LinearLayout>
<Space
@ -109,7 +106,7 @@
android:layout_width="@dimen/icon_size_status_profile_image"
android:layout_height="0dp"
android:layout_alignWithParentIfMissing="true"
android:layout_below="@+id/profile_images_container" />
android:layout_below="@+id/profile_images_container"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
android:id="@+id/title"
@ -134,6 +131,6 @@
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorSecondary"
tools:text="@string/sample_status_text"
tools:textSize="@dimen/text_size_extra_small" />
tools:textSize="@dimen/text_size_extra_small"/>
</org.mariotaku.twidere.view.ColorLabelRelativeLayout>