Merge branch 'maintenance'

This commit is contained in:
Tlaster 2020-04-24 16:46:14 +08:00
commit e2acc418d4
7 changed files with 73 additions and 42 deletions

View File

@ -17,8 +17,8 @@ buildscript {
allprojects {
ext {
projectGroupId = 'org.mariotaku.twidere'
projectVersionCode = 509
projectVersionName = '4.1.0'
projectVersionCode = 510
projectVersionName = '4.1.1'
globalCompileSdkVersion = 29
globalBuildToolsVersion = "29.0.3"

View File

@ -185,8 +185,6 @@ dependencies {
implementation 'com.commonsware.cwac:layouts:0.4.3'
implementation 'com.rengwuxian.materialedittext:library:2.1.4'
implementation 'com.pnikosis:materialish-progress:1.7'
implementation "com.github.mariotaku:MessageBubbleView:${libVersions['MessageBubbleView']}"
implementation 'com.github.mariotaku:DragSortListView:0.6.1'
implementation 'com.github.uucky:ColorPicker-Android:0.9.7@aar'
implementation "pl.droidsonroids.gif:android-gif-drawable:${libVersions['AndroidGIFDrawable']}"
implementation 'com.sprylab.android.texturevideoview:texturevideoview:1.2.1'
@ -216,7 +214,8 @@ dependencies {
/** Custom dependencies **/
implementation 'com.github.mariotaku:MessageBubbleView:1.6'
implementation 'com.github.mariotaku:DragSortListView:0.6.1'
implementation "com.github.mariotaku:MessageBubbleView:${libVersions['MessageBubbleView']}"
implementation 'com.github.mariotaku:DragSortListView:0.6.1'
implementation "com.github.mariotaku.MediaViewerLibrary:base:${libVersions['MediaViewerLibrary']}"
implementation "com.github.mariotaku.MediaViewerLibrary:subsample-image-view:${libVersions['MediaViewerLibrary']}"

View File

@ -1032,6 +1032,12 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
}
return true
}
R.id.copy_url -> {
val uri = LinkCreator.getUserWebLink(user)
ClipboardUtils.setText(context, uri.toString())
Toast.makeText(context, R.string.message_toast_link_copied_to_clipboard, Toast.LENGTH_SHORT).show()
return true
}
R.id.qr_code -> {
executeAfterFragmentResumed {
val df = UserQrDialogFragment()

View File

@ -38,7 +38,6 @@ import org.mariotaku.twidere.extension.atto.filter
import org.mariotaku.twidere.extension.atto.firstElementOrNull
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.isOfficial
import org.mariotaku.twidere.extension.model.makeOriginal
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.AccountDetails
@ -153,39 +152,34 @@ class ConversationLoader(
}
if (loadReplies || noSinceMaxId || sinceId != null && sinceSortId > status.sort_id) {
// Load replies
var repliesLoaded = false
// try {
// if (details.type == AccountType.TWITTER) {
// if (noSinceMaxId) {
// statuses.addAll(loadTwitterWebReplies(details, twitter))
// }
// repliesLoaded = true
// }
// } catch (e: MicroBlogException) {
// // Ignore
// }
if (!repliesLoaded) {
val query = SearchQuery()
query.count(100)
try {
if (details.type == AccountType.TWITTER) {
query.query("to:${status.user_screen_name} since_id:${status.id}")
} else {
query.query("@${status.user_screen_name}")
// try to load thread
statuses.addAll(loadTwitterWebReplies(details, twitter))
}
query.sinceId(sinceId ?: status.id)
try {
val queryResult = twitter.search(query)
val firstId = queryResult.firstOrNull()?.id
if (firstId != null) {
nextPagination = SinceMaxPagination.sinceId(firstId, 0)
}
queryResult.filterTo(statuses) { it.inReplyToStatusId == status.id }
} catch (e: MicroBlogException) {
// Ignore for now
} catch (e: MicroBlogException) {
// Ignore
}
val query = SearchQuery()
query.count(100)
if (details.type == AccountType.TWITTER) {
query.query("to:${status.user_screen_name} since_id:${status.id}")
} else {
query.query("@${status.user_screen_name}")
}
query.sinceId(sinceId ?: status.id)
try {
val queryResult = twitter.search(query)
val firstId = queryResult.firstOrNull()?.id
if (firstId != null) {
nextPagination = SinceMaxPagination.sinceId(firstId, 0)
}
queryResult.filterTo(statuses) { it.inReplyToStatusId == status.id }
} catch (e: MicroBlogException) {
// Ignore for now
}
}
return statuses.mapTo(PaginatedArrayList()) {
return statuses.distinctBy { it.id }.mapTo(PaginatedArrayList()) {
it.toParcelable(details, profileImageSize)
}.apply {
this.nextPage = nextPagination

View File

@ -60,6 +60,7 @@ import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.UriUtils
import org.mariotaku.twidere.util.content.ContentResolverUtils
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.filter
@ -171,19 +172,27 @@ class GetMessagesTask(
}.filter { it.sender != null && it.recipient != null }
val insertMessages = arrayListOf<ParcelableMessage>()
val conversations = hashMapOf<String, ParcelableMessageConversation>()
val conversationIds = hashSetOf<String>()
result.forEach {
conversationIds.add(ParcelableMessageUtils.incomingConversationId(it.senderId, it.recipientId))
}
val conversationIds = result.map {
if (it.senderId == details.key.id) {
ParcelableMessageUtils.outgoingConversationId(it.senderId, it.recipientId)
} else {
ParcelableMessageUtils.incomingConversationId(it.senderId, it.recipientId)
}
}.distinct().toHashSet()
val conversations = hashMapOf<String, ParcelableMessageConversation>()
conversations.addLocalConversations(context, accountKey, conversationIds)
// remove duplicate conversations upgrade from version 4.0.9
val distinct = distinctLocalConversations(context, accountKey, result.map { it.id }.toSet())
.distinct()
.filter { !it.startsWith(details.key.id) || it == details.key.id }
result.forEachIndexed { i, dm ->
addConversationMessage(insertMessages, conversations, details, dm, i, list.size,
false, profileImageSize, updateLastRead)
dm.senderId == details.key.id, profileImageSize, updateLastRead)
}
return DatabaseUpdateData(conversations.values, insertMessages)
return DatabaseUpdateData(conversations.values, insertMessages, distinct)
}
@ -490,6 +499,26 @@ class GetMessagesTask(
}
}
internal fun distinctLocalConversations(context: Context, accountKey: UserKey, messageIds: Set<String>): ArrayList<String> {
val where = Expression.and(Expression.inArgs(Messages.MESSAGE_ID, messageIds.size),
Expression.equalsArgs(Conversations.ACCOUNT_KEY)).sql
val whereArgs = messageIds.toTypedArray() + accountKey.toString()
val result = arrayListOf<String>()
context.contentResolver.queryReference(Messages.CONTENT_URI, Messages.COLUMNS,
where, whereArgs, null)?.use { (cur) ->
val indices = ObjectCursor.indicesFrom(cur, ParcelableMessage::class.java)
cur.moveToFirst()
while (!cur.isAfterLast) {
val conversationId = cur.getString(indices[Messages.CONVERSATION_ID])
result.add(conversationId)
indices.newObject(cur)
cur.moveToNext()
}
}
return result
}
internal fun MutableMap<String, ParcelableMessageConversation>.addLocalConversations(context: Context,
accountKey: UserKey, conversationIds: Set<String>) {
val newIds = conversationIds.filterNot { it in this.keys }

View File

@ -86,6 +86,10 @@
android:id="@id/open_in_browser"
android:icon="@drawable/ic_action_web"
android:title="@string/action_open_in_browser"/>
<item
android:id="@id/copy_url"
android:icon="@drawable/ic_action_copy"
android:title="@android:string/copyUrl"/>
<item
android:id="@+id/add_to_home_screen_submenu"
android:icon="@drawable/ic_action_home"

View File

@ -41,7 +41,6 @@
<!-- Window attributes -->
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="windowActionBarOverlay">true</item>
<item name="actionBarStyle">@style/Widget.Twidere.Viewer.ActionBar</item>