fixed several adapter count crashes

added buffer login in compose screen
This commit is contained in:
Mariotaku Lee 2017-03-26 21:41:28 +08:00
parent 6f4b9e43f3
commit 64c2371786
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
16 changed files with 159 additions and 118 deletions

View File

@ -54,7 +54,8 @@ subprojects {
OSMDroid : '5.6.4',
LeakCanary : '1.5',
TwitterText : '1.14.3',
MediaViewerLibrary : '0.9.23'
MediaViewerLibrary : '0.9.23',
PickNCrop : '0.9.22'
]
}

View File

@ -161,7 +161,7 @@ dependencies {
compile "com.bluelinelabs:logansquare:${libVersions['LoganSquare']}"
compile 'com.soundcloud.android:android-crop:1.0.1@aar'
compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2'
compile 'com.github.mariotaku:PickNCrop:0.9.21'
compile "com.github.mariotaku:PickNCrop:${libVersions['PickNCrop']}"
compile "com.github.mariotaku.RestFu:library:${libVersions['RestFu']}"
compile "com.github.mariotaku.RestFu:okhttp3:${libVersions['RestFu']}"
compile 'com.squareup.okhttp3:okhttp:3.6.0'

View File

@ -1,53 +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.util.webkit;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import static org.mariotaku.twidere.util.Utils.showErrorMessage;
public class DefaultWebViewClient extends WebViewClient {
private final Activity mActivity;
public DefaultWebViewClient(final Activity activity) {
mActivity = activity;
}
@Override
@Deprecated
public boolean shouldOverrideUrlLoading(final WebView view, final String url) {
try {
mActivity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
} catch (final ActivityNotFoundException e) {
showErrorMessage(mActivity, null, e, false);
}
return true;
}
public Activity getActivity() {
return mActivity;
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.util.webkit
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.webkit.WebView
import android.webkit.WebViewClient
import org.mariotaku.twidere.util.Utils.showErrorMessage
open class DefaultWebViewClient<out A : Activity>(val activity: A) : WebViewClient() {
@Deprecated("")
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
try {
activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
} catch (e: ActivityNotFoundException) {
showErrorMessage(activity, null, e, false)
}
return true
}
}

View File

@ -107,9 +107,9 @@ open class BaseActivity : ChameleonActivity(), IBaseActivity<BaseActivity>, IThe
@Inject
lateinit var restHttpClient: RestHttpClient
protected val statusScheduleController: StatusScheduleController? by lazy {
statusScheduleControllerFactory.newInstance(this)
}
protected val statusScheduleController: StatusScheduleController?
get() = statusScheduleControllerFactory.newInstance(this)
private val actionHelper = IBaseActivity.ActionHelper(this)
private val themePreferences by lazy {

View File

@ -32,6 +32,7 @@ import android.view.MenuItem
import android.view.View
import android.webkit.CookieManager
import android.webkit.JavascriptInterface
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_browser_sign_in.*
@ -77,6 +78,7 @@ class BrowserSignInActivity : BaseActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_browser_sign_in)
CookieManager.getInstance().removeAllCookiesSupport()
webView.setWebChromeClient(AuthorizationWebChromeClient(this))
webView.setWebViewClient(AuthorizationWebViewClient(this))
webView.isVerticalScrollBarEnabled = false
webView.addJavascriptInterface(InjectorJavaScriptInterface(this), "injector")
@ -134,16 +136,31 @@ class BrowserSignInActivity : BaseActivity() {
progressContainer.visibility = if (shown) View.VISIBLE else View.GONE
}
private fun setLoadProgress(progress: Int) {
loadProgress.progress = progress
}
private fun setRequestToken(token: OAuthToken) {
requestToken = token
}
internal class AuthorizationWebViewClient(activity: BrowserSignInActivity) : DefaultWebViewClient(activity) {
internal class AuthorizationWebChromeClient(val activity: BrowserSignInActivity) : WebChromeClient() {
override fun onProgressChanged(view: WebView, newProgress: Int) {
super.onProgressChanged(view, newProgress)
activity.setLoadProgress(newProgress)
}
}
internal class AuthorizationWebViewClient(activity: BrowserSignInActivity) : DefaultWebViewClient<BrowserSignInActivity>(activity) {
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
activity.setLoadProgressShown(true)
}
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
view.loadUrl(INJECT_CONTENT)
val activity = activity as BrowserSignInActivity
activity.setLoadProgressShown(false)
val uri = Uri.parse(url)
// Hack for fanfou
@ -164,11 +181,6 @@ class BrowserSignInActivity : BaseActivity() {
}
}
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
(activity as BrowserSignInActivity).setLoadProgressShown(true)
}
@Suppress("Deprecation")
override fun onReceivedError(view: WebView, errorCode: Int, description: String?,
failingUrl: String?) {
@ -183,7 +195,7 @@ class BrowserSignInActivity : BaseActivity() {
val uri = Uri.parse(url)
if (url.startsWith(TwidereConstants.OAUTH_CALLBACK_URL)) {
val oauthVerifier = uri.getQueryParameter(EXTRA_OAUTH_VERIFIER)
val activity = activity as BrowserSignInActivity
val activity = activity
val requestToken = activity.requestToken
if (oauthVerifier != null && requestToken != null) {
val intent = Intent()

View File

@ -76,6 +76,13 @@ class MessagesConversationAdapter(
var listener: Listener? = null
var displaySenderProfile: Boolean = false
override var loadMoreIndicatorPosition: Long
get() = super.loadMoreIndicatorPosition
set(value) {
super.loadMoreIndicatorPosition = value
updateItemCounts()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
when (viewType) {
@ -126,8 +133,6 @@ class MessagesConversationAdapter(
}
override fun getItemCount(): Int {
itemCounts[ITEM_START_MESSAGE] = messages?.size ?: 0
itemCounts[ITEM_START_LOAD_OLDER] = if (loadMoreIndicatorPosition and ILoadMoreSupportAdapter.START != 0L) 1 else 0
return itemCounts.itemCount
}
@ -162,9 +167,15 @@ class MessagesConversationAdapter(
fun setData(conversation: ParcelableMessageConversation?, messages: List<ParcelableMessage>?) {
this.conversation = conversation
this.messages = messages
updateItemCounts()
notifyDataSetChanged()
}
private fun updateItemCounts() {
itemCounts[ITEM_START_MESSAGE] = messages?.size ?: 0
itemCounts[ITEM_START_LOAD_OLDER] = if (loadMoreIndicatorPosition and ILoadMoreSupportAdapter.START != 0L) 1 else 0
}
interface Listener {
fun onMediaClick(position: Int, media: ParcelableMedia, accountKey: UserKey?)

View File

@ -28,12 +28,14 @@ class MessagesEntriesAdapter(
var conversations: List<ParcelableMessageConversation>? = null
set(value) {
field = value
updateItemCounts()
notifyDataSetChanged()
}
var drawAccountColors: Boolean = false
set(value) {
field = value
updateItemCounts()
notifyDataSetChanged()
}
@ -42,8 +44,6 @@ class MessagesEntriesAdapter(
var listener: MessageConversationClickListener? = null
override fun getItemCount(): Int {
itemCounts[0] = conversations?.size ?: 0
itemCounts[1] = if (loadMoreIndicatorPosition and ILoadMoreSupportAdapter.END != 0L) 1 else 0
return itemCounts.itemCount
}
@ -80,6 +80,11 @@ class MessagesEntriesAdapter(
throw UnsupportedOperationException()
}
private fun updateItemCounts() {
itemCounts[0] = conversations?.size ?: 0
itemCounts[1] = if (loadMoreIndicatorPosition and ILoadMoreSupportAdapter.END != 0L) 1 else 0
}
fun getConversation(position: Int): ParcelableMessageConversation? {
return conversations?.get(position - itemCounts.getItemStartPosition(0))
}

View File

@ -52,6 +52,7 @@ class SelectableUsersAdapter(
var data: List<ParcelableUser>? = null
set(value) {
field = value
updateItemCounts()
notifyDataSetChanged()
}
@ -60,10 +61,6 @@ class SelectableUsersAdapter(
}
override fun getItemCount(): Int {
val position = loadMoreIndicatorPosition
itemCounts[0] = if (position and ILoadMoreSupportAdapter.START != 0L) 1 else 0
itemCounts[1] = userCount
itemCounts[2] = if (position and ILoadMoreSupportAdapter.END != 0L) 1 else 0
return itemCounts.itemCount
}
@ -91,11 +88,12 @@ class SelectableUsersAdapter(
}
override fun getItemViewType(position: Int): Int {
when (itemCounts.getItemCountIndex(position)) {
val countIndex = itemCounts.getItemCountIndex(position)
when (countIndex) {
0, 2 -> ILoadMoreSupportAdapter.ITEM_VIEW_TYPE_LOAD_INDICATOR
1 -> return ITEM_VIEW_TYPE_USER
}
throw UnsupportedOperationException()
throw UnsupportedOperationException("Unsupported countIndex $countIndex, position $position")
}
override fun getItemId(position: Int): Long {
@ -104,13 +102,20 @@ class SelectableUsersAdapter(
0, 2 -> return Integer.MAX_VALUE.toLong() + countIndex
1 -> return getUser(position)!!.hashCode().toLong()
}
throw UnsupportedOperationException()
throw UnsupportedOperationException("Unsupported countIndex $countIndex, position $position")
}
private fun bindUser(holder: SelectableUserViewHolder, position: Int) {
holder.displayUser(getUser(position)!!)
}
private fun updateItemCounts() {
val position = loadMoreIndicatorPosition
itemCounts[0] = if (position and ILoadMoreSupportAdapter.START != 0L) 1 else 0
itemCounts[1] = userCount
itemCounts[2] = if (position and ILoadMoreSupportAdapter.END != 0L) 1 else 0
}
fun getUser(position: Int): ParcelableUser? {
return data?.getOrNull(position - itemCounts.getItemStartPosition(1))
}

View File

@ -509,12 +509,14 @@ class MessageConversationInfoFragment : BaseFragment(), IToolBarSupportFragment,
var conversation: ParcelableMessageConversation? = null
set(value) {
field = value
updateItemCounts()
notifyDataSetChanged()
}
var showButtonSpace: Boolean = false
set(value) {
field = value
updateItemCounts()
notifyDataSetChanged()
}
@ -524,25 +526,6 @@ class MessageConversationInfoFragment : BaseFragment(), IToolBarSupportFragment,
}
override fun getItemCount(): Int {
val conversation = this.conversation ?: return 0
val participantsSize = conversation.participants.size
itemCounts[ITEM_INDEX_TOP_SPACE] = if (showButtonSpace) 1 else 0
itemCounts[ITEM_INDEX_HEADER] = 1
itemCounts[ITEM_INDEX_ITEM] = participantsSize
when (conversation.conversation_type) {
ConversationType.GROUP -> {
if (participantsSize < defaultFeatures.getDirectMessageMaxParticipants(conversation.conversation_extras_type)) {
itemCounts[ITEM_INDEX_ADD_USER] = 1
} else {
itemCounts[ITEM_INDEX_ADD_USER] = 0
}
}
else -> {
itemCounts[ITEM_INDEX_ADD_USER] = 0
}
}
itemCounts[ITEM_INDEX_SPACE] = 1
return itemCounts.itemCount
}
@ -613,6 +596,31 @@ class MessageConversationInfoFragment : BaseFragment(), IToolBarSupportFragment,
return conversation?.participants?.getOrNull(itemPos)
}
private fun updateItemCounts() {
val conversation = this.conversation ?: run {
itemCounts.clear()
return
}
val participantsSize = conversation.participants.size
itemCounts[ITEM_INDEX_TOP_SPACE] = if (showButtonSpace) 1 else 0
itemCounts[ITEM_INDEX_HEADER] = 1
itemCounts[ITEM_INDEX_ITEM] = participantsSize
when (conversation.conversation_type) {
ConversationType.GROUP -> {
if (participantsSize < defaultFeatures.getDirectMessageMaxParticipants(conversation.conversation_extras_type)) {
itemCounts[ITEM_INDEX_ADD_USER] = 1
} else {
itemCounts[ITEM_INDEX_ADD_USER] = 0
}
}
else -> {
itemCounts[ITEM_INDEX_ADD_USER] = 0
}
}
itemCounts[ITEM_INDEX_SPACE] = 1
}
interface Listener {
fun onUserClick(position: Int) {}
fun onAddUserClick(position: Int) {}

View File

@ -35,4 +35,10 @@ class ItemCounts(counts: Int) {
return data[countIndex]
}
fun clear() {
for (i in data.indices) {
data[i] = 0
}
}
}

View File

@ -572,16 +572,6 @@ class UpdateStatusTask(
constructor(message: String) : super(message)
}
class ScheduleException : UpdateStatusException {
constructor() : super()
constructor(detailMessage: String, throwable: Throwable) : super(detailMessage, throwable)
constructor(throwable: Throwable) : super(throwable)
constructor(message: String) : super(message)
}
class ExtensionVersionMismatchException : AbsServiceInterface.CheckServiceException()

View File

@ -35,12 +35,23 @@ import java.util.*
interface StatusScheduleController {
@WorkerThread
@Throws(UpdateStatusTask.ScheduleException::class)
@Throws(ScheduleException::class)
fun scheduleStatus(statusUpdate: ParcelableStatusUpdate, pendingUpdate: PendingStatusUpdate,
scheduleInfo: ScheduleInfo)
fun createSetScheduleIntent(): Intent
class ScheduleException : UpdateStatusTask.UpdateStatusException {
constructor() : super()
constructor(detailMessage: String, throwable: Throwable) : super(detailMessage, throwable)
constructor(throwable: Throwable) : super(throwable)
constructor(message: String) : super(message)
}
interface Factory {
fun newInstance(context: Context): StatusScheduleController?

View File

@ -346,10 +346,7 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
mediaPreview.visibility = View.GONE
}
var displayEnd = -1
if (status.extras.display_text_range != null) {
displayEnd = status.extras.display_text_range!![1]
}
val displayEnd = status.extras?.display_text_range?.getOrNull(1) ?: -1
val text: CharSequence
if (adapter.linkHighlightingStyle != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {

View File

@ -35,11 +35,15 @@
android:layout_height="match_parent"
android:clickable="false">
<com.pnikosis.materialishprogress.ProgressWheel
android:layout_width="@dimen/element_size_mlarge"
android:layout_height="@dimen/element_size_mlarge"
android:layout_gravity="center"
app:matProg_progressIndeterminate="true"/>
<ProgressBar
android:id="@+id/loadProgress"
style="?android:progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="8dp"
android:layout_gravity="top"
android:layout_marginTop="-2dp"
android:indeterminate="false"
android:max="100"/>
</FrameLayout>
</RelativeLayout>

View File

@ -598,6 +598,7 @@
<string name="message_destroy_conversation_confirm">Leave this conversation?</string>
<string name="message_direct_message_deleted">Direct message deleted.</string>
<string name="message_direct_message_sent">Direct message sent.</string>
<string name="message_error_buffer_media_not_supported">Schedule media with Buffer is not yet supported</string>
<string name="message_error_invalid_account">Some account data are corrupted, Twidere will remove those accounts to prevent crash.</string>
<string name="message_format_compose_message_convert_to_status">This tweet will be sent as a message to <xliff:g id="name">%1$s</xliff:g>, continue? Converting to a normal tweet uses an extra character.</string>
<string name="message_format_conversation_avatar_update">Conversation avatar changed</string>
@ -1122,6 +1123,7 @@
<string name="title_block_user">Block <xliff:g id="name">%s</xliff:g></string>
<string name="title_blocked_users">Blocked users</string>
<string name="title_browser_sign_in">Browser sign in</string>
<string name="title_buffer_set_schedule">Schedule with Buffer</string>
<string name="title_compose">Compose</string>
<string name="title_conversation">Conversation</string>
<string name="title_dialog_sync_connect_to">Connect to…</string>
@ -1154,6 +1156,7 @@
<string name="title_search">Search</string>
<string name="title_select_users">Select users</string>
<string name="title_set_nickname">Set nickname</string>
<string name="title_sign_in_to_buffer">Sign in to Buffer</string>
<string name="title_status">Tweet</string>
<string name="title_statuses">Tweets</string>
<string name="title_statuses_scheduling">Tweets scheduling</string>
@ -1258,6 +1261,4 @@
<string name="users_statuses">User\'s tweets</string>
<string name="vibration">Vibration</string>
<string name="message_error_buffer_media_not_supported">Schedule media with Buffer is not yet supported</string>
<string name="title_buffer_set_schedule">Schedule with Buffer</string>
</resources>