improved error display

This commit is contained in:
Mariotaku Lee 2016-12-24 13:48:01 +08:00
parent b50904c7ec
commit 0de5011e80
10 changed files with 99 additions and 16 deletions

View File

@ -3,6 +3,7 @@ package org.mariotaku.twidere.util;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -107,10 +108,11 @@ public class ErrorInfoStore {
public static class DisplayErrorInfo {
int code;
@DrawableRes
int icon;
String message;
public DisplayErrorInfo(int code, int icon, String message) {
public DisplayErrorInfo(int code, @DrawableRes int icon, String message) {
this.code = code;
this.icon = icon;
this.message = message;
@ -120,6 +122,7 @@ public class ErrorInfoStore {
return code;
}
@DrawableRes
public int getIcon() {
return icon;
}

View File

@ -20,17 +20,22 @@
package org.mariotaku.twidere.util;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.SparseIntArray;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.model.ErrorInfo;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.ErrorInfoStore.DisplayErrorInfo;
public class StatusCodeMessageUtils {
private static final SparseIntArray TWITTER_ERROR_CODE_MESSAGES = new SparseIntArray();
private static final SparseIntArray TWITTER_ERROR_CODE_ICONS = new SparseIntArray();
private static final SparseIntArray HTTP_STATUS_CODE_MESSAGES = new SparseIntArray();
private static final SparseIntArray HTTP_STATUS_CODE_ICONS = new SparseIntArray();
static {
TWITTER_ERROR_CODE_MESSAGES.put(32, R.string.error_twitter_32);
@ -53,6 +58,8 @@ public class StatusCodeMessageUtils {
TWITTER_ERROR_CODE_MESSAGES.put(215, R.string.error_twitter_215);
TWITTER_ERROR_CODE_MESSAGES.put(326, R.string.error_twitter_326);
TWITTER_ERROR_CODE_ICONS.put(136, R.drawable.ic_info_error_blocked);
HTTP_STATUS_CODE_MESSAGES.put(407, R.string.error_http_407);
}
@ -63,18 +70,34 @@ public class StatusCodeMessageUtils {
return HTTP_STATUS_CODE_MESSAGES.get(code, -1) != -1;
}
public static boolean containsTwitterError(final int code) {
static boolean containsTwitterError(final int code) {
return TWITTER_ERROR_CODE_MESSAGES.get(code, -1) != -1;
}
@Nullable
public static String getHttpStatusMessage(final Context context, final int code) {
static String getHttpStatusMessage(final Context context, final int code) {
if (context == null) return null;
final int res_id = HTTP_STATUS_CODE_MESSAGES.get(code, -1);
if (res_id > 0) return context.getString(res_id);
return null;
}
@Nullable
private static DisplayErrorInfo getHttpStatusInfo(final Context context, final int code) {
final int messageId = HTTP_STATUS_CODE_MESSAGES.get(code, 0);
if (messageId == 0) return null;
final int icon = HTTP_STATUS_CODE_ICONS.get(code, R.drawable.ic_info_error_generic);
return new DisplayErrorInfo(code, icon, context.getString(messageId));
}
@Nullable
private static DisplayErrorInfo getTwitterErrorInfo(final Context context, final int code) {
final int messageId = TWITTER_ERROR_CODE_MESSAGES.get(code, 0);
if (messageId == 0) return null;
final int icon = TWITTER_ERROR_CODE_ICONS.get(code, R.drawable.ic_info_error_generic);
return new DisplayErrorInfo(code, icon, context.getString(messageId));
}
@Nullable
public static String getMessage(final Context context, final int statusCode, final int errorCode) {
if (containsHttpStatus(statusCode)) return getHttpStatusMessage(context, statusCode);
@ -83,10 +106,38 @@ public class StatusCodeMessageUtils {
}
@Nullable
public static String getTwitterErrorMessage(final Context context, final int code) {
static String getTwitterErrorMessage(final Context context, final int code) {
if (context == null) return null;
final int resId = TWITTER_ERROR_CODE_MESSAGES.get(code, -1);
if (resId > 0) return context.getString(resId);
return null;
}
private static DisplayErrorInfo getErrorInfo(final Context context, final int statusCode, final int errorCode) {
if (containsHttpStatus(statusCode)) return getHttpStatusInfo(context, statusCode);
if (containsTwitterError(errorCode)) return getTwitterErrorInfo(context, errorCode);
return null;
}
@NonNull
public static DisplayErrorInfo getMicroBlogErrorInfo(final Context context, final MicroBlogException te) {
final DisplayErrorInfo errorInfo = getErrorInfo(context, te.getStatusCode(), te.getErrorCode());
if (errorInfo != null) return errorInfo;
return new DisplayErrorInfo(0, R.drawable.ic_info_error_generic, te.getMessage());
}
@Nullable
public static String getMicroBlogErrorMessage(final Context context, final MicroBlogException te) {
final DisplayErrorInfo errorInfo = getErrorInfo(context, te.getStatusCode(), te.getErrorCode());
if (errorInfo != null) return errorInfo.getMessage();
return te.getMessage();
}
public static DisplayErrorInfo getErrorInfo(@NonNull final Context context, @NonNull final Throwable t) {
if (t instanceof MicroBlogException)
return getMicroBlogErrorInfo(context, (MicroBlogException) t);
return new DisplayErrorInfo(0, R.drawable.ic_info_error_generic, t.getMessage());
}
}

View File

@ -124,6 +124,7 @@ import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.ConversationEntries;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.util.ErrorInfoStore.DisplayErrorInfo;
import org.mariotaku.twidere.util.TwidereLinkify.HighlightStyle;
import org.mariotaku.twidere.view.CardMediaContainer.PreviewStyle;
import org.mariotaku.twidere.view.ShapedImageView;
@ -609,7 +610,7 @@ public final class Utils implements Constants {
return context.getString(R.string.error_unknown_error);
}
if (t instanceof MicroBlogException)
return getTwitterErrorMessage(context, (MicroBlogException) t);
return StatusCodeMessageUtils.getMicroBlogErrorMessage(context, (MicroBlogException) t);
return t.getMessage();
}

View File

@ -22,7 +22,10 @@ package org.mariotaku.twidere.fragment
import android.accounts.AccountManager
import android.app.Activity
import android.app.Dialog
import android.content.*
import android.content.ContentValues
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Color
import android.graphics.Rect
import android.nfc.NdefMessage
@ -36,7 +39,6 @@ import android.support.v4.app.LoaderManager.LoaderCallbacks
import android.support.v4.app.hasRunningLoadersSafe
import android.support.v4.content.AsyncTaskLoader
import android.support.v4.content.ContextCompat
import android.support.v4.content.IntentCompat
import android.support.v4.content.Loader
import android.support.v4.view.MenuItemCompat
import android.support.v4.view.ViewCompat
@ -442,7 +444,9 @@ class StatusFragment : BaseSupportFragment(), LoaderCallbacks<SingleResponse<Par
} else {
adapter.loadMoreSupportedPosition = ILoadMoreSupportAdapter.NONE
setState(STATE_ERROR)
errorText.text = Utils.getErrorMessage(context, data.exception)
val errorInfo = StatusCodeMessageUtils.getErrorInfo(context, data.exception!!)
errorText.text = errorInfo.message
errorIcon.setImageResource(errorInfo.icon)
}
activity.supportInvalidateOptionsMenu()
}
@ -892,9 +896,9 @@ class StatusFragment : BaseSupportFragment(), LoaderCallbacks<SingleResponse<Par
val timeString = Utils.formatToLongTimeString(context, timestamp)
if (!TextUtils.isEmpty(timeString) && !TextUtils.isEmpty(status.source)) {
itemView.timeSource.text = HtmlSpanBuilder.fromHtml(context.getString(R.string.time_source, timeString, status.source))
itemView.timeSource.text = HtmlSpanBuilder.fromHtml(context.getString(R.string.status_format_time_source, timeString, status.source))
} else if (TextUtils.isEmpty(timeString) && !TextUtils.isEmpty(status.source)) {
itemView.timeSource.text = HtmlSpanBuilder.fromHtml(context.getString(R.string.source, status.source))
itemView.timeSource.text = HtmlSpanBuilder.fromHtml(status.source)
} else if (!TextUtils.isEmpty(timeString) && TextUtils.isEmpty(status.source)) {
itemView.timeSource.text = timeString
}

View File

@ -283,7 +283,6 @@ class UserFragment : BaseSupportFragment(), OnClickListener, OnLinkClickListener
relationship = userRelationship
}
activity.invalidateOptionsMenu()
followContainer.follow.isEnabled = userRelationship.blocking || !userRelationship.blocked_by
if (userRelationship.blocked_by) {
pagesErrorContainer.visibility = View.GONE
pagesErrorText.text = null
@ -300,6 +299,8 @@ class UserFragment : BaseSupportFragment(), OnClickListener, OnLinkClickListener
}
if (userRelationship.blocking) {
followContainer.follow.setText(R.string.unblock)
} else if (userRelationship.blocked_by) {
followContainer.follow.setText(R.string.action_block)
} else if (userRelationship.following) {
followContainer.follow.setText(R.string.unfollow)
} else if (user.is_follow_request_sent) {
@ -1122,6 +1123,8 @@ class UserFragment : BaseSupportFragment(), OnClickListener, OnLinkClickListener
if (userRelationship == null) return
if (userRelationship.blocking) {
twitter.destroyBlockAsync(user.account_key, user.key)
} else if (userRelationship.blocked_by) {
CreateUserBlockDialogFragment.show(childFragmentManager, user)
} else if (userRelationship.following) {
DestroyFriendshipDialogFragment.show(fragmentManager, user)
} else {

View File

@ -59,7 +59,7 @@ class ParcelableStatusLoader(
override fun loadInBackground(): SingleResponse<ParcelableStatus> {
if (accountKey == null || statusId == null) {
return SingleResponse(exception = IllegalArgumentException())
return SingleResponse(IllegalArgumentException())
}
val details = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true)
if (!omitIntentExtra && extras != null) {
@ -70,7 +70,7 @@ class ParcelableStatusLoader(
return response
}
}
if (details == null) return SingleResponse(exception = MicroBlogException("No account"))
if (details == null) return SingleResponse(MicroBlogException("No account"))
try {
val status = findStatus(context, accountKey, statusId)
ParcelableStatusUtils.updateExtraInformation(status, details, userColorNameManager)
@ -85,7 +85,7 @@ class ParcelableStatusLoader(
statusId, null)
DataStoreUtils.deleteActivityStatus(cr, accountKey, statusId, null)
}
return SingleResponse(exception = e)
return SingleResponse(e)
}
}

View File

@ -27,6 +27,10 @@ data class SingleResponse<Data>(
override val extras: Bundle = Bundle()
) : Response<Data> {
constructor(data: Data) : this(data, null)
constructor(exception: Exception) : this(null, exception)
override fun hasData(): Boolean {
return data != null
}

View File

@ -60,11 +60,11 @@
<item
android:id="@id/block"
android:icon="@drawable/ic_action_block"
android:title="@string/block"/>
android:title="@string/action_block"/>
<item
android:id="@id/report_spam"
android:icon="@drawable/ic_action_warning"
android:title="@string/report_for_spam"/>
android:title="@string/action_report_spam"/>
<item
android:id="@+id/muted_users"
android:icon="@drawable/ic_action_visibility_off"

View File

@ -144,6 +144,7 @@
<string name="block">Block</string>
<string name="unblock">Unblock</string>
<string name="report_for_spam">Report spam</string>
<string name="action_report_spam">Report spam</string>
<string name="twitter_mute_user">Mute user</string>
<string name="twitter_muted_users">Muted users</string>
<string name="message_user_muted">Added this user to filter list. You will not see tweets from this user in your home timeline/mentions list.</string>
@ -823,4 +824,7 @@
<string name="error_info_oauth_timestamp_error">Please check your system date &amp; time settings.</string>
<string name="fab_visible">Floating Action Button</string>
<string name="fab_visible_summary">Show the Floating Action Button</string>
<string name="action_block">Block</string>
<string name="status_format_time_source"><xliff:g example="0:00, Jan 1 2017" id="time">%1$s</xliff:g> · <xliff:g example="Twidere for Android" id="source">%2$s</xliff:g></string>
<string name="status_format_source"><xliff:g example="Twidere for Android" id="source">%s</xliff:g></string>
</resources>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
<title>ic_info_error_blocked-mdpi</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Error-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="ic_info_error_blocked-mdpi">
<polygon id="Shape" points="0 0 64 0 64 64 0 64"></polygon>
<path d="M32,5.33333333 C17.28,5.33333333 5.33333333,17.28 5.33333333,32 C5.33333333,46.72 17.28,58.6666667 32,58.6666667 C46.72,58.6666667 58.6666667,46.72 58.6666667,32 C58.6666667,17.28 46.72,5.33333333 32,5.33333333 Z M10.6666667,32 C10.6666667,20.2133333 20.2133333,10.6666667 32,10.6666667 C36.9333333,10.6666667 41.4666667,12.3466667 45.0666667,15.1733333 L15.1733333,45.0666667 C12.3466667,41.4666667 10.6666667,36.9333333 10.6666667,32 L10.6666667,32 Z M32,53.3333333 C27.0666667,53.3333333 22.5333333,51.6533333 18.9333333,48.8266667 L48.8266667,18.9333333 C51.6533333,22.5333333 53.3333333,27.0666667 53.3333333,32 C53.3333333,43.7866667 43.7866667,53.3333333 32,53.3333333 L32,53.3333333 Z" id="Shape" fill="#FFFFFF"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB