1
0
mirror of https://github.com/TwidereProject/Twidere-Android synced 2025-02-02 09:46:51 +01:00

added size limit for StatusNet #848

This commit is contained in:
Mariotaku Lee 2017-05-24 13:34:33 +08:00
parent 83785e1478
commit 53d9ce3f77
No known key found for this signature in database
GPG Key ID: 99505AEA531814F1
16 changed files with 185 additions and 90 deletions

View File

@ -32,16 +32,92 @@ import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
@JsonObject
public class StatusNetConfig implements Parcelable {
public static final Creator<StatusNetConfig> CREATOR = new Creator<StatusNetConfig>() {
@Override
public StatusNetConfig createFromParcel(Parcel source) {
StatusNetConfig target = new StatusNetConfig();
StatusNetConfigParcelablePlease.readFromParcel(target, source);
return target;
}
@Override
public StatusNetConfig[] newArray(int size) {
return new StatusNetConfig[size];
}
};
@JsonField(name = "site")
Site site;
@JsonField(name = "attachments")
Attachments attachments;
public Site getSite() {
return site;
}
public Attachments getAttachments() {
return attachments;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
StatusNetConfigParcelablePlease.writeToParcel(this, dest, flags);
}
@ParcelablePlease
@JsonObject
public static class Attachments implements Parcelable {
@JsonField(name = "file_quota")
long fileQuota;
public long getFileQuota() {
return fileQuota;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
StatusNetConfig$AttachmentsParcelablePlease.writeToParcel(this, dest, flags);
}
public static final Creator<Attachments> CREATOR = new Creator<Attachments>() {
public Attachments createFromParcel(Parcel source) {
Attachments target = new Attachments();
StatusNetConfig$AttachmentsParcelablePlease.readFromParcel(target, source);
return target;
}
public Attachments[] newArray(int size) {
return new Attachments[size];
}
};
}
@ParcelablePlease
@JsonObject
public static class Site implements Parcelable {
public static final Creator<Site> CREATOR = new Creator<Site>() {
@Override
public Site createFromParcel(Parcel source) {
Site target = new Site();
StatusNetConfig$SiteParcelablePlease.readFromParcel(target, source);
return target;
}
@Override
public Site[] newArray(int size) {
return new Site[size];
}
};
@JsonField(name = "textlimit")
int textLimit;
@ -58,43 +134,6 @@ public class StatusNetConfig implements Parcelable {
public void writeToParcel(Parcel dest, int flags) {
StatusNetConfig$SiteParcelablePlease.writeToParcel(this, dest, flags);
}
public static final Creator<Site> CREATOR = new Creator<Site>() {
@Override
public Site createFromParcel(Parcel source) {
Site target = new Site();
StatusNetConfig$SiteParcelablePlease.readFromParcel(target, source);
return target;
}
@Override
public Site[] newArray(int size) {
return new Site[size];
}
};
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
StatusNetConfigParcelablePlease.writeToParcel(this, dest, flags);
}
public static final Creator<StatusNetConfig> CREATOR = new Creator<StatusNetConfig>() {
@Override
public StatusNetConfig createFromParcel(Parcel source) {
StatusNetConfig target = new StatusNetConfig();
StatusNetConfigParcelablePlease.readFromParcel(target, source);
return target;
}
@Override
public StatusNetConfig[] newArray(int size) {
return new StatusNetConfig[size];
}
};
}

View File

@ -37,6 +37,11 @@ public interface AccountExtras extends Parcelable {
@JsonField(name = "max_height")
int maxHeight;
@JsonField(name = "max_size_sync")
long maxSizeSync;
@JsonField(name = "max_size_async")
long maxSizeAsync;
public int getMaxWidth() {
return maxWidth;
}
@ -53,6 +58,22 @@ public interface AccountExtras extends Parcelable {
this.maxHeight = maxHeight;
}
public long getMaxSizeSync() {
return maxSizeSync;
}
public void setMaxSizeSync(long maxSizeSync) {
this.maxSizeSync = maxSizeSync;
}
public long getMaxSizeAsync() {
return maxSizeAsync;
}
public void setMaxSizeAsync(long maxSizeAsync) {
this.maxSizeAsync = maxSizeAsync;
}
@NonNull
public static ImageLimit ofSize(int width, int height) {
final ImageLimit limit = new ImageLimit();
@ -60,6 +81,13 @@ public interface AccountExtras extends Parcelable {
limit.setMaxHeight(height);
return limit;
}
public boolean checkSize(long size, boolean async) {
final long limit = async ? getMaxSizeAsync() : getMaxSizeSync();
if (limit <= 0 || size <= 0) return true;
return size < limit;
}
}
@JsonObject
@ -274,7 +302,7 @@ public interface AccountExtras extends Parcelable {
public boolean checkSize(long size, boolean async) {
final long limit = async ? getMaxSizeAsync() : getMaxSizeSync();
if (limit <= 0) return true;
if (limit <= 0 || size <= 0) return true;
return size < limit;
}

View File

@ -50,6 +50,9 @@ public class StatusNetAccountExtras implements Parcelable, AccountExtras {
@ParcelableThisPlease
@JsonField(name = "text_limit")
int textLimit;
@ParcelableThisPlease
@JsonField(name = "upload_limit")
long uploadLimit;
public int getTextLimit() {
return textLimit;
@ -59,6 +62,14 @@ public class StatusNetAccountExtras implements Parcelable, AccountExtras {
this.textLimit = textLimit;
}
public long getUploadLimit() {
return uploadLimit;
}
public void setUploadLimit(long uploadLimit) {
this.uploadLimit = uploadLimit;
}
@Override
public int describeContents() {
return 0;
@ -73,6 +84,7 @@ public class StatusNetAccountExtras implements Parcelable, AccountExtras {
public String toString() {
return "StatusNetAccountExtras{" +
"textLimit=" + textLimit +
", uploadLimit=" + uploadLimit +
'}';
}
}

View File

@ -44,12 +44,12 @@ operator fun Bundle.set(key: String, value: Array<String>?) {
return putStringArray(key, value)
}
inline fun <reified T> Bundle.getTypedArray(key: String): Array<T> {
inline fun <reified T: Parcelable> Bundle.getTypedArray(key: String): Array<T> {
val parcelable = getParcelableArray(key)
return Array(parcelable.size) { parcelable[it] as T }
}
inline fun <reified T> Bundle.getNullableTypedArray(key: String): Array<T>? {
inline fun <reified T: Parcelable> Bundle.getNullableTypedArray(key: String): Array<T>? {
val parcelable = getParcelableArray(key) ?: return null
return Array(parcelable.size) { parcelable[it] as T }
}

View File

@ -22,6 +22,12 @@ package org.mariotaku.ktextension
import android.content.Intent
import android.os.Parcelable
fun <T> Intent.getTypedArrayExtra(key: String, creator: Parcelable.Creator<T>): Array<T> {
return getParcelableArrayExtra(key).toTypedArray(creator)
inline fun <reified T : Parcelable> Intent.getTypedArrayExtra(key: String): Array<T> {
val extra = getParcelableArrayExtra(key)
return Array(extra.size) { extra[it] as T }
}
inline fun <reified T : Parcelable> Intent.getNullableTypedArrayExtra(key: String): Array<T>? {
val extra = getParcelableArrayExtra(key) ?: return null
return Array(extra.size) { extra[it] as T }
}

View File

@ -1,10 +0,0 @@
package org.mariotaku.ktextension
import android.os.Parcelable
fun <T> Array<Parcelable>.toTypedArray(creator: Parcelable.Creator<T>): Array<T> {
val result = creator.newArray(size)
System.arraycopy(this, 0, result, 0, size)
return result
}

View File

@ -30,7 +30,7 @@ import android.widget.ListView
import android.widget.Toast
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.activity_account_selector.*
import org.mariotaku.ktextension.toTypedArray
import org.mariotaku.ktextension.getNullableTypedArrayExtra
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.adapter.AccountDetailsAdapter
@ -47,7 +47,7 @@ class AccountSelectorActivity : BaseActivity(), OnItemClickListener {
private val onlyIncludeKeys: Array<UserKey>?
get() {
return intent.getParcelableArrayExtra(EXTRA_ACCOUNT_KEYS)?.toTypedArray(UserKey.CREATOR)
return intent.getNullableTypedArrayExtra(EXTRA_ACCOUNT_KEYS)
}
private val isOAuthOnly: Boolean

View File

@ -1073,7 +1073,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
val hasVisibility = intent.hasExtra(EXTRA_VISIBILITY)
val hasAccountKeys: Boolean
if (intent.hasExtra(EXTRA_ACCOUNT_KEYS)) {
val accountKeys = intent.getParcelableArrayExtra(EXTRA_ACCOUNT_KEYS).toTypedArray(UserKey.CREATOR)
val accountKeys = intent.getTypedArrayExtra<UserKey>(EXTRA_ACCOUNT_KEYS)
accountsAdapter.selectedAccountKeys = accountKeys
hasAccountKeys = true
} else if (intent.hasExtra(EXTRA_ACCOUNT_KEY)) {

View File

@ -44,8 +44,8 @@ import kotlinx.android.synthetic.main.activity_media_viewer.*
import org.mariotaku.chameleon.Chameleon
import org.mariotaku.ktextension.checkAllSelfPermissionsGranted
import org.mariotaku.ktextension.contains
import org.mariotaku.ktextension.getNullableTypedArrayExtra
import org.mariotaku.ktextension.setItemAvailability
import org.mariotaku.ktextension.toTypedArray
import org.mariotaku.mediaviewer.library.*
import org.mariotaku.mediaviewer.library.subsampleimageview.SubsampleImageViewerFragment.EXTRA_MEDIA_URI
import org.mariotaku.twidere.R
@ -95,8 +95,8 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
private val initialMedia: ParcelableMedia?
get() = intent.getParcelableExtra<ParcelableMedia>(EXTRA_CURRENT_MEDIA)
private val media: Array<out ParcelableMedia> by lazy {
intent.getParcelableArrayExtra(EXTRA_MEDIA)?.toTypedArray(ParcelableMedia.CREATOR).orEmpty()
private val media: Array<ParcelableMedia> by lazy {
return@lazy intent.getNullableTypedArrayExtra<ParcelableMedia>(EXTRA_MEDIA) ?: emptyArray()
}
private val currentFragment: MediaViewerFragment? get() {

View File

@ -1231,12 +1231,10 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
private fun getStatusNetAccountExtras(twitter: MicroBlog): StatusNetAccountExtras {
// Get StatusNet specific resource
val config = twitter.statusNetConfig
val extras = StatusNetAccountExtras()
val site = config.site
if (site != null) {
extras.textLimit = site.textLimit
return StatusNetAccountExtras().apply {
textLimit = config.site?.textLimit ?: -1
uploadLimit = config.attachments?.fileQuota ?: -1L
}
return extras
}
private fun getTwitterAccountExtras(twitter: MicroBlog): TwitterAccountExtras {

View File

@ -42,19 +42,34 @@ val AccountDetails.isOAuth: Boolean
get() = credentials_type == Credentials.Type.OAUTH || credentials_type == Credentials.Type.XAUTH
val AccountDetails.mediaSizeLimit: UpdateStatusTask.SizeLimit?
get() = when (type) {
get() {
when (type) {
AccountType.TWITTER -> {
val imageLimit = AccountExtras.ImageLimit.ofSize(2048, 1536)
val videoLimit = AccountExtras.VideoLimit.twitterDefault()
UpdateStatusTask.SizeLimit(imageLimit, videoLimit)
return UpdateStatusTask.SizeLimit(imageLimit, videoLimit)
}
AccountType.FANFOU -> {
val imageLimit = AccountExtras.ImageLimit.ofSize(2048, 1536)
val videoLimit = AccountExtras.VideoLimit.unsupported()
UpdateStatusTask.SizeLimit(imageLimit, videoLimit)
return UpdateStatusTask.SizeLimit(imageLimit, videoLimit)
}
else -> null
AccountType.STATUSNET -> {
val extras = extras as? StatusNetAccountExtras ?: return null
val imageLimit = AccountExtras.ImageLimit().apply {
maxSizeSync = extras.uploadLimit
maxSizeAsync = extras.uploadLimit
}
val videoLimit = AccountExtras.VideoLimit().apply {
maxSizeSync = extras.uploadLimit
maxSizeAsync = extras.uploadLimit
}
return UpdateStatusTask.SizeLimit(imageLimit, videoLimit)
}
else -> return null
}
}
/**
* Text limit when composing a status, 0 for no limit
*/

View File

@ -25,7 +25,7 @@ import android.os.Bundle
import android.support.v4.app.FragmentManager
import android.support.v7.app.AlertDialog
import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.toTypedArray
import org.mariotaku.ktextension.getNullableTypedArray
import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_USERS
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_USER_LIST
@ -87,7 +87,7 @@ class DeleteUserListMembersDialogFragment : BaseDialogFragment(), DialogInterfac
get() {
val args = arguments
if (!args.containsKey(EXTRA_USERS)) return null
return args.getParcelableArray(EXTRA_USERS)?.toTypedArray(ParcelableUser.CREATOR)
return args.getNullableTypedArray(EXTRA_USERS)
}
companion object {

View File

@ -23,7 +23,7 @@ import android.app.Dialog
import android.content.DialogInterface
import android.os.Bundle
import android.support.v7.app.AlertDialog
import org.mariotaku.ktextension.toTypedArray
import org.mariotaku.ktextension.getNullableTypedArray
import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.extension.applyTheme
@ -37,15 +37,14 @@ class SensitiveContentWarningDialogFragment : BaseDialogFragment(), DialogInterf
override fun onClick(dialog: DialogInterface, which: Int) {
when (which) {
DialogInterface.BUTTON_POSITIVE -> {
val context = activity
val args = arguments
if (args == null || context == null) return
val context = activity ?: return
val args = arguments ?: return
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
val current = args.getParcelable<ParcelableMedia>(EXTRA_CURRENT_MEDIA)
val status = args.getParcelable<ParcelableStatus>(EXTRA_STATUS)
val option = args.getBundle(EXTRA_ACTIVITY_OPTIONS)
val newDocument = args.getBoolean(EXTRA_NEW_DOCUMENT)
val media = args.getParcelableArray(EXTRA_MEDIA).toTypedArray(ParcelableMedia.CREATOR)
val media: Array<ParcelableMedia> = args.getNullableTypedArray(EXTRA_MEDIA) ?: emptyArray()
IntentUtils.openMediaDirectly(context, accountKey, media, current, option, newDocument,
status)
}

View File

@ -1738,7 +1738,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
class AddRemoveUserListDialogFragment : BaseDialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val lists = arguments.getParcelableArray(EXTRA_USER_LISTS).toTypedArray(ParcelableUserList.CREATOR)
val lists = arguments.getTypedArray<ParcelableUserList>(EXTRA_USER_LISTS)
val userKey = arguments.getParcelable<UserKey>(EXTRA_USER_KEY)
val accountKey = arguments.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
val builder = AlertDialog.Builder(context)

View File

@ -42,8 +42,8 @@ import org.mariotaku.abstask.library.AbstractTask
import org.mariotaku.abstask.library.ManualTaskStarter
import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.configure
import org.mariotaku.ktextension.getNullableTypedArrayExtra
import org.mariotaku.ktextension.toLongOr
import org.mariotaku.ktextension.toTypedArray
import org.mariotaku.ktextension.useCursor
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlogException
@ -222,11 +222,11 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
private fun handleUpdateStatusIntent(intent: Intent) {
val status = intent.getParcelableExtra<ParcelableStatusUpdate>(EXTRA_STATUS)
val statusParcelables = intent.getParcelableArrayExtra(EXTRA_STATUSES)
val statusParcelables = intent.getNullableTypedArrayExtra<ParcelableStatusUpdate>(EXTRA_STATUSES)
val scheduleInfo = intent.getParcelableExtra<ScheduleInfo>(EXTRA_SCHEDULE_INFO)
val statuses: Array<ParcelableStatusUpdate>
if (statusParcelables != null) {
statuses = statusParcelables.toTypedArray(ParcelableStatusUpdate.CREATOR)
statuses = statusParcelables
} else if (status != null) {
statuses = arrayOf(status)
} else

View File

@ -812,7 +812,7 @@ class UpdateStatusTask(
val data = when (type) {
ParcelableMedia.Type.IMAGE -> imageStream(context, resolver, mediaUri, mediaType,
sizeLimit?.image)
sizeLimit?.image, chucked)
ParcelableMedia.Type.VIDEO -> videoStream(context, resolver, mediaUri, mediaType,
sizeLimit?.video, chucked)
else -> null
@ -893,11 +893,18 @@ class UpdateStatusTask(
resolver: ContentResolver,
mediaUri: Uri,
defaultType: String?,
imageLimit: AccountExtras.ImageLimit?
imageLimit: AccountExtras.ImageLimit?,
chucked: Boolean
): MediaStreamData? {
var mediaType = defaultType
val o = BitmapFactory.Options()
o.inJustDecodeBounds = true
val o = BitmapFactory.Options().apply {
inJustDecodeBounds = true
}
var imageSize = -1L
resolver.openInputStream(mediaUri).use {
imageSize = it.available().toLong()
BitmapFactory.decodeStream(it, null, o)
}
BitmapFactoryUtils.decodeUri(resolver, mediaUri, opts = o)
// Try to use decoded media type
if (o.outMimeType != null) {
@ -908,7 +915,8 @@ class UpdateStatusTask(
return null
}
if (imageLimit == null || imageLimit.checkGeomentry(o.outWidth, o.outHeight)) return null
if (imageLimit == null || imageLimit.checkGeomentry(o.outWidth, o.outHeight)
|| imageLimit.checkSize(imageSize, chucked)) return null
o.inSampleSize = o.calculateInSampleSize(imageLimit.maxWidth, imageLimit.maxHeight)
o.inJustDecodeBounds = false
// Do actual image decoding