upgrade ktlint plugin to 12.0.3 (#4169)
There are some new rules, I think they mostly make sense, except for the max line length which I had to disable because we are over it in a lot of places. --------- Co-authored-by: Goooler <wangzongler@gmail.com>
This commit is contained in:
parent
33cd6fdb98
commit
5192fb08a5
215 changed files with 2813 additions and 1177 deletions
|
|
@ -38,8 +38,10 @@ data class AccountEntity(
|
|||
@field:PrimaryKey(autoGenerate = true) var id: Long,
|
||||
val domain: String,
|
||||
var accessToken: String,
|
||||
var clientId: String?, // nullable for backward compatibility
|
||||
var clientSecret: String?, // nullable for backward compatibility
|
||||
// nullable for backward compatibility
|
||||
var clientId: String?,
|
||||
// nullable for backward compatibility
|
||||
var clientSecret: String?,
|
||||
var isActive: Boolean,
|
||||
var accountId: String = "",
|
||||
var username: String = "",
|
||||
|
|
@ -111,7 +113,7 @@ data class AccountEntity(
|
|||
|
||||
var isShowHomeBoosts: Boolean = true,
|
||||
var isShowHomeReplies: Boolean = true,
|
||||
var isShowHomeSelfBoosts: Boolean = true,
|
||||
var isShowHomeSelfBoosts: Boolean = true
|
||||
) {
|
||||
|
||||
val identifier: String
|
||||
|
|
|
|||
|
|
@ -236,7 +236,10 @@ class AccountManager @Inject constructor(db: AppDatabase) {
|
|||
*/
|
||||
fun shouldDisplaySelfUsername(context: Context): Boolean {
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val showUsernamePreference = sharedPreferences.getString(PrefKeys.SHOW_SELF_USERNAME, "disambiguate")
|
||||
val showUsernamePreference = sharedPreferences.getString(
|
||||
PrefKeys.SHOW_SELF_USERNAME,
|
||||
"disambiguate"
|
||||
)
|
||||
if (showUsernamePreference == "always") {
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,14 +66,19 @@ class Converters @Inject constructor(
|
|||
return str?.split(";")
|
||||
?.map {
|
||||
val data = it.split(":")
|
||||
createTabDataFromId(data[0], data.drop(1).map { s -> URLDecoder.decode(s, "UTF-8") })
|
||||
createTabDataFromId(
|
||||
data[0],
|
||||
data.drop(1).map { s -> URLDecoder.decode(s, "UTF-8") }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun tabDataToString(tabData: List<TabData>?): String? {
|
||||
// List name may include ":"
|
||||
return tabData?.joinToString(";") { it.id + ":" + it.arguments.joinToString(":") { s -> URLEncoder.encode(s, "UTF-8") } }
|
||||
return tabData?.joinToString(";") {
|
||||
it.id + ":" + it.arguments.joinToString(":") { s -> URLEncoder.encode(s, "UTF-8") }
|
||||
}
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
|
|
@ -93,7 +98,10 @@ class Converters @Inject constructor(
|
|||
|
||||
@TypeConverter
|
||||
fun jsonToAccountList(accountListJson: String?): List<ConversationAccountEntity>? {
|
||||
return gson.fromJson(accountListJson, object : TypeToken<List<ConversationAccountEntity>>() {}.type)
|
||||
return gson.fromJson(
|
||||
accountListJson,
|
||||
object : TypeToken<List<ConversationAccountEntity>>() {}.type
|
||||
)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
|
|
@ -163,7 +171,10 @@ class Converters @Inject constructor(
|
|||
|
||||
@TypeConverter
|
||||
fun jsonToDraftAttachmentList(draftAttachmentListJson: String?): List<DraftAttachment>? {
|
||||
return gson.fromJson(draftAttachmentListJson, object : TypeToken<List<DraftAttachment>>() {}.type)
|
||||
return gson.fromJson(
|
||||
draftAttachmentListJson,
|
||||
object : TypeToken<List<DraftAttachment>>() {}.type
|
||||
)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
|
|
|
|||
|
|
@ -34,7 +34,9 @@ interface DraftDao {
|
|||
@Query("SELECT COUNT(*) FROM DraftEntity WHERE accountId = :accountId AND failedToSendNew = 1")
|
||||
fun draftsNeedUserAlert(accountId: Long): LiveData<Int>
|
||||
|
||||
@Query("UPDATE DraftEntity SET failedToSendNew = 0 WHERE accountId = :accountId AND failedToSendNew = 1")
|
||||
@Query(
|
||||
"UPDATE DraftEntity SET failedToSendNew = 0 WHERE accountId = :accountId AND failedToSendNew = 1"
|
||||
)
|
||||
suspend fun draftsClearNeedUserAlert(accountId: Long)
|
||||
|
||||
@Query("SELECT * FROM DraftEntity WHERE accountId = :accountId")
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ data class DraftAttachment(
|
|||
get() = uriString.toUri()
|
||||
|
||||
enum class Type {
|
||||
IMAGE, VIDEO, AUDIO;
|
||||
IMAGE,
|
||||
VIDEO,
|
||||
AUDIO
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,99 +1,99 @@
|
|||
/* Copyright 2023 Andi McClure
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Tusky 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 Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky.db
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.lifecycle.LifecycleCoroutineScope
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.components.drafts.DraftsActivity
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* This class manages an alert popup when a post has failed and been saved to drafts.
|
||||
* It must be separately registered in each lifetime in which it is to appear,
|
||||
* and it only appears if the post failure belongs to the current user.
|
||||
*/
|
||||
|
||||
private const val TAG = "DraftsAlert"
|
||||
|
||||
@Singleton
|
||||
class DraftsAlert @Inject constructor(db: AppDatabase) {
|
||||
// For tracking when a media upload fails in the service
|
||||
private val draftDao: DraftDao = db.draftDao()
|
||||
|
||||
@Inject
|
||||
lateinit var accountManager: AccountManager
|
||||
|
||||
fun <T> observeInContext(context: T, showAlert: Boolean) where T : Context, T : LifecycleOwner {
|
||||
accountManager.activeAccount?.let { activeAccount ->
|
||||
val coroutineScope = context.lifecycleScope
|
||||
|
||||
// Assume a single MainActivity, AccountActivity or DraftsActivity never sees more then one user id in its lifetime.
|
||||
val activeAccountId = activeAccount.id
|
||||
|
||||
// This LiveData will be automatically disposed when the activity is destroyed.
|
||||
val draftsNeedUserAlert = draftDao.draftsNeedUserAlert(activeAccountId)
|
||||
|
||||
// observe ensures that this gets called at the most appropriate moment wrt the context lifecycle—
|
||||
// at init, at next onResume, or immediately if the context is resumed already.
|
||||
if (showAlert) {
|
||||
draftsNeedUserAlert.observe(context) { count ->
|
||||
Log.d(TAG, "User id $activeAccountId changed: Notification-worthy draft count $count")
|
||||
if (count > 0) {
|
||||
AlertDialog.Builder(context)
|
||||
.setTitle(R.string.action_post_failed)
|
||||
.setMessage(
|
||||
context.resources.getQuantityString(R.plurals.action_post_failed_detail, count)
|
||||
)
|
||||
.setPositiveButton(R.string.action_post_failed_show_drafts) { _: DialogInterface?, _: Int ->
|
||||
clearDraftsAlert(coroutineScope, activeAccountId) // User looked at drafts
|
||||
|
||||
val intent = DraftsActivity.newIntent(context)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
.setNegativeButton(R.string.action_post_failed_do_nothing) { _: DialogInterface?, _: Int ->
|
||||
clearDraftsAlert(coroutineScope, activeAccountId) // User doesn't care
|
||||
}
|
||||
.show()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
draftsNeedUserAlert.observe(context) {
|
||||
Log.d(TAG, "User id $activeAccountId: Clean out notification-worthy drafts")
|
||||
clearDraftsAlert(coroutineScope, activeAccountId)
|
||||
}
|
||||
}
|
||||
} ?: run {
|
||||
Log.w(TAG, "Attempted to observe drafts, but there is no active account")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear drafts alert for specified user
|
||||
*/
|
||||
private fun clearDraftsAlert(coroutineScope: LifecycleCoroutineScope, id: Long) {
|
||||
coroutineScope.launch {
|
||||
draftDao.draftsClearNeedUserAlert(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Copyright 2023 Andi McClure
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Tusky 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 Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky.db
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.lifecycle.LifecycleCoroutineScope
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.components.drafts.DraftsActivity
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* This class manages an alert popup when a post has failed and been saved to drafts.
|
||||
* It must be separately registered in each lifetime in which it is to appear,
|
||||
* and it only appears if the post failure belongs to the current user.
|
||||
*/
|
||||
|
||||
private const val TAG = "DraftsAlert"
|
||||
|
||||
@Singleton
|
||||
class DraftsAlert @Inject constructor(db: AppDatabase) {
|
||||
// For tracking when a media upload fails in the service
|
||||
private val draftDao: DraftDao = db.draftDao()
|
||||
|
||||
@Inject
|
||||
lateinit var accountManager: AccountManager
|
||||
|
||||
fun <T> observeInContext(context: T, showAlert: Boolean) where T : Context, T : LifecycleOwner {
|
||||
accountManager.activeAccount?.let { activeAccount ->
|
||||
val coroutineScope = context.lifecycleScope
|
||||
|
||||
// Assume a single MainActivity, AccountActivity or DraftsActivity never sees more then one user id in its lifetime.
|
||||
val activeAccountId = activeAccount.id
|
||||
|
||||
// This LiveData will be automatically disposed when the activity is destroyed.
|
||||
val draftsNeedUserAlert = draftDao.draftsNeedUserAlert(activeAccountId)
|
||||
|
||||
// observe ensures that this gets called at the most appropriate moment wrt the context lifecycle—
|
||||
// at init, at next onResume, or immediately if the context is resumed already.
|
||||
if (showAlert) {
|
||||
draftsNeedUserAlert.observe(context) { count ->
|
||||
Log.d(TAG, "User id $activeAccountId changed: Notification-worthy draft count $count")
|
||||
if (count > 0) {
|
||||
AlertDialog.Builder(context)
|
||||
.setTitle(R.string.action_post_failed)
|
||||
.setMessage(
|
||||
context.resources.getQuantityString(R.plurals.action_post_failed_detail, count)
|
||||
)
|
||||
.setPositiveButton(R.string.action_post_failed_show_drafts) { _: DialogInterface?, _: Int ->
|
||||
clearDraftsAlert(coroutineScope, activeAccountId) // User looked at drafts
|
||||
|
||||
val intent = DraftsActivity.newIntent(context)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
.setNegativeButton(R.string.action_post_failed_do_nothing) { _: DialogInterface?, _: Int ->
|
||||
clearDraftsAlert(coroutineScope, activeAccountId) // User doesn't care
|
||||
}
|
||||
.show()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
draftsNeedUserAlert.observe(context) {
|
||||
Log.d(TAG, "User id $activeAccountId: Clean out notification-worthy drafts")
|
||||
clearDraftsAlert(coroutineScope, activeAccountId)
|
||||
}
|
||||
}
|
||||
} ?: run {
|
||||
Log.w(TAG, "Attempted to observe drafts, but there is no active account")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear drafts alert for specified user
|
||||
*/
|
||||
private fun clearDraftsAlert(coroutineScope: LifecycleCoroutineScope, id: Long) {
|
||||
coroutineScope.launch {
|
||||
draftDao.draftsClearNeedUserAlert(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -255,13 +255,21 @@ WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId =
|
|||
"""UPDATE TimelineStatusEntity SET contentShowing = :contentShowing
|
||||
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
||||
)
|
||||
abstract suspend fun setContentShowing(accountId: Long, statusId: String, contentShowing: Boolean)
|
||||
abstract suspend fun setContentShowing(
|
||||
accountId: Long,
|
||||
statusId: String,
|
||||
contentShowing: Boolean
|
||||
)
|
||||
|
||||
@Query(
|
||||
"""UPDATE TimelineStatusEntity SET contentCollapsed = :contentCollapsed
|
||||
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
||||
)
|
||||
abstract suspend fun setContentCollapsed(accountId: Long, statusId: String, contentCollapsed: Boolean)
|
||||
abstract suspend fun setContentCollapsed(
|
||||
accountId: Long,
|
||||
statusId: String,
|
||||
contentCollapsed: Boolean
|
||||
)
|
||||
|
||||
@Query(
|
||||
"""UPDATE TimelineStatusEntity SET pinned = :pinned
|
||||
|
|
@ -278,39 +286,53 @@ AND timelineUserId = :accountId
|
|||
)
|
||||
abstract suspend fun deleteAllFromInstance(accountId: Long, instanceDomain: String)
|
||||
|
||||
@Query("UPDATE TimelineStatusEntity SET filtered = NULL WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)")
|
||||
@Query(
|
||||
"UPDATE TimelineStatusEntity SET filtered = NULL WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"
|
||||
)
|
||||
abstract suspend fun clearWarning(accountId: Long, statusId: String): Int
|
||||
|
||||
@Query("SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId ORDER BY LENGTH(serverId) DESC, serverId DESC LIMIT 1")
|
||||
@Query(
|
||||
"SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId ORDER BY LENGTH(serverId) DESC, serverId DESC LIMIT 1"
|
||||
)
|
||||
abstract suspend fun getTopId(accountId: Long): String?
|
||||
|
||||
@Query("SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND authorServerId IS NULL ORDER BY LENGTH(serverId) DESC, serverId DESC LIMIT 1")
|
||||
@Query(
|
||||
"SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND authorServerId IS NULL ORDER BY LENGTH(serverId) DESC, serverId DESC LIMIT 1"
|
||||
)
|
||||
abstract suspend fun getTopPlaceholderId(accountId: Long): String?
|
||||
|
||||
/**
|
||||
* Returns the id directly above [serverId], or null if [serverId] is the id of the top status
|
||||
*/
|
||||
@Query("SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND (LENGTH(:serverId) < LENGTH(serverId) OR (LENGTH(:serverId) = LENGTH(serverId) AND :serverId < serverId)) ORDER BY LENGTH(serverId) ASC, serverId ASC LIMIT 1")
|
||||
@Query(
|
||||
"SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND (LENGTH(:serverId) < LENGTH(serverId) OR (LENGTH(:serverId) = LENGTH(serverId) AND :serverId < serverId)) ORDER BY LENGTH(serverId) ASC, serverId ASC LIMIT 1"
|
||||
)
|
||||
abstract suspend fun getIdAbove(accountId: Long, serverId: String): String?
|
||||
|
||||
/**
|
||||
* Returns the ID directly below [serverId], or null if [serverId] is the ID of the bottom
|
||||
* status
|
||||
*/
|
||||
@Query("SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND (LENGTH(:serverId) > LENGTH(serverId) OR (LENGTH(:serverId) = LENGTH(serverId) AND :serverId > serverId)) ORDER BY LENGTH(serverId) DESC, serverId DESC LIMIT 1")
|
||||
@Query(
|
||||
"SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND (LENGTH(:serverId) > LENGTH(serverId) OR (LENGTH(:serverId) = LENGTH(serverId) AND :serverId > serverId)) ORDER BY LENGTH(serverId) DESC, serverId DESC LIMIT 1"
|
||||
)
|
||||
abstract suspend fun getIdBelow(accountId: Long, serverId: String): String?
|
||||
|
||||
/**
|
||||
* Returns the id of the next placeholder after [serverId]
|
||||
*/
|
||||
@Query("SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND authorServerId IS NULL AND (LENGTH(:serverId) > LENGTH(serverId) OR (LENGTH(:serverId) = LENGTH(serverId) AND :serverId > serverId)) ORDER BY LENGTH(serverId) DESC, serverId DESC LIMIT 1")
|
||||
@Query(
|
||||
"SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND authorServerId IS NULL AND (LENGTH(:serverId) > LENGTH(serverId) OR (LENGTH(:serverId) = LENGTH(serverId) AND :serverId > serverId)) ORDER BY LENGTH(serverId) DESC, serverId DESC LIMIT 1"
|
||||
)
|
||||
abstract suspend fun getNextPlaceholderIdAfter(accountId: Long, serverId: String): String?
|
||||
|
||||
@Query("SELECT COUNT(*) FROM TimelineStatusEntity WHERE timelineUserId = :accountId")
|
||||
abstract suspend fun getStatusCount(accountId: Long): Int
|
||||
|
||||
/** Developer tools: Find N most recent status IDs */
|
||||
@Query("SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId ORDER BY LENGTH(serverId) DESC, serverId DESC LIMIT :count")
|
||||
@Query(
|
||||
"SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId ORDER BY LENGTH(serverId) DESC, serverId DESC LIMIT :count"
|
||||
)
|
||||
abstract suspend fun getMostRecentNStatusIds(accountId: Long, count: Int): List<String>
|
||||
|
||||
/** Developer tools: Convert a status to a placeholder */
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ import com.keylesspalace.tusky.entity.Status
|
|||
)
|
||||
@TypeConverters(Converters::class)
|
||||
data class TimelineStatusEntity(
|
||||
val serverId: String, // id never flips: we need it for sorting so it's a real id
|
||||
// id never flips: we need it for sorting so it's a real id
|
||||
val serverId: String,
|
||||
val url: String?,
|
||||
// our local id for the logged in user in case there are multiple accounts per instance
|
||||
val timelineUserId: Long,
|
||||
|
|
@ -74,7 +75,8 @@ data class TimelineStatusEntity(
|
|||
val mentions: String?,
|
||||
val tags: String?,
|
||||
val application: String?,
|
||||
val reblogServerId: String?, // if it has a reblogged status, it's id is stored here
|
||||
// if it has a reblogged status, it's id is stored here
|
||||
val reblogServerId: String?,
|
||||
val reblogAccountId: String?,
|
||||
val poll: String?,
|
||||
val muted: Boolean?,
|
||||
|
|
@ -109,8 +111,10 @@ data class TimelineAccountEntity(
|
|||
data class TimelineStatusWithAccount(
|
||||
@Embedded
|
||||
val status: TimelineStatusEntity,
|
||||
// null when placeholder
|
||||
@Embedded(prefix = "a_")
|
||||
val account: TimelineAccountEntity? = null, // null when placeholder
|
||||
val account: TimelineAccountEntity? = null,
|
||||
// null when no reblog
|
||||
@Embedded(prefix = "rb_")
|
||||
val reblogAccount: TimelineAccountEntity? = null // null when no reblog
|
||||
val reblogAccount: TimelineAccountEntity? = null
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue