fixed media size limit

improved error message
This commit is contained in:
Mariotaku Lee 2017-04-12 21:40:29 +08:00
parent d45a5722b6
commit ec231d15b6
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
6 changed files with 58 additions and 41 deletions

View File

@ -24,13 +24,13 @@ package org.mariotaku.microblog.library;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import org.mariotaku.restfu.http.HttpRequest;
import org.mariotaku.restfu.http.HttpResponse;
import org.mariotaku.microblog.library.twitter.http.HttpResponseCode;
import org.mariotaku.microblog.library.twitter.model.ErrorInfo;
import org.mariotaku.microblog.library.twitter.model.RateLimitStatus;
import org.mariotaku.microblog.library.twitter.model.TwitterResponse;
import org.mariotaku.microblog.library.twitter.util.InternalParseUtil;
import org.mariotaku.restfu.http.HttpRequest;
import org.mariotaku.restfu.http.HttpResponse;
import java.io.IOException;
import java.util.Locale;
@ -84,7 +84,7 @@ public class MicroBlogException extends Exception implements TwitterResponse, Ht
public ErrorInfo[] getErrors() {
if (errors != null && errorMessage != null && requestPath != null) {
if (errors == null && errorMessage != null && requestPath != null) {
return new ErrorInfo[]{new SingleErrorInfo(errorMessage, requestPath)};
}
return errors;

View File

@ -237,6 +237,7 @@ public interface AccountExtras extends Parcelable {
@SuppressWarnings("RedundantIfStatement")
public boolean checkGeometry(int width, int height) {
if (minWidth <= 0 || maxWidth <= 0) return false;
// Check w & h
boolean widthValid = inRange(width, getMinWidth(), getMaxWidth());
boolean heightValid = inRange(height, getMinHeight(), getMaxHeight());

View File

@ -22,6 +22,7 @@ package org.mariotaku.twidere.util;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.SparseIntArray;
import org.mariotaku.microblog.library.MicroBlogException;
@ -114,23 +115,34 @@ public class StatusCodeMessageUtils {
}
private static DisplayErrorInfo getErrorInfo(final Context context, final int statusCode, final int errorCode) {
if (containsHttpStatus(statusCode)) return getHttpStatusInfo(context, statusCode);
@Nullable
private static DisplayErrorInfo getErrorInfo(@NonNull final Context context, final int statusCode,
@Nullable final ErrorInfo[] errors) {
int errorCode = -1;
if (errors != null) for (ErrorInfo error : errors) {
errorCode = error.getCode();
if (errorCode > 0) break;
String message = error.getMessage();
if (!TextUtils.isEmpty(message)) {
return new DisplayErrorInfo(0, R.drawable.ic_info_error_generic, message);
}
}
if (containsTwitterError(errorCode)) return getTwitterErrorInfo(context, errorCode);
if (containsHttpStatus(statusCode)) return getHttpStatusInfo(context, statusCode);
return null;
}
@NonNull
public static DisplayErrorInfo getMicroBlogErrorInfo(final Context context, final MicroBlogException te) {
final DisplayErrorInfo errorInfo = getErrorInfo(context, te.getStatusCode(), te.getErrorCode());
final DisplayErrorInfo errorInfo = getErrorInfo(context, te.getStatusCode(), te.getErrors());
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());
final DisplayErrorInfo errorInfo = getErrorInfo(context, te.getStatusCode(), te.getErrors());
if (errorInfo != null) return errorInfo.getMessage();
return te.getMessage();
}

View File

@ -40,14 +40,19 @@ fun <T> AccountDetails.newMicroBlogInstance(context: Context, cls: Class<T>): T
val AccountDetails.isOAuth: Boolean
get() = credentials_type == Credentials.Type.OAUTH || credentials_type == Credentials.Type.XAUTH
val AccountDetails.mediaSizeLimit: UpdateStatusTask.SizeLimit
val AccountDetails.mediaSizeLimit: UpdateStatusTask.SizeLimit?
get() = when (type) {
AccountType.TWITTER -> {
val imageLimit = AccountExtras.ImageLimit.ofSize(2048, 1536)
val videoLimit = AccountExtras.VideoLimit.twitterDefault()
UpdateStatusTask.SizeLimit(imageLimit, videoLimit)
}
else -> UpdateStatusTask.SizeLimit(AccountExtras.ImageLimit(), AccountExtras.VideoLimit.unsupported())
AccountType.FANFOU -> {
val imageLimit = AccountExtras.ImageLimit.ofSize(2048, 1536)
val videoLimit = AccountExtras.VideoLimit.unsupported()
UpdateStatusTask.SizeLimit(imageLimit, videoLimit)
}
else -> null
}
/**
* Text limit when composing a status, 0 for no limit

View File

@ -33,7 +33,6 @@ import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.User
import org.mariotaku.sqliteqb.library.Columns
import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.annotation.AccountType
@ -56,13 +55,13 @@ import javax.inject.Inject
class ParcelableUserLoader(
context: Context,
private val accountKey: UserKey,
private val accountKey: UserKey?,
private val userKey: UserKey?,
private val screenName: String?,
private val extras: Bundle?,
private val omitIntentExtra: Boolean,
private val loadFromCache: Boolean
) : FixedAsyncTaskLoader<SingleResponse<ParcelableUser>>(context), Constants {
) : FixedAsyncTaskLoader<SingleResponse<ParcelableUser>>(context) {
private val profileImageSize = context.getString(R.string.profile_image_size)
@ -76,7 +75,7 @@ class ParcelableUserLoader(
override fun loadInBackground(): SingleResponse<ParcelableUser> {
val context = context
val resolver = context.contentResolver
val accountKey = accountKey
val accountKey = accountKey ?: return SingleResponse(MicroBlogException("No account"))
val am = AccountManager.get(context)
val details = AccountUtils.getAllAccountDetails(am, AccountUtils.getAccounts(am), true).firstOrNull {
if (it.key == accountKey) {
@ -105,7 +104,7 @@ class ParcelableUserLoader(
where = Expression.equalsArgs(CachedUsers.USER_KEY)
whereArgs = arrayOf(userKey.toString())
} else if (screenName != null) {
val host = this.accountKey.host
val host = accountKey.host
if (host != null) {
where = Expression.and(
Expression.likeRaw(Columns.Column(CachedUsers.USER_KEY), "'%@'||?"),

View File

@ -346,7 +346,7 @@ class UpdateStatusTask(
@Throws(MicroBlogException::class, UploadException::class)
private fun fanfouUpdateStatusWithPhoto(microBlog: MicroBlog, statusUpdate: ParcelableStatusUpdate,
pendingUpdate: PendingStatusUpdate, sizeLimit: SizeLimit, updateIndex: Int): Status {
pendingUpdate: PendingStatusUpdate, sizeLimit: SizeLimit?, updateIndex: Int): Status {
if (statusUpdate.media.size > 1) {
throw MicroBlogException(context.getString(R.string.error_too_many_photos_fanfou))
}
@ -767,13 +767,13 @@ class UpdateStatusTask(
return@run null
}
val data = if (sizeLimit != null) when (type) {
val data = when (type) {
ParcelableMedia.Type.IMAGE -> imageStream(context, resolver, mediaUri, mediaType,
sizeLimit)
sizeLimit?.image)
ParcelableMedia.Type.VIDEO -> videoStream(context, resolver, mediaUri, mediaType,
sizeLimit, chucked)
sizeLimit?.video, chucked)
else -> null
} else null
}
val cis = data?.stream ?: run {
val st = resolver.openInputStream(mediaUri) ?: throw FileNotFoundException(mediaUri.toString())
@ -849,7 +849,7 @@ class UpdateStatusTask(
resolver: ContentResolver,
mediaUri: Uri,
defaultType: String?,
sizeLimit: SizeLimit
imageLimit: AccountExtras.ImageLimit?
): MediaStreamData? {
var mediaType = defaultType
val o = BitmapFactory.Options()
@ -864,13 +864,11 @@ class UpdateStatusTask(
return null
}
val imageLimit = sizeLimit.image
if (imageLimit.check(o.outWidth, o.outHeight)) {
return null
if (imageLimit != null) {
if (imageLimit.checkGeomentry(o.outWidth, o.outHeight)) return null
o.inSampleSize = Utils.calculateInSampleSize(o.outWidth, o.outHeight,
imageLimit.maxWidth, imageLimit.maxHeight)
}
o.inSampleSize = Utils.calculateInSampleSize(o.outWidth, o.outHeight,
imageLimit.maxWidth, imageLimit.maxHeight)
o.inJustDecodeBounds = false
// Do actual image decoding
val bitmap = context.contentResolver.openInputStream(mediaUri).use {
@ -916,11 +914,10 @@ class UpdateStatusTask(
resolver: ContentResolver,
mediaUri: Uri,
defaultType: String?,
sizeLimit: SizeLimit,
videoLimit: AccountExtras.VideoLimit?,
chucked: Boolean
): MediaStreamData? {
var mediaType = defaultType
val videoLimit = sizeLimit.video
val geometry = Point()
var duration = -1L
var framerate = -1.0
@ -945,20 +942,22 @@ class UpdateStatusTask(
retriever.releaseSafe()
}
if (geometry.x > 0 && geometry.y > 0 && videoLimit.checkGeometry(geometry.x, geometry.y)
&& framerate > 0 && videoLimit.checkFrameRate(framerate)
&& size > 0 && videoLimit.checkSize(size, chucked)) {
// Size valid, upload directly
DebugLog.d(LOGTAG, "Upload video directly")
return null
}
if (videoLimit != null) {
if (geometry.x > 0 && geometry.y > 0 && videoLimit.checkGeometry(geometry.x, geometry.y)
&& framerate > 0 && videoLimit.checkFrameRate(framerate)
&& size > 0 && videoLimit.checkSize(size, chucked)) {
// Size valid, upload directly
DebugLog.d(LOGTAG, "Upload video directly")
return null
}
if (!videoLimit.checkMinDuration(duration, chucked)) {
throw UploadException(context.getString(R.string.message_video_too_short))
}
if (!videoLimit.checkMinDuration(duration, chucked)) {
throw UploadException(context.getString(R.string.message_video_too_short))
}
if (!videoLimit.checkMaxDuration(duration, chucked)) {
throw UploadException(context.getString(R.string.message_video_too_long))
if (!videoLimit.checkMaxDuration(duration, chucked)) {
throw UploadException(context.getString(R.string.message_video_too_long))
}
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
@ -1022,7 +1021,8 @@ class UpdateStatusTask(
context.contentResolver.delete(Drafts.CONTENT_URI, where, null)
}
fun AccountExtras.ImageLimit.check(width: Int, height: Int): Boolean {
fun AccountExtras.ImageLimit.checkGeomentry(width: Int, height: Int): Boolean {
if (this.maxWidth <= 0 || this.maxHeight <= 0) return true
return (width <= this.maxWidth && height <= this.maxHeight) || (height <= this.maxWidth
&& width <= this.maxHeight)
}