diff --git a/resources/Twidere Icon Assets.sketch b/resources/Twidere Icon Assets.sketch index d9c0f928b..9041551ef 100644 Binary files a/resources/Twidere Icon Assets.sketch and b/resources/Twidere Icon Assets.sketch differ diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/Activity.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/Activity.java index 191963637..b5aab19cd 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/Activity.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/Activity.java @@ -193,5 +193,6 @@ public class Activity extends TwitterResponseObject implements TwitterResponse, String FAVORITED_MEDIA_TAGGED = ("favorited_media_tagged"); String RETWEETED_MEDIA_TAGGED = ("retweeted_media_tagged"); + String[] MENTION_ACTIONS = {MENTION, REPLY, QUOTE}; } } \ No newline at end of file diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ErrorInfo.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ErrorInfo.java index 5be8e3605..3bebfde4f 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ErrorInfo.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ErrorInfo.java @@ -28,6 +28,12 @@ import com.bluelinelabs.logansquare.annotation.JsonObject; @JsonObject public class ErrorInfo { + public static final int PAGE_NOT_FOUND = 34; + public static final int RATE_LIMIT_EXCEEDED = 88; + public static final int NOT_AUTHORIZED = 179; + public static final int STATUS_IS_DUPLICATE = 187; + public static final int NO_DIRECT_MESSAGE_PERMISSION = 93; + @JsonField(name = "code") int code; @JsonField(name = "message") diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java index 499401cbd..690bc4898 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java @@ -209,6 +209,7 @@ public interface IntentConstants { String EXTRA_CURRENT_MEDIA = "current_media"; String EXTRA_EXTRAS = "extras"; String EXTRA_MY_FOLLOWING_ONLY = "my_following_only"; + String EXTRA_MENTIONS_ONLY = "mentions_only"; String EXTRA_CHANGED = "changed"; String EXTRA_NOTIFY_CHANGE = "notify_change"; String EXTRA_RESTART_ACTIVITY = "restart_activity"; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java index eb2923e73..24f19b697 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java @@ -265,6 +265,7 @@ public interface SharedPreferenceConstants { String KEY_NOTIFICATION_TYPE_MENTIONS = "notification_type_mentions"; String KEY_NOTIFICATION_TYPE_DIRECT_MESSAGES = "notification_type_direct_messages"; String KEY_NOTIFICATION_FOLLOWING_ONLY = "notification_following_only"; + String KEY_NOTIFICATION_MENTIONS_ONLY = "notification_mentions_only"; @Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false) String KEY_PEBBLE_NOTIFICATIONS = "pebble_notifications"; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java index 98d2eb5e8..aeb09f9d5 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java @@ -893,7 +893,6 @@ public interface TwidereDataStore { String ACCOUNT_ID = "account_id"; String ACTION = "action"; - String RAW_ACTION = "raw_action"; String TIMESTAMP = "timestamp"; String STATUS_ID = "status_id"; String STATUS_RETWEET_ID = "status_retweet_id"; @@ -925,7 +924,7 @@ public interface TwidereDataStore { IS_GAP, MIN_POSITION, MAX_POSITION, SOURCES, SOURCE_IDS, TARGET_STATUSES, TARGET_USERS, TARGET_USER_LISTS, TARGET_OBJECT_STATUSES, TARGET_OBJECT_USER_LISTS, TARGET_OBJECT_USERS, STATUS_RETWEET_ID, STATUS_USER_FOLLOWING, INSERTED_DATE}; - String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, + String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_INT, TYPE_TEXT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_BOOLEAN, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_BOOLEAN, INSERTED_DATE_TYPE}; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/util/TwidereArrayUtils.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/util/TwidereArrayUtils.java index 728327495..83ec1506e 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/util/TwidereArrayUtils.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/util/TwidereArrayUtils.java @@ -87,27 +87,13 @@ public final class TwidereArrayUtils { } @SuppressWarnings("SuspiciousSystemArraycopy") - public static void mergeArray(final Object dest, final Object... arrays) { - if (arrays == null || arrays.length == 0) return; - if (arrays.length == 1) { - final Object array = arrays[0]; - System.arraycopy(array, 0, dest, 0, Array.getLength(array)); - return; + public static void mergeArray(final Object dest, @NonNull final Object... arrays) { + for (int i = 0, j = arrays.length, k = 0; i < j; i++) { + final Object array = arrays[i]; + final int length = Array.getLength(array); + System.arraycopy(array, 0, dest, k, length); + k += length; } - for (int i = 0, j = arrays.length - 1; i < j; i++) { - final Object array1 = arrays[i], array2 = arrays[i + 1]; - System.arraycopy(array1, 0, dest, 0, Array.getLength(array1)); - System.arraycopy(array2, 0, dest, Array.getLength(array1), Array.getLength(array2)); - } - } - - public static String mergeArrayToString(final String[] array) { - if (array == null) return null; - final StringBuilder builder = new StringBuilder(); - for (final String c : array) { - builder.append(c); - } - return builder.toString(); } public static long min(final long[] array) { diff --git a/twidere/src/androidTest/java/org/mariotaku/twidere/util/TwidereArrayUtilsTest.java b/twidere/src/androidTest/java/org/mariotaku/twidere/util/TwidereArrayUtilsTest.java new file mode 100644 index 000000000..fcde70abc --- /dev/null +++ b/twidere/src/androidTest/java/org/mariotaku/twidere/util/TwidereArrayUtilsTest.java @@ -0,0 +1,14 @@ +package org.mariotaku.twidere.util; + + +import org.junit.Test; + +/** + * Created by mariotaku on 16/1/31. + */ +public class TwidereArrayUtilsTest { + + @Test + public void testMergeArray() throws Exception { + } +} \ No newline at end of file diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java index 16b47baaa..3ab59f545 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java @@ -67,12 +67,14 @@ import com.squareup.otto.Subscribe; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.math.NumberUtils; +import org.mariotaku.sqliteqb.library.Expression; import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.SettingsActivity; import org.mariotaku.twidere.activity.SettingsWizardActivity; import org.mariotaku.twidere.activity.UsageStatisticsActivity; import org.mariotaku.twidere.adapter.support.SupportTabsAdapter; import org.mariotaku.twidere.annotation.CustomTabType; +import org.mariotaku.twidere.api.twitter.model.Activity; import org.mariotaku.twidere.fragment.CustomTabsFragment; import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface; import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback; @@ -955,8 +957,20 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen final String tagWithAccounts = Utils.getReadPositionTagWithAccounts(mContext, true, spec.tag, accountIds); final long position = mReadStateManager.getPosition(tagWithAccounts); + + Expression extraWhere = null; + String[] extraWhereArgs = null; + if (spec.args != null) { + Bundle extras = spec.args.getBundle(EXTRA_EXTRAS); + if (extras != null && extras.getBoolean(EXTRA_MENTIONS_ONLY)) { + extraWhere = Expression.inArgs(Activities.ACTION, 3); + extraWhereArgs = new String[]{Activity.Action.MENTION, + Activity.Action.REPLY, Activity.Action.QUOTE}; + } + } result.put(spec.position, DataStoreUtils.getActivitiesCount(mContext, - Activities.AboutMe.CONTENT_URI, position, accountIds)); + Activities.AboutMe.CONTENT_URI, extraWhere, extraWhereArgs, + position, accountIds)); break; } case CustomTabType.DIRECT_MESSAGES: { diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/MediaViewerActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/MediaViewerActivity.java index 7812402d3..8751e2a94 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/MediaViewerActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/MediaViewerActivity.java @@ -116,7 +116,7 @@ public final class MediaViewerActivity extends AbsMediaViewerActivity implements @Override public void setBarVisibility(boolean visible) { - ActionBar actionBar = getSupportActionBar(); + final ActionBar actionBar = getSupportActionBar(); if (actionBar == null) return; if (visible) { actionBar.show(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java index 57ef23e45..873d0d2a3 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java @@ -79,6 +79,7 @@ public abstract class AbsActivitiesAdapter extends LoadMoreSupportAdapter< long[] mFilteredUserIds; boolean mFollowingOnly; + boolean mMentionsOnly; protected AbsActivitiesAdapter(final Context context, boolean compact) { @@ -245,35 +246,44 @@ public abstract class AbsActivitiesAdapter extends LoadMoreSupportAdapter< return ITEM_VIEW_TYPE_GAP; } final String action = getActivityAction(position); - if (Activity.Action.MENTION.equals(action)) { - if (ArrayUtils.isEmpty(activity.target_object_statuses)) { - return ITEM_VIEW_TYPE_STUB; + switch (action) { + case Activity.Action.MENTION: { + if (ArrayUtils.isEmpty(activity.target_object_statuses)) { + return ITEM_VIEW_TYPE_STUB; + } + if (mFollowingOnly && !activity.status_user_following) return ITEM_VIEW_TYPE_EMPTY; + return ITEM_VIEW_TYPE_STATUS; } - if (mFollowingOnly && !activity.status_user_following) return ITEM_VIEW_TYPE_EMPTY; - return ITEM_VIEW_TYPE_STATUS; - } else if (Activity.Action.REPLY.equals(action)) { - if (ArrayUtils.isEmpty(activity.target_statuses)) { - return ITEM_VIEW_TYPE_STUB; + case Activity.Action.REPLY: { + if (ArrayUtils.isEmpty(activity.target_statuses)) { + return ITEM_VIEW_TYPE_STUB; + } + if (mFollowingOnly && !activity.status_user_following) return ITEM_VIEW_TYPE_EMPTY; + return ITEM_VIEW_TYPE_STATUS; } - if (mFollowingOnly && !activity.status_user_following) return ITEM_VIEW_TYPE_EMPTY; - return ITEM_VIEW_TYPE_STATUS; - } else if (Activity.Action.QUOTE.equals(action)) { - if (ArrayUtils.isEmpty(activity.target_statuses)) { - return ITEM_VIEW_TYPE_STUB; + case Activity.Action.QUOTE: { + if (ArrayUtils.isEmpty(activity.target_statuses)) { + return ITEM_VIEW_TYPE_STUB; + } + if (mFollowingOnly && !activity.status_user_following) return ITEM_VIEW_TYPE_EMPTY; + return ITEM_VIEW_TYPE_STATUS; } - if (mFollowingOnly && !activity.status_user_following) return ITEM_VIEW_TYPE_EMPTY; - return ITEM_VIEW_TYPE_STATUS; - } else if (Activity.Action.FOLLOW.equals(action) || Activity.Action.FAVORITE.equals(action) - || Activity.Action.RETWEET.equals(action) || Activity.Action.FAVORITED_RETWEET.equals(action) - || Activity.Action.RETWEETED_RETWEET.equals(action) || Activity.Action.RETWEETED_MENTION.equals(action) - || Activity.Action.FAVORITED_MENTION.equals(action) || Activity.Action.LIST_CREATED.equals(action) - || Activity.Action.LIST_MEMBER_ADDED.equals(action)) { - ParcelableActivityUtils.getAfterFilteredSourceIds(activity, mFilteredUserIds, - mFollowingOnly); - if (ArrayUtils.isEmpty(activity.after_filtered_source_ids)) { - return ITEM_VIEW_TYPE_EMPTY; + case Activity.Action.FOLLOW: + case Activity.Action.FAVORITE: + case Activity.Action.RETWEET: + case Activity.Action.FAVORITED_RETWEET: + case Activity.Action.RETWEETED_RETWEET: + case Activity.Action.RETWEETED_MENTION: + case Activity.Action.FAVORITED_MENTION: + case Activity.Action.LIST_CREATED: + case Activity.Action.LIST_MEMBER_ADDED: { + if (mMentionsOnly) return ITEM_VIEW_TYPE_EMPTY; + ParcelableActivityUtils.initAfterFilteredSourceIds(activity, mFilteredUserIds, mFollowingOnly); + if (ArrayUtils.isEmpty(activity.after_filtered_source_ids)) { + return ITEM_VIEW_TYPE_EMPTY; + } + return ITEM_VIEW_TYPE_TITLE_SUMMARY; } - return ITEM_VIEW_TYPE_TITLE_SUMMARY; } return ITEM_VIEW_TYPE_STUB; } @@ -283,6 +293,11 @@ public abstract class AbsActivitiesAdapter extends LoadMoreSupportAdapter< notifyDataSetChanged(); } + public void setMentionsOnly(boolean mentionsOnly) { + mMentionsOnly = mentionsOnly; + notifyDataSetChanged(); + } + @Override public final int getItemCount() { return getActivityCount() + (isLoadMoreIndicatorVisible() ? 1 : 0); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsActivitiesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsActivitiesFragment.java index 956da06d8..465162885 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsActivitiesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsActivitiesFragment.java @@ -30,7 +30,6 @@ 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.PopupMenu; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.OnScrollListener; import android.view.KeyEvent; @@ -117,7 +116,7 @@ public abstract class AbsActivitiesFragment extends AbsContentListRecycler } } }; - private PopupMenu mPopupMenu; + private final OnScrollListener mOnScrollListener = new OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { @@ -427,9 +426,6 @@ public abstract class AbsActivitiesFragment extends AbsContentListRecycler @Override public void onDestroyView() { - if (mPopupMenu != null) { - mPopupMenu.dismiss(); - } super.onDestroyView(); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsContentRecyclerViewFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsContentRecyclerViewFragment.java index c39c34d21..98f73becf 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsContentRecyclerViewFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsContentRecyclerViewFragment.java @@ -51,8 +51,9 @@ import org.mariotaku.twidere.view.themed.AccentSwipeRefreshLayout; /** * Created by mariotaku on 15/10/26. */ -public abstract class AbsContentRecyclerViewFragment extends BaseSupportFragment - implements SwipeRefreshLayout.OnRefreshListener, HeaderDrawerLayout.DrawerCallback, RefreshScrollTopInterface, IControlBarActivity.ControlBarOffsetListener, +public abstract class AbsContentRecyclerViewFragment + extends BaseSupportFragment implements SwipeRefreshLayout.OnRefreshListener, + HeaderDrawerLayout.DrawerCallback, RefreshScrollTopInterface, IControlBarActivity.ControlBarOffsetListener, ContentListScrollListener.ContentListSupport, IControlBarActivity.ControlBarShowHideHelper.ControlBarAnimationListener { private View mProgressContainer; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ActivitiesAboutMeFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ActivitiesAboutMeFragment.java index 29718d637..5c7cb970a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ActivitiesAboutMeFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ActivitiesAboutMeFragment.java @@ -25,8 +25,11 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import org.apache.commons.lang3.ArrayUtils; +import org.mariotaku.sqliteqb.library.Expression; import org.mariotaku.twidere.adapter.ParcelableActivitiesAdapter; import org.mariotaku.twidere.annotation.ReadPositionTag; +import org.mariotaku.twidere.api.twitter.model.Activity; import org.mariotaku.twidere.provider.TwidereDataStore.Activities; import edu.tsinghua.hotmobi.model.TimelineType; @@ -66,6 +69,21 @@ public class ActivitiesAboutMeFragment extends CursorActivitiesFragment { setRefreshing(mTwitterWrapper.isMentionsTimelineRefreshing()); } + @Override + @NonNull + protected Where processWhere(@NonNull Expression where, @NonNull String[] whereArgs) { + final Bundle arguments = getArguments(); + if (arguments != null) { + final Bundle extras = arguments.getBundle(EXTRA_EXTRAS); + if (extras != null && extras.getBoolean(EXTRA_MENTIONS_ONLY)) { + final Expression expression = Expression.and(where, Expression.inArgs(Activities.ACTION, 3)); + return new Where(expression, ArrayUtils.addAll(whereArgs, Activity.Action.MENTION, + Activity.Action.REPLY, Activity.Action.QUOTE)); + } + } + return super.processWhere(where, whereArgs); + } + @NonNull @Override protected ParcelableActivitiesAdapter onCreateAdapter(Context context, boolean compact) { @@ -75,6 +93,7 @@ public class ActivitiesAboutMeFragment extends CursorActivitiesFragment { final Bundle extras = arguments.getBundle(EXTRA_EXTRAS); if (extras != null) { adapter.setFollowingOnly(extras.getBoolean(EXTRA_MY_FOLLOWING_ONLY)); + adapter.setMentionsOnly(extras.getBoolean(EXTRA_MENTIONS_ONLY)); } } return adapter; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportFragment.java index a6814337b..0e6bc05f9 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportFragment.java @@ -46,6 +46,7 @@ import org.mariotaku.twidere.fragment.iface.IBaseFragment; import org.mariotaku.twidere.util.AsyncTaskManager; import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.DebugModeUtils; +import org.mariotaku.twidere.util.ErrorInfoStore; import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.MultiSelectManager; import org.mariotaku.twidere.util.NotificationManagerWrapper; @@ -80,6 +81,8 @@ public class BaseSupportFragment extends Fragment implements IBaseFragment, Cons protected NotificationManagerWrapper mNotificationManager; @Inject protected BidiFormatter mBidiFormatter; + @Inject + protected ErrorInfoStore mErrorInfoStore; public BaseSupportFragment() { diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorActivitiesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorActivitiesFragment.java index 0d6bd9b37..349277c90 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorActivitiesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorActivitiesFragment.java @@ -27,6 +27,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.app.FragmentActivity; import android.support.v4.content.Loader; @@ -34,6 +35,7 @@ import com.desmond.asyncmanager.AsyncManager; import com.desmond.asyncmanager.TaskRunnable; import com.squareup.otto.Subscribe; +import org.apache.commons.lang3.ArrayUtils; import org.mariotaku.library.objectcursor.ObjectCursor; import org.mariotaku.sqliteqb.library.Columns.Column; import org.mariotaku.sqliteqb.library.Expression; @@ -92,19 +94,21 @@ public abstract class CursorActivitiesFragment extends AbsActivitiesFragment> adapter = getAdapter(); adapter.setShowAccountsColor(accountIds.length > 1); final String[] projection = Activities.COLUMNS; - return new CursorActivitiesLoader(context, uri, projection, selection, null, sortOrder, - fromUser); + return new CursorActivitiesLoader(context, uri, projection, selection, expression.whereArgs, + sortOrder, fromUser); } @Override @@ -242,8 +246,9 @@ public abstract class CursorActivitiesFragment extends AbsActivitiesFragment { public CursorActivitiesLoader(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java index 196032749..3c04ccdad 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java @@ -57,6 +57,7 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Statuses; import org.mariotaku.twidere.util.AsyncTaskUtils; import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.DataStoreUtils; +import org.mariotaku.twidere.util.ErrorInfoStore; import org.mariotaku.twidere.util.KeyboardShortcutsHandler; import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback; import org.mariotaku.twidere.util.RecyclerViewNavigationHelper; @@ -150,17 +151,25 @@ public class DirectMessagesFragment extends AbsContentListRecyclerViewFragment loader, final Cursor cursor) { if (getActivity() == null) return; + final boolean isEmpty = cursor != null && cursor.getCount() == 0; mFirstVisibleItem = -1; final MessageEntriesAdapter adapter = getAdapter(); adapter.setCursor(cursor); adapter.setLoadMoreIndicatorVisible(false); - adapter.setLoadMoreSupported(cursor != null && cursor.getCount() > 0); + adapter.setLoadMoreSupported(!isEmpty); adapter.setLoadMoreSupported(hasMoreData(cursor)); final long[] accountIds = getAccountIds(); adapter.setShowAccountsColor(accountIds.length > 1); setRefreshEnabled(true); + if (accountIds.length > 0) { - showContent(); + final ErrorInfoStore.DisplayErrorInfo errorInfo = ErrorInfoStore.getErrorInfo(getContext(), + mErrorInfoStore.get(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountIds[0])); + if (isEmpty && errorInfo != null) { + showError(errorInfo.getIcon(), errorInfo.getMessage()); + } else { + showContent(); + } } else { showError(R.drawable.ic_info_accounts, getString(R.string.no_account_selected)); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/AccountPreferences.java b/twidere/src/main/java/org/mariotaku/twidere/model/AccountPreferences.java index 7222b2a4c..e36c0f927 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/AccountPreferences.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/AccountPreferences.java @@ -113,6 +113,10 @@ public class AccountPreferences implements Constants { return mPreferences.getBoolean(KEY_NOTIFICATION_FOLLOWING_ONLY, false); } + public boolean isNotificationMentionsOnly() { + return mPreferences.getBoolean(KEY_NOTIFICATION_FOLLOWING_ONLY, false); + } + public boolean isNotificationEnabled() { return mPreferences.getBoolean(KEY_NOTIFICATION, DEFAULT_NOTIFICATION); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableActivityUtils.java b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableActivityUtils.java index ff1b3e0ad..64e0539af 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableActivityUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableActivityUtils.java @@ -9,8 +9,16 @@ import org.mariotaku.twidere.model.ParcelableUser; * Created by mariotaku on 16/1/2. */ public class ParcelableActivityUtils { - public static void getAfterFilteredSourceIds(ParcelableActivity activity, long[] filteredUserIds, boolean followingOnly) { - if (activity.after_filtered_source_ids != null) return; + + /** + * @param activity Activity for processing + * @param filteredUserIds Those ids will be removed from source_ids. + * @param followingOnly Limit following users in sources + * @return true if source ids changed, false otherwise + */ + public static boolean initAfterFilteredSourceIds(ParcelableActivity activity, long[] filteredUserIds, + boolean followingOnly) { + if (activity.after_filtered_source_ids != null) return false; if (followingOnly || !ArrayUtils.isEmpty(filteredUserIds)) { ArrayLongList list = new ArrayLongList(); for (ParcelableUser user : activity.sources) { @@ -22,8 +30,10 @@ public class ParcelableActivityUtils { } } activity.after_filtered_source_ids = list.toArray(); + return true; } else { activity.after_filtered_source_ids = activity.source_ids; + return false; } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java b/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java index f74f738b1..29a97e689 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java +++ b/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java @@ -78,6 +78,7 @@ import org.mariotaku.twidere.activity.support.HomeActivity; import org.mariotaku.twidere.annotation.CustomTabType; import org.mariotaku.twidere.annotation.NotificationType; import org.mariotaku.twidere.annotation.ReadPositionTag; +import org.mariotaku.twidere.api.twitter.model.Activity; import org.mariotaku.twidere.app.TwidereApplication; import org.mariotaku.twidere.model.AccountPreferences; import org.mariotaku.twidere.model.ActivityTitleSummaryMessage; @@ -85,9 +86,10 @@ import org.mariotaku.twidere.model.DraftItem; import org.mariotaku.twidere.model.DraftItemCursorIndices; import org.mariotaku.twidere.model.ParcelableActivity; import org.mariotaku.twidere.model.ParcelableActivityCursorIndices; -import org.mariotaku.twidere.model.ParcelableStatus; +import org.mariotaku.twidere.model.ParcelableUser; import org.mariotaku.twidere.model.StringLongPair; import org.mariotaku.twidere.model.UnreadItem; +import org.mariotaku.twidere.model.util.ParcelableActivityUtils; import org.mariotaku.twidere.provider.TwidereDataStore.Accounts; import org.mariotaku.twidere.provider.TwidereDataStore.Activities; import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags; @@ -135,7 +137,6 @@ import java.io.IOException; import java.net.InetAddress; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -1348,18 +1349,28 @@ public final class TwidereDataProvider extends ContentProvider implements Consta int messageLines = 0; long timestamp = -1; - while (!c.isAfterLast()) { + c.moveToFirst(); + while (c.moveToNext()) { if (messageLines == 5) { style.addLine(resources.getString(R.string.and_N_more, count - c.getPosition())); break; } final ParcelableActivity activity = ci.newObject(c); + if (pref.isNotificationMentionsOnly() && ArrayUtils.contains(Activity.Action.MENTION_ACTIONS, + activity.action)) { + continue; + } + final long[] filteredUserIds = DataStoreUtils.getFilteredUserIds(context); if (timestamp == -1) { timestamp = activity.timestamp; } + ParcelableActivityUtils.initAfterFilteredSourceIds(activity, filteredUserIds, + pref.isNotificationFollowingOnly()); + final ParcelableUser[] sources = ParcelableActivityUtils.getAfterFilteredSources(activity); + if (ArrayUtils.isEmpty(sources)) continue; final ActivityTitleSummaryMessage message = ActivityTitleSummaryMessage.get(context, - mUserColorNameManager, activity, activity.sources, 0, false, - mUseStarForLikes, mNameFirst); + mUserColorNameManager, activity, sources, + 0, false, mUseStarForLikes, mNameFirst); if (message != null) { final CharSequence summary = message.getSummary(); if (TextUtils.isEmpty(summary)) { @@ -1370,7 +1381,6 @@ public final class TwidereDataProvider extends ContentProvider implements Consta } messageLines++; } - c.moveToNext(); } builder.setContentIntent(getContentIntent(context, CustomTabType.NOTIFICATIONS_TIMELINE, NotificationType.INTERACTIONS, accountId)); diff --git a/twidere/src/main/java/org/mariotaku/twidere/receiver/ConnectivityStateReceiver.java b/twidere/src/main/java/org/mariotaku/twidere/receiver/ConnectivityStateReceiver.java index 9c7a7b005..8d17857cc 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/receiver/ConnectivityStateReceiver.java +++ b/twidere/src/main/java/org/mariotaku/twidere/receiver/ConnectivityStateReceiver.java @@ -25,12 +25,12 @@ import android.content.Intent; import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.os.AsyncTask; +import android.support.v4.net.ConnectivityManagerCompat; import android.util.Log; import org.mariotaku.twidere.BuildConfig; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.app.TwidereApplication; -import org.mariotaku.twidere.util.ConnectivityUtils; import org.mariotaku.twidere.util.Utils; import edu.tsinghua.hotmobi.HotMobiLogger; @@ -60,14 +60,16 @@ public class ConnectivityStateReceiver extends BroadcastReceiver implements Cons HotMobiLogger.getInstance(context).log(event); // END HotMobi } - final int networkType = ConnectivityUtils.getActiveNetworkType(context.getApplicationContext()); - final boolean isWifi = networkType == ConnectivityManager.TYPE_WIFI; - final boolean isCharging = Utils.isCharging(context.getApplicationContext()); - if (isWifi && isCharging) { + + final Context appContext = context.getApplicationContext(); + final ConnectivityManager cm = (ConnectivityManager) appContext.getSystemService(Context.CONNECTIVITY_SERVICE); + final boolean isNetworkMetered = ConnectivityManagerCompat.isActiveNetworkMetered(cm); + final boolean isCharging = Utils.isCharging(appContext); + if (!isNetworkMetered && isCharging) { final long currentTime = System.currentTimeMillis(); - final long lastSuccessfulTime = HotMobiLogger.getLastUploadTime(context); + final long lastSuccessfulTime = HotMobiLogger.getLastUploadTime(appContext); if ((currentTime - lastSuccessfulTime) > HotMobiLogger.UPLOAD_INTERVAL_MILLIS) { - AsyncTask.execute(new UploadLogsTask(context.getApplicationContext())); + AsyncTask.execute(new UploadLogsTask(appContext)); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java b/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java index 1d1cdf229..66b033e54 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java +++ b/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java @@ -54,6 +54,7 @@ import org.mariotaku.twidere.activity.MainHondaJOJOActivity; import org.mariotaku.twidere.api.twitter.Twitter; import org.mariotaku.twidere.api.twitter.TwitterException; import org.mariotaku.twidere.api.twitter.TwitterUpload; +import org.mariotaku.twidere.api.twitter.model.ErrorInfo; import org.mariotaku.twidere.api.twitter.model.MediaUploadResponse; import org.mariotaku.twidere.api.twitter.model.Status; import org.mariotaku.twidere.api.twitter.model.StatusUpdate; @@ -78,10 +79,8 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Drafts; import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.BitmapUtils; import org.mariotaku.twidere.util.ContentValuesCreator; -import org.mariotaku.twidere.util.DebugModeUtils; import org.mariotaku.twidere.util.MediaUploaderInterface; import org.mariotaku.twidere.util.NotificationManagerWrapper; -import org.mariotaku.twidere.util.StatusCodeMessageUtils; import org.mariotaku.twidere.util.StatusShortenerInterface; import org.mariotaku.twidere.util.TwidereListUtils; import org.mariotaku.twidere.util.TwidereValidator; @@ -367,7 +366,7 @@ public class BackgroundOperationService extends IntentService implements Constan // If the status is a duplicate, there's no need to save it to // drafts. if (exception instanceof TwitterException - && ((TwitterException) exception).getErrorCode() == StatusCodeMessageUtils.STATUS_IS_DUPLICATE) { + && ((TwitterException) exception).getErrorCode() == ErrorInfo.STATUS_IS_DUPLICATE) { showErrorMessage(getString(R.string.status_is_duplicate), false); } else { final ContentValues accountIdsValues = new ContentValues(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java index e04ce94cf..3ff6800ed 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java @@ -47,6 +47,7 @@ import org.mariotaku.twidere.api.twitter.http.HttpResponseCode; import org.mariotaku.twidere.api.twitter.model.Activity; import org.mariotaku.twidere.api.twitter.model.CursorTimestampResponse; import org.mariotaku.twidere.api.twitter.model.DirectMessage; +import org.mariotaku.twidere.api.twitter.model.ErrorInfo; import org.mariotaku.twidere.api.twitter.model.FriendshipUpdate; import org.mariotaku.twidere.api.twitter.model.Paging; import org.mariotaku.twidere.api.twitter.model.Relationship; @@ -114,6 +115,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { private final Bus mBus; private final UserColorNameManager mUserColorNameManager; private final ReadStateManager mReadStateManager; + private final ErrorInfoStore mErrorInfoStore; private int mGetReceivedDirectMessagesTaskId, mGetSentDirectMessagesTaskId; private int mGetLocalTrendsTaskId; @@ -127,7 +129,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { public AsyncTwitterWrapper(Context context, UserColorNameManager userColorNameManager, ReadStateManager readStateManager, Bus bus, - SharedPreferencesWrapper preferences, AsyncTaskManager asyncTaskManager) { + SharedPreferencesWrapper preferences, AsyncTaskManager asyncTaskManager, ErrorInfoStore errorInfoStore) { mContext = context; mResolver = context.getContentResolver(); mUserColorNameManager = userColorNameManager; @@ -135,6 +137,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { mBus = bus; mPreferences = preferences; mAsyncTaskManager = asyncTaskManager; + mErrorInfoStore = errorInfoStore; } public int acceptFriendshipAsync(final long accountId, final long userId) { @@ -1465,7 +1468,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { private boolean isMessageNotFound(final Exception e) { if (!(e instanceof TwitterException)) return false; final TwitterException te = (TwitterException) e; - return te.getErrorCode() == StatusCodeMessageUtils.PAGE_NOT_FOUND + return te.getErrorCode() == ErrorInfo.PAGE_NOT_FOUND || te.getStatusCode() == HttpResponseCode.NOT_FOUND; } @@ -1523,7 +1526,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { private boolean isMessageNotFound(final Exception e) { if (!(e instanceof TwitterException)) return false; final TwitterException te = (TwitterException) e; - return te.getErrorCode() == StatusCodeMessageUtils.PAGE_NOT_FOUND + return te.getErrorCode() == ErrorInfo.PAGE_NOT_FOUND || te.getStatusCode() == HttpResponseCode.NOT_FOUND; } @@ -1948,13 +1951,13 @@ public class AsyncTwitterWrapper extends TwitterWrapper { if (account_ids == null) return result; int idx = 0; - final int load_item_limit = mPreferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT); + final int loadItemLimit = mPreferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT); for (final long accountId : account_ids) { final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, accountId, true); if (twitter == null) continue; try { final Paging paging = new Paging(); - paging.setCount(load_item_limit); + paging.setCount(loadItemLimit); long max_id = -1, since_id = -1; if (isMaxIdsValid() && max_ids[idx] > 0) { max_id = max_ids[idx]; @@ -1970,7 +1973,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper { result.add(new MessageListResponse(accountId, max_id, since_id, messages, truncated)); storeMessages(accountId, messages, isOutgoing(), true); + mErrorInfoStore.remove(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountId); } catch (final TwitterException e) { + if (e.getErrorCode() == 93) { + mErrorInfoStore.put(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountId, + ErrorInfoStore.CODE_NO_DM_PERMISSION); + } if (BuildConfig.DEBUG) { Log.w(LOGTAG, e); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ConnectivityUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/ConnectivityUtils.java deleted file mode 100644 index 89667414c..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/util/ConnectivityUtils.java +++ /dev/null @@ -1,44 +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.util; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; - -/** - * Created by mariotaku on 15/12/15. - */ -public class ConnectivityUtils { - public static boolean isOnWifi(final Context context) { - if (context == null) return false; - final ConnectivityManager conn = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - final NetworkInfo networkInfo = conn.getActiveNetworkInfo(); - return networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI - && networkInfo.isConnected(); - } - - public static int getActiveNetworkType(final Context context) { - if (context == null) return -1; - final ConnectivityManager conn = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - final NetworkInfo networkInfo = conn.getActiveNetworkInfo(); - return networkInfo != null && networkInfo.isConnected() ? networkInfo.getType() : -1; - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/CustomTabUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/CustomTabUtils.java index ae9eb60ce..e2bb49067 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/CustomTabUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/CustomTabUtils.java @@ -75,7 +75,8 @@ public class CustomTabUtils implements Constants { CUSTOM_TABS_CONFIGURATION_MAP.put(CustomTabType.NOTIFICATIONS_TIMELINE, new CustomTabConfiguration( ActivitiesAboutMeFragment.class, R.string.notifications, R.drawable.ic_action_notification, CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 1, false, - ExtraConfiguration.newBoolean(EXTRA_MY_FOLLOWING_ONLY, R.string.following_only, false))); + ExtraConfiguration.newBoolean(EXTRA_MY_FOLLOWING_ONLY, R.string.following_only, false), + ExtraConfiguration.newBoolean(EXTRA_MENTIONS_ONLY, R.string.mentions_only, false))); CUSTOM_TABS_CONFIGURATION_MAP.put(CustomTabType.DIRECT_MESSAGES, new CustomTabConfiguration( DirectMessagesFragment.class, R.string.direct_messages, R.drawable.ic_action_message, diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/DataStoreUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/DataStoreUtils.java index e1522f90e..ca533e39e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/DataStoreUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/DataStoreUtils.java @@ -601,8 +601,9 @@ public class DataStoreUtils implements Constants { return queryCount(context, uri, selection.getSQL(), null); } - public static int getActivitiesCount(final Context context, final Uri uri, final long sinceTimestamp, - final long... accountIds) { + public static int getActivitiesCount(final Context context, final Uri uri, + final Expression extraWhere, final String[] extraWhereArgs, + final long sinceTimestamp, final long... accountIds) { if (context == null) return 0; final RawItemArray idsIn; if (accountIds == null || accountIds.length == 0 || (accountIds.length == 1 && accountIds[0] < 0)) { @@ -610,12 +611,18 @@ public class DataStoreUtils implements Constants { } else { idsIn = new RawItemArray(accountIds); } - final Expression selection = Expression.and( - Expression.in(new Columns.Column(Activities.ACCOUNT_ID), idsIn), - Expression.greaterThan(Activities.TIMESTAMP, sinceTimestamp), - buildActivityFilterWhereClause(getTableNameByUri(uri), null) - ); - return queryCount(context, uri, selection.getSQL(), null); + Expression[] expressions; + if (extraWhere != null) { + expressions = new Expression[4]; + expressions[3] = extraWhere; + } else { + expressions = new Expression[3]; + } + expressions[0] = Expression.in(new Columns.Column(Activities.ACCOUNT_ID), idsIn); + expressions[1] = Expression.greaterThan(Activities.TIMESTAMP, sinceTimestamp); + expressions[2] = buildActivityFilterWhereClause(getTableNameByUri(uri), null); + final Expression selection = Expression.and(expressions); + return queryCount(context, uri, selection.getSQL(), extraWhereArgs); } public static int getTableId(final Uri uri) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ErrorInfoStore.java b/twidere/src/main/java/org/mariotaku/twidere/util/ErrorInfoStore.java new file mode 100644 index 000000000..707e3bb02 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/util/ErrorInfoStore.java @@ -0,0 +1,85 @@ +package org.mariotaku.twidere.util; + +import android.app.Application; +import android.content.Context; +import android.content.SharedPreferences; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import org.mariotaku.twidere.R; + + +/** + * Created by mariotaku on 16/1/31. + */ +public class ErrorInfoStore { + + public static final String KEY_DIRECT_MESSAGES = "direct_messages"; + + public static final int CODE_NO_DM_PERMISSION = 1; + + private final SharedPreferences mPreferences; + + public ErrorInfoStore(Application application) { + mPreferences = application.getSharedPreferences("error_info", Context.MODE_PRIVATE); + } + + public int get(String key) { + return mPreferences.getInt(key, 0); + } + + public int get(String key, long extraId) { + return get(key + "_" + extraId); + } + + public void put(String key, int code) { + mPreferences.edit().putInt(key, code).apply(); + } + + public void put(String key, long extraId, int code) { + put(key + "_" + extraId, code); + } + + @Nullable + public static DisplayErrorInfo getErrorInfo(@NonNull Context context, int code) { + switch (code) { + case CODE_NO_DM_PERMISSION: { + return new DisplayErrorInfo(code, R.drawable.ic_info_error_generic, + context.getString(R.string.error_no_dm_permission)); + } + } + return null; + } + + public void remove(String key, long extraId) { + remove(key + "_" + extraId); + } + + public void remove(String key) { + mPreferences.edit().remove(key).apply(); + } + + public static class DisplayErrorInfo { + int code; + int icon; + String message; + + public DisplayErrorInfo(int code, int icon, String message) { + this.code = code; + this.icon = icon; + this.message = message; + } + + public int getCode() { + return code; + } + + public int getIcon() { + return icon; + } + + public String getMessage() { + return message; + } + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ImagePreloader.java b/twidere/src/main/java/org/mariotaku/twidere/util/ImagePreloader.java index 5b23a504e..ce0bb128e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/ImagePreloader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/ImagePreloader.java @@ -21,6 +21,8 @@ package org.mariotaku.twidere.util; import android.content.Context; import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.support.v4.net.ConnectivityManagerCompat; import android.text.TextUtils; import com.nostra13.universalimageloader.cache.disc.DiskCache; @@ -30,8 +32,6 @@ import org.mariotaku.twidere.Constants; import java.io.File; -import static org.mariotaku.twidere.util.ConnectivityUtils.isOnWifi; - /** * @author mariotaku */ @@ -43,9 +43,11 @@ public class ImagePreloader implements Constants { private final SharedPreferences mPreferences; private final DiskCache mDiskCache; private final ImageLoader mImageLoader; + private final ConnectivityManager mConnectivityManager; public ImagePreloader(final Context context, final ImageLoader loader) { mContext = context; + mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); mPreferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); mImageLoader = loader; mDiskCache = loader.getDiskCache(); @@ -64,7 +66,8 @@ public class ImagePreloader implements Constants { public void preloadImage(final String url) { if (TextUtils.isEmpty(url)) return; - if (!isOnWifi(mContext) && mPreferences.getBoolean(KEY_PRELOAD_WIFI_ONLY, true)) return; + if (ConnectivityManagerCompat.isActiveNetworkMetered(mConnectivityManager) + && mPreferences.getBoolean(KEY_PRELOAD_WIFI_ONLY, true)) return; mImageLoader.loadImage(url, null); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/StatusCodeMessageUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/StatusCodeMessageUtils.java index 3be4f1a17..561010f12 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/StatusCodeMessageUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/StatusCodeMessageUtils.java @@ -23,22 +23,18 @@ import android.content.Context; import android.util.SparseIntArray; import org.mariotaku.twidere.R; +import org.mariotaku.twidere.api.twitter.model.ErrorInfo; public class StatusCodeMessageUtils { - public static final int PAGE_NOT_FOUND = 34; - public static final int RATE_LIMIT_EXCEEDED = 88; - public static final int NOT_AUTHORIZED = 179; - public static final int STATUS_IS_DUPLICATE = 187; - private static final SparseIntArray TWITTER_ERROR_CODE_MESSAGES = new SparseIntArray(); private static final SparseIntArray HTTP_STATUS_CODE_MESSAGES = new SparseIntArray(); static { TWITTER_ERROR_CODE_MESSAGES.put(32, R.string.error_twitter_32); - TWITTER_ERROR_CODE_MESSAGES.put(PAGE_NOT_FOUND, R.string.error_twitter_34); - TWITTER_ERROR_CODE_MESSAGES.put(RATE_LIMIT_EXCEEDED, R.string.error_twitter_88); + TWITTER_ERROR_CODE_MESSAGES.put(ErrorInfo.PAGE_NOT_FOUND, R.string.error_twitter_34); + TWITTER_ERROR_CODE_MESSAGES.put(ErrorInfo.RATE_LIMIT_EXCEEDED, R.string.error_twitter_88); TWITTER_ERROR_CODE_MESSAGES.put(89, R.string.error_twitter_89); TWITTER_ERROR_CODE_MESSAGES.put(64, R.string.error_twitter_64); TWITTER_ERROR_CODE_MESSAGES.put(130, R.string.error_twitter_130); @@ -49,8 +45,8 @@ public class StatusCodeMessageUtils { TWITTER_ERROR_CODE_MESSAGES.put(161, R.string.error_twitter_161); TWITTER_ERROR_CODE_MESSAGES.put(162, R.string.error_twitter_162); TWITTER_ERROR_CODE_MESSAGES.put(172, R.string.error_twitter_172); - TWITTER_ERROR_CODE_MESSAGES.put(NOT_AUTHORIZED, R.string.error_twitter_179); - TWITTER_ERROR_CODE_MESSAGES.put(STATUS_IS_DUPLICATE, R.string.error_twitter_187); + TWITTER_ERROR_CODE_MESSAGES.put(ErrorInfo.NOT_AUTHORIZED, R.string.error_twitter_179); + TWITTER_ERROR_CODE_MESSAGES.put(ErrorInfo.STATUS_IS_DUPLICATE, R.string.error_twitter_187); TWITTER_ERROR_CODE_MESSAGES.put(193, R.string.error_twitter_193); TWITTER_ERROR_CODE_MESSAGES.put(215, R.string.error_twitter_215); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/dagger/ApplicationModule.java b/twidere/src/main/java/org/mariotaku/twidere/util/dagger/ApplicationModule.java index 62680ab39..9872eba86 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/dagger/ApplicationModule.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/dagger/ApplicationModule.java @@ -44,6 +44,7 @@ import org.mariotaku.twidere.constant.SharedPreferenceConstants; import org.mariotaku.twidere.util.ActivityTracker; import org.mariotaku.twidere.util.AsyncTaskManager; import org.mariotaku.twidere.util.AsyncTwitterWrapper; +import org.mariotaku.twidere.util.ErrorInfoStore; import org.mariotaku.twidere.util.ExternalThemeManager; import org.mariotaku.twidere.util.HttpClientFactory; import org.mariotaku.twidere.util.KeyboardShortcutsHandler; @@ -174,9 +175,9 @@ public class ApplicationModule implements Constants { public AsyncTwitterWrapper asyncTwitterWrapper(UserColorNameManager userColorNameManager, ReadStateManager readStateManager, Bus bus, SharedPreferencesWrapper preferences, - AsyncTaskManager asyncTaskManager) { + AsyncTaskManager asyncTaskManager, ErrorInfoStore errorInfoStore) { return new AsyncTwitterWrapper(application, userColorNameManager, readStateManager, bus, - preferences, asyncTaskManager); + preferences, asyncTaskManager, errorInfoStore); } @Provides @@ -215,6 +216,12 @@ public class ApplicationModule implements Constants { return new TwidereMediaDownloader(application, preferences, client); } + @Provides + @Singleton + public ErrorInfoStore errorInfoStore() { + return new ErrorInfoStore(application); + } + @Provides public BidiFormatter provideBidiFormatter() { return BidiFormatter.getInstance(); diff --git a/twidere/src/main/res/drawable-hdpi/ic_action_notification.png b/twidere/src/main/res/drawable-hdpi/ic_action_notification.png deleted file mode 100644 index df38f1eb0..000000000 Binary files a/twidere/src/main/res/drawable-hdpi/ic_action_notification.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_action_notification.png b/twidere/src/main/res/drawable-mdpi/ic_action_notification.png deleted file mode 100644 index 62173a1b8..000000000 Binary files a/twidere/src/main/res/drawable-mdpi/ic_action_notification.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_action_notification.png b/twidere/src/main/res/drawable-xhdpi/ic_action_notification.png deleted file mode 100644 index a534699b3..000000000 Binary files a/twidere/src/main/res/drawable-xhdpi/ic_action_notification.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_action_notification.png b/twidere/src/main/res/drawable-xxhdpi/ic_action_notification.png deleted file mode 100644 index 4a3ca869e..000000000 Binary files a/twidere/src/main/res/drawable-xxhdpi/ic_action_notification.png and /dev/null differ diff --git a/twidere/src/main/res/layout/layout_content_fragment_common.xml b/twidere/src/main/res/layout/layout_content_fragment_common.xml index 6afd0afc0..4424bbde5 100644 --- a/twidere/src/main/res/layout/layout_content_fragment_common.xml +++ b/twidere/src/main/res/layout/layout_content_fragment_common.xml @@ -44,7 +44,6 @@ android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" - android:padding="@dimen/element_spacing_large" android:visibility="gone"> diff --git a/twidere/src/main/res/values/strings.xml b/twidere/src/main/res/values/strings.xml index 93528faba..5408ea186 100644 --- a/twidere/src/main/res/values/strings.xml +++ b/twidere/src/main/res/values/strings.xml @@ -839,4 +839,6 @@ Poll %1$s ยท %2$s %1$s: %2$s + Mentions only + No direct message permission, check your Twitter application permission setting. \ No newline at end of file diff --git a/twidere/src/main/svg/drawable/ic_action_notification-mdpi.svg b/twidere/src/main/svg/drawable/ic_action_notification-mdpi.svg new file mode 100644 index 000000000..ed6f24f87 --- /dev/null +++ b/twidere/src/main/svg/drawable/ic_action_notification-mdpi.svg @@ -0,0 +1,15 @@ + + + + ic_action_notification-mdpi + Created with Sketch. + + + + + + + + + + \ No newline at end of file