fixed oauth

This commit is contained in:
Mariotaku Lee 2016-07-16 15:27:46 +08:00
parent 6463922d0e
commit 5af50a7289
10 changed files with 138 additions and 116 deletions

View File

@ -41,8 +41,8 @@ dependencies {
apt 'com.github.mariotaku.ObjectCursor:processor:0.9.9' apt 'com.github.mariotaku.ObjectCursor:processor:0.9.9'
compile 'com.android.support:support-annotations:24.0.0' compile 'com.android.support:support-annotations:24.0.0'
compile 'com.bluelinelabs:logansquare:1.3.7' compile 'com.bluelinelabs:logansquare:1.3.7'
compile 'com.github.mariotaku.RestFu:library:0.9.31' compile 'com.github.mariotaku.RestFu:library:0.9.32'
compile 'com.github.mariotaku.RestFu:oauth:0.9.31' compile 'com.github.mariotaku.RestFu:oauth:0.9.32'
compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2' compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2'
compile 'com.github.mariotaku.ObjectCursor:core:0.9.9' compile 'com.github.mariotaku.ObjectCursor:core:0.9.9'
compile 'com.github.mariotaku.CommonsLibrary:objectcursor:0.9.8' compile 'com.github.mariotaku.CommonsLibrary:objectcursor:0.9.8'

View File

@ -151,8 +151,8 @@ dependencies {
compile 'com.soundcloud.android:android-crop:1.0.1@aar' compile 'com.soundcloud.android:android-crop:1.0.1@aar'
compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2' compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2'
compile 'com.github.mariotaku:PickNCrop:0.9.4' compile 'com.github.mariotaku:PickNCrop:0.9.4'
compile 'com.github.mariotaku.RestFu:library:0.9.31' compile 'com.github.mariotaku.RestFu:library:0.9.32'
compile 'com.github.mariotaku.RestFu:okhttp3:0.9.31' compile 'com.github.mariotaku.RestFu:okhttp3:0.9.32'
compile 'com.squareup.okhttp3:okhttp:3.2.0' compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.lnikkila:extendedtouchview:0.1.0' compile 'com.lnikkila:extendedtouchview:0.1.0'
compile 'com.google.dagger:dagger:2.1' compile 'com.google.dagger:dagger:2.1'

View File

@ -3,11 +3,14 @@ package org.mariotaku.twidere.task.twitter
import android.content.ContentResolver import android.content.ContentResolver
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri import android.net.Uri
import android.support.annotation.UiThread import android.support.annotation.UiThread
import android.support.annotation.WorkerThread import android.support.annotation.WorkerThread
import android.text.TextUtils import android.text.TextUtils
import android.util.Pair import android.util.Pair
import android.util.Size
import org.apache.commons.lang3.ArrayUtils import org.apache.commons.lang3.ArrayUtils
import org.apache.commons.lang3.math.NumberUtils import org.apache.commons.lang3.math.NumberUtils
import org.mariotaku.abstask.library.AbstractTask import org.mariotaku.abstask.library.AbstractTask
@ -26,11 +29,8 @@ import org.mariotaku.restfu.http.mime.SimpleBody
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.Constants import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.app.TwidereApplication import org.mariotaku.twidere.app.TwidereApplication
import org.mariotaku.twidere.constant.SharedPreferenceConstants
import org.mariotaku.twidere.constant.SharedPreferenceConstants.*
import org.mariotaku.twidere.model.* import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.draft.UpdateStatusActionExtra import org.mariotaku.twidere.model.draft.UpdateStatusActionExtra
import org.mariotaku.twidere.model.util.ParcelableAccountUtils import org.mariotaku.twidere.model.util.ParcelableAccountUtils
@ -41,8 +41,7 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
import org.mariotaku.twidere.util.* import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.io.ContentLengthInputStream import org.mariotaku.twidere.util.io.ContentLengthInputStream
import java.io.FileNotFoundException import java.io.*
import java.io.IOException
import java.util.* import java.util.*
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
@ -654,11 +653,26 @@ class UpdateStatusTask(internal val context: Context, internal val stateCallback
@Throws(IOException::class) @Throws(IOException::class)
fun getBodyFromMedia(resolver: ContentResolver, fun getBodyFromMedia(resolver: ContentResolver,
mediaUri: Uri, mediaUri: Uri,
readListener: ContentLengthInputStream.ReadListener): FileBody { readListener: ContentLengthInputStream.ReadListener,
sizeLimit: Size? = null): FileBody {
val mediaType = resolver.getType(mediaUri) val mediaType = resolver.getType(mediaUri)
val `is` = resolver.openInputStream(mediaUri) ?: throw FileNotFoundException(mediaUri.toString()) val st = resolver.openInputStream(mediaUri) ?: throw FileNotFoundException(mediaUri.toString())
val length = `is`.available().toLong() val cis: ContentLengthInputStream
val cis = ContentLengthInputStream(`is`, length) val length: Long
if (sizeLimit != null) {
val o = BitmapFactory.Options()
o.inJustDecodeBounds = true
BitmapFactory.decodeStream(st, null, o)
o.inJustDecodeBounds = false
val bitmap = BitmapFactory.decodeStream(st, null, o)
val os = DirectByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, os)
length = os.size().toLong()
cis = ContentLengthInputStream(os.inputStream(true), length)
} else {
length = st.available().toLong()
cis = ContentLengthInputStream(st, length)
}
cis.setReadListener(readListener) cis.setReadListener(readListener)
val contentType: ContentType val contentType: ContentType
if (TextUtils.isEmpty(mediaType)) { if (TextUtils.isEmpty(mediaType)) {
@ -668,5 +682,28 @@ class UpdateStatusTask(internal val context: Context, internal val stateCallback
} }
return FileBody(cis, "attachment", length, contentType) return FileBody(cis, "attachment", length, contentType)
} }
internal class DirectByteArrayOutputStream : ByteArrayOutputStream {
constructor() : super()
constructor(size: Int) : super(size)
fun inputStream(close: Boolean): InputStream {
return DirectInputStream(this, close)
}
internal class DirectInputStream(
val os: DirectByteArrayOutputStream,
val close: Boolean
) : ByteArrayInputStream(os.buf, 0, os.count) {
override fun close() {
if (close) {
os.close()
}
super.close()
}
}
}
} }
} }

View File

@ -1,72 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.text;
import android.support.annotation.NonNull;
import android.text.TextPaint;
import android.text.style.URLSpan;
import android.view.View;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.model.UserKey;
import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener;
public class TwidereURLSpan extends URLSpan implements Constants {
private final int type, highlightStyle;
private final UserKey accountKey;
private final long extraId;
private final String orig;
private final boolean sensitive;
private final OnLinkClickListener listener;
private final int start, end;
public TwidereURLSpan(final String url, final String orig, final UserKey accountKey, final long extraId,
final int type, final boolean sensitive, final int highlightStyle, int start, int end,
final OnLinkClickListener listener) {
super(url);
this.orig = orig;
this.accountKey = accountKey;
this.extraId = extraId;
this.type = type;
this.sensitive = sensitive;
this.highlightStyle = highlightStyle;
this.start = start;
this.end = end;
this.listener = listener;
}
@Override
public void onClick(@NonNull final View widget) {
if (listener != null) {
listener.onLinkClick(getURL(), orig, accountKey, extraId, type, sensitive, start, end);
}
}
@Override
public void updateDrawState(@NonNull final TextPaint ds) {
if ((highlightStyle & VALUE_LINK_HIGHLIGHT_OPTION_CODE_UNDERLINE) != 0) {
ds.setUnderlineText(true);
}
if ((highlightStyle & VALUE_LINK_HIGHLIGHT_OPTION_CODE_HIGHLIGHT) != 0) {
ds.setColor(ds.linkColor);
}
}
}

View File

@ -0,0 +1,56 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.text
import android.text.TextPaint
import android.text.style.URLSpan
import android.view.View
import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.constant.SharedPreferenceConstants.VALUE_LINK_HIGHLIGHT_OPTION_CODE_HIGHLIGHT
import org.mariotaku.twidere.constant.SharedPreferenceConstants.VALUE_LINK_HIGHLIGHT_OPTION_CODE_UNDERLINE
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener
class TwidereURLSpan(
url: String,
private val orig: String?,
private val accountKey: UserKey?,
private val extraId: Long,
private val type: Int,
private val sensitive: Boolean,
private val highlightStyle: Int,
private val start: Int,
private val end: Int,
private val listener: OnLinkClickListener?
) : URLSpan(url), Constants {
override fun onClick(widget: View) {
listener?.onLinkClick(url, orig, accountKey, extraId, type, sensitive, start, end)
}
override fun updateDrawState(ds: TextPaint) {
if (highlightStyle and VALUE_LINK_HIGHLIGHT_OPTION_CODE_UNDERLINE != 0) {
ds.isUnderlineText = true
}
if (highlightStyle and VALUE_LINK_HIGHLIGHT_OPTION_CODE_HIGHLIGHT != 0) {
ds.color = ds.linkColor
}
}
}

View File

@ -43,7 +43,7 @@ open class OnLinkClickHandler(
protected val preferences: SharedPreferencesWrapper protected val preferences: SharedPreferencesWrapper
) : OnLinkClickListener { ) : OnLinkClickListener {
override fun onLinkClick(link: String, orig: String?, accountKey: UserKey, override fun onLinkClick(link: String, orig: String?, accountKey: UserKey?,
extraId: Long, type: Int, sensitive: Boolean, extraId: Long, type: Int, sensitive: Boolean,
start: Int, end: Int): Boolean { start: Int, end: Int): Boolean {
if (manager != null && manager.isActive) return false if (manager != null && manager.isActive) return false
@ -67,7 +67,7 @@ open class OnLinkClickHandler(
} }
TwidereLinkify.LINK_TYPE_LINK_IN_TEXT -> { TwidereLinkify.LINK_TYPE_LINK_IN_TEXT -> {
if (isMedia(link, extraId)) { if (isMedia(link, extraId)) {
openMedia(accountKey, extraId, sensitive, link, start, end) openMedia(accountKey!!, extraId, sensitive, link, start, end)
} else { } else {
openLink(link) openLink(link)
} }
@ -75,7 +75,7 @@ open class OnLinkClickHandler(
} }
TwidereLinkify.LINK_TYPE_ENTITY_URL -> { TwidereLinkify.LINK_TYPE_ENTITY_URL -> {
if (isMedia(link, extraId)) { if (isMedia(link, extraId)) {
openMedia(accountKey, extraId, sensitive, link, start, end) openMedia(accountKey!!, extraId, sensitive, link, start, end)
} else { } else {
val authority = UriUtils.getAuthority(link) val authority = UriUtils.getAuthority(link)
if (authority == null) { if (authority == null) {
@ -110,7 +110,7 @@ open class OnLinkClickHandler(
} }
else -> { else -> {
if (IntentUtils.isWebLinkHandled(context, Uri.parse(link))) { if (IntentUtils.isWebLinkHandled(context, Uri.parse(link))) {
openTwitterLink(link, accountKey) openTwitterLink(link, accountKey!!)
return true return true
} }
} }

View File

@ -20,6 +20,7 @@
package org.mariotaku.twidere.util; package org.mariotaku.twidere.util;
import android.support.annotation.IntDef; import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
@ -276,9 +277,10 @@ public final class TwidereLinkify implements Constants {
final int listEnd = matcherEnd(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST); final int listEnd = matcherEnd(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST);
final String username = matcherGroup(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_USERNAME); final String username = matcherGroup(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_USERNAME);
final String list = matcherGroup(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST); final String list = matcherGroup(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST);
if (username != null) {
applyLink(username, null, start, usernameEnd, spannable, accountKey, extraId, applyLink(username, null, start, usernameEnd, spannable, accountKey, extraId,
LINK_TYPE_MENTION, false, highlightOption, listener); LINK_TYPE_MENTION, false, highlightOption, listener);
if (listStart >= 0 && listEnd >= 0 && list != null && username != null) { if (listStart >= 0 && listEnd >= 0 && list != null) {
StringBuilder sb = new StringBuilder(username); StringBuilder sb = new StringBuilder(username);
if (!list.startsWith("/")) { if (!list.startsWith("/")) {
sb.append("/"); sb.append("/");
@ -289,6 +291,7 @@ public final class TwidereLinkify implements Constants {
} }
hasMatches = true; hasMatches = true;
} }
}
// Extract lists from twitter.com links. // Extract lists from twitter.com links.
final URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class); final URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
for (final URLSpan span : spans) { for (final URLSpan span : spans) {
@ -307,8 +310,8 @@ public final class TwidereLinkify implements Constants {
return hasMatches; return hasMatches;
} }
private void applyLink(final String url, final String orig, final int start, final int end, private void applyLink(@NonNull final String url, @Nullable final String orig, final int start, final int end,
final Spannable text, final UserKey accountKey, final long extraId, final int type, final boolean sensitive, final Spannable text, @Nullable final UserKey accountKey, final long extraId, final int type, final boolean sensitive,
final int highlightOption, final OnLinkClickListener listener) { final int highlightOption, final OnLinkClickListener listener) {
final TwidereURLSpan span = new TwidereURLSpan(url, orig, accountKey, extraId, type, sensitive, final TwidereURLSpan span = new TwidereURLSpan(url, orig, accountKey, extraId, type, sensitive,
highlightOption, start, end, listener); highlightOption, start, end, listener);
@ -323,7 +326,7 @@ public final class TwidereLinkify implements Constants {
} }
public interface OnLinkClickListener { public interface OnLinkClickListener {
boolean onLinkClick(String link, String orig, UserKey accountKey, long extraId, int type, boolean onLinkClick(@NonNull String link, @Nullable String orig, @Nullable UserKey accountKey, long extraId, int type,
boolean sensitive, int start, int end); boolean sensitive, int start, int end);
} }
} }

View File

@ -36,7 +36,7 @@ import android.widget.AdapterView.OnItemClickListener
import android.widget.ListView import android.widget.ListView
import android.widget.Toast import android.widget.Toast
import kotlinx.android.synthetic.main.activity_account_selector.* import kotlinx.android.synthetic.main.activity_account_selector.*
import org.apache.commons.lang3.ArrayUtils import org.mariotaku.ktextension.asTypedArray
import org.mariotaku.sqliteqb.library.Columns import org.mariotaku.sqliteqb.library.Columns
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
@ -45,6 +45,7 @@ import org.mariotaku.twidere.adapter.AccountsAdapter
import org.mariotaku.twidere.app.TwidereApplication import org.mariotaku.twidere.app.TwidereApplication
import org.mariotaku.twidere.model.ParcelableAccount import org.mariotaku.twidere.model.ParcelableAccount
import org.mariotaku.twidere.model.ParcelableCredentials import org.mariotaku.twidere.model.ParcelableCredentials
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts import org.mariotaku.twidere.provider.TwidereDataStore.Accounts
import java.util.* import java.util.*
@ -124,12 +125,9 @@ class AccountSelectorActivity : BaseActivity(), LoaderCallbacks<Cursor?>, OnClic
val adapter = adapter!! val adapter = adapter!!
adapter.swapCursor(cursor) adapter.swapCursor(cursor)
if (cursor != null && firstCreated) { if (cursor != null && firstCreated) {
val activatedIds = intentExtraIds val activatedKeys = intentExtraIds
var i = 0 for (i in 0..adapter.count - 1) {
val j = adapter.count accountsList.setItemChecked(i, activatedKeys?.contains(adapter.getAccount(i)!!.account_key) ?: false)
while (i < j) {
accountsList.setItemChecked(i, ArrayUtils.contains(activatedIds, adapter.getItemId(i)))
i++
} }
} }
if (adapter.count == 1 && shouldSelectOnlyItem()) { if (adapter.count == 1 && shouldSelectOnlyItem()) {
@ -199,9 +197,9 @@ class AccountSelectorActivity : BaseActivity(), LoaderCallbacks<Cursor?>, OnClic
super.onStop() super.onStop()
} }
private val intentExtraIds: LongArray private val intentExtraIds: Array<UserKey>?
get() { get() {
return intent.getLongArrayExtra(EXTRA_IDS) return intent.getParcelableArrayExtra(EXTRA_ACCOUNT_KEYS)?.asTypedArray(UserKey.CREATOR)
} }
private val isOAuthOnly: Boolean private val isOAuthOnly: Boolean

View File

@ -1364,7 +1364,7 @@ class StatusFragment : BaseSupportFragment(), LoaderCallbacks<SingleResponse<Par
preferences: SharedPreferencesWrapper preferences: SharedPreferencesWrapper
) : StatusLinkClickHandler(context, manager, preferences) { ) : StatusLinkClickHandler(context, manager, preferences) {
override fun onLinkClick(link: String, orig: String?, accountKey: UserKey, override fun onLinkClick(link: String, orig: String?, accountKey: UserKey?,
extraId: Long, type: Int, sensitive: Boolean, start: Int, end: Int): Boolean { extraId: Long, type: Int, sensitive: Boolean, start: Int, end: Int): Boolean {
val current = getCurrentMedia(link, extraId.toInt()) val current = getCurrentMedia(link, extraId.toInt())
if (current != null && !current.open_browser) { if (current != null && !current.open_browser) {

View File

@ -1113,7 +1113,7 @@ class UserFragment : BaseSupportFragment(), OnClickListener, OnLinkClickListener
} }
override fun onLinkClick(link: String?, orig: String, accountKey: UserKey, override fun onLinkClick(link: String, orig: String?, accountKey: UserKey?,
extraId: Long, type: Int, sensitive: Boolean, extraId: Long, type: Int, sensitive: Boolean,
start: Int, end: Int): Boolean { start: Int, end: Int): Boolean {
val user = user ?: return false val user = user ?: return false
@ -1124,7 +1124,7 @@ class UserFragment : BaseSupportFragment(), OnClickListener, OnLinkClickListener
return true return true
} }
TwidereLinkify.LINK_TYPE_HASHTAG -> { TwidereLinkify.LINK_TYPE_HASHTAG -> {
IntentUtils.openTweetSearch(activity, user.account_key, "#" + link!!) IntentUtils.openTweetSearch(activity, user.account_key, "#" + link)
return true return true
} }
TwidereLinkify.LINK_TYPE_LINK_IN_TEXT, TwidereLinkify.LINK_TYPE_ENTITY_URL -> { TwidereLinkify.LINK_TYPE_LINK_IN_TEXT, TwidereLinkify.LINK_TYPE_ENTITY_URL -> {
@ -1139,8 +1139,8 @@ class UserFragment : BaseSupportFragment(), OnClickListener, OnLinkClickListener
return true return true
} }
TwidereLinkify.LINK_TYPE_LIST -> { TwidereLinkify.LINK_TYPE_LIST -> {
val mentionList = link?.split("/".toRegex())?.dropLastWhile { it.isEmpty() }?.toTypedArray() val mentionList = link.split("/".toRegex()).dropLastWhile { it.isEmpty() }
if (mentionList?.size != 2) { if (mentionList.size != 2) {
return false return false
} }
return true return true