add ktlint plugin to project and apply default code style (#2209)

* add ktlint plugin to project and apply default code style

* some manual adjustments, fix wildcard imports

* update CONTRIBUTING.md

* fix formatting
This commit is contained in:
Konrad Pozniak 2021-06-28 21:13:24 +02:00 committed by GitHub
commit 16ffcca748
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
227 changed files with 3933 additions and 3371 deletions

View file

@ -15,7 +15,11 @@
package com.keylesspalace.tusky.db
import androidx.room.*
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
@Dao
interface AccountDao {
@ -27,5 +31,4 @@ interface AccountDao {
@Query("SELECT * FROM AccountEntity ORDER BY id ASC")
fun loadAll(): List<AccountEntity>
}

View file

@ -21,42 +21,49 @@ import androidx.room.PrimaryKey
import androidx.room.TypeConverters
import com.keylesspalace.tusky.TabData
import com.keylesspalace.tusky.defaultTabs
import com.keylesspalace.tusky.entity.Emoji
import com.keylesspalace.tusky.entity.Status
@Entity(indices = [Index(value = ["domain", "accountId"],
unique = true)])
@Entity(
indices = [
Index(
value = ["domain", "accountId"],
unique = true
)
]
)
@TypeConverters(Converters::class)
data class AccountEntity(@field:PrimaryKey(autoGenerate = true) var id: Long,
val domain: String,
var accessToken: String,
var isActive: Boolean,
var accountId: String = "",
var username: String = "",
var displayName: String = "",
var profilePictureUrl: String = "",
var notificationsEnabled: Boolean = true,
var notificationsMentioned: Boolean = true,
var notificationsFollowed: Boolean = true,
var notificationsFollowRequested: Boolean = false,
var notificationsReblogged: Boolean = true,
var notificationsFavorited: Boolean = true,
var notificationsPolls: Boolean = true,
var notificationsSubscriptions: Boolean = true,
var notificationSound: Boolean = true,
var notificationVibration: Boolean = true,
var notificationLight: Boolean = true,
var defaultPostPrivacy: Status.Visibility = Status.Visibility.PUBLIC,
var defaultMediaSensitivity: Boolean = false,
var alwaysShowSensitiveMedia: Boolean = false,
var alwaysOpenSpoiler: Boolean = false,
var mediaPreviewEnabled: Boolean = true,
var lastNotificationId: String = "0",
var activeNotifications: String = "[]",
var emojis: List<Emoji> = emptyList(),
var tabPreferences: List<TabData> = defaultTabs(),
var notificationsFilter: String = "[\"follow_request\"]") {
data class AccountEntity(
@field:PrimaryKey(autoGenerate = true) var id: Long,
val domain: String,
var accessToken: String,
var isActive: Boolean,
var accountId: String = "",
var username: String = "",
var displayName: String = "",
var profilePictureUrl: String = "",
var notificationsEnabled: Boolean = true,
var notificationsMentioned: Boolean = true,
var notificationsFollowed: Boolean = true,
var notificationsFollowRequested: Boolean = false,
var notificationsReblogged: Boolean = true,
var notificationsFavorited: Boolean = true,
var notificationsPolls: Boolean = true,
var notificationsSubscriptions: Boolean = true,
var notificationSound: Boolean = true,
var notificationVibration: Boolean = true,
var notificationLight: Boolean = true,
var defaultPostPrivacy: Status.Visibility = Status.Visibility.PUBLIC,
var defaultMediaSensitivity: Boolean = false,
var alwaysShowSensitiveMedia: Boolean = false,
var alwaysOpenSpoiler: Boolean = false,
var mediaPreviewEnabled: Boolean = true,
var lastNotificationId: String = "0",
var activeNotifications: String = "[]",
var emojis: List<Emoji> = emptyList(),
var tabPreferences: List<TabData> = defaultTabs(),
var notificationsFilter: String = "[\"follow_request\"]"
) {
val identifier: String
get() = "$domain:$accountId"

View file

@ -18,7 +18,7 @@ package com.keylesspalace.tusky.db
import android.util.Log
import com.keylesspalace.tusky.entity.Account
import com.keylesspalace.tusky.entity.Status
import java.util.*
import java.util.Locale
import javax.inject.Inject
import javax.inject.Singleton
@ -66,7 +66,6 @@ class AccountManager @Inject constructor(db: AppDatabase) {
val maxAccountId = accounts.maxByOrNull { it.id }?.id ?: 0
val newAccountId = maxAccountId + 1
activeAccount = AccountEntity(id = newAccountId, domain = domain.lowercase(Locale.ROOT), accessToken = accessToken, isActive = true)
}
/**
@ -79,7 +78,6 @@ class AccountManager @Inject constructor(db: AppDatabase) {
Log.d(TAG, "saveAccount: saving account with id " + account.id)
accountDao.insertOrReplace(account)
}
}
/**
@ -103,9 +101,7 @@ class AccountManager @Inject constructor(db: AppDatabase) {
activeAccount = null
}
return activeAccount
}
}
/**
@ -129,13 +125,12 @@ class AccountManager @Inject constructor(db: AppDatabase) {
val accountIndex = accounts.indexOf(it)
if (accountIndex != -1) {
//in case the user was already logged in with this account, remove the old information
// in case the user was already logged in with this account, remove the old information
accounts.removeAt(accountIndex)
accounts.add(accountIndex, it)
} else {
accounts.add(it)
}
}
}
@ -194,5 +189,4 @@ class AccountManager @Inject constructor(db: AppDatabase) {
id == accountId
}
}
}
}

View file

@ -35,9 +35,8 @@ interface ConversationsDao {
suspend fun delete(conversation: ConversationEntity): Int
@Query("SELECT * FROM ConversationEntity WHERE accountId = :accountId ORDER BY s_createdAt DESC")
fun conversationsForAccount(accountId: Long) : PagingSource<Int, ConversationEntity>
fun conversationsForAccount(accountId: Long): PagingSource<Int, ConversationEntity>
@Query("DELETE FROM ConversationEntity WHERE accountId = :accountId")
fun deleteForAccount(accountId: Long)
}

View file

@ -25,18 +25,23 @@ import com.google.gson.reflect.TypeToken
import com.keylesspalace.tusky.TabData
import com.keylesspalace.tusky.components.conversation.ConversationAccountEntity
import com.keylesspalace.tusky.createTabDataFromId
import com.keylesspalace.tusky.entity.*
import com.keylesspalace.tusky.entity.Attachment
import com.keylesspalace.tusky.entity.Emoji
import com.keylesspalace.tusky.entity.NewPoll
import com.keylesspalace.tusky.entity.Poll
import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.util.trimTrailingWhitespace
import java.net.URLDecoder
import java.net.URLEncoder
import java.util.*
import java.util.ArrayList
import java.util.Date
import javax.inject.Inject
import javax.inject.Singleton
@ProvidedTypeConverter
@Singleton
class Converters @Inject constructor (
private val gson: Gson
private val gson: Gson
) {
@TypeConverter
@ -62,10 +67,10 @@ class Converters @Inject constructor (
@TypeConverter
fun stringToTabData(str: String?): List<TabData>? {
return str?.split(";")
?.map {
val data = it.split(":")
createTabDataFromId(data[0], data.drop(1).map { s -> URLDecoder.decode(s, "UTF-8") })
}
?.map {
val data = it.split(":")
createTabDataFromId(data[0], data.drop(1).map { s -> URLDecoder.decode(s, "UTF-8") })
}
}
@TypeConverter
@ -126,7 +131,7 @@ class Converters @Inject constructor (
@TypeConverter
fun spannedToString(spanned: Spanned?): String? {
if(spanned == null) {
if (spanned == null) {
return null
}
return spanned.toHtml()
@ -134,7 +139,7 @@ class Converters @Inject constructor (
@TypeConverter
fun stringToSpanned(spannedString: String?): Spanned? {
if(spannedString == null) {
if (spannedString == null) {
return null
}
return spannedString.parseAsHtml().trimTrailingWhitespace()

View file

@ -38,5 +38,4 @@ interface DraftDao {
@Query("SELECT * FROM DraftEntity WHERE id = :id")
suspend fun find(id: Int): DraftEntity?
}

View file

@ -28,24 +28,24 @@ import kotlinx.parcelize.Parcelize
@Entity
@TypeConverters(Converters::class)
data class DraftEntity(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val accountId: Long,
val inReplyToId: String?,
val content: String?,
val contentWarning: String?,
val sensitive: Boolean,
val visibility: Status.Visibility,
val attachments: List<DraftAttachment>,
val poll: NewPoll?,
val failedToSend: Boolean
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val accountId: Long,
val inReplyToId: String?,
val content: String?,
val contentWarning: String?,
val sensitive: Boolean,
val visibility: Status.Visibility,
val attachments: List<DraftAttachment>,
val poll: NewPoll?,
val failedToSend: Boolean
)
@Parcelize
data class DraftAttachment(
val uriString: String,
val description: String?,
val type: Type
): Parcelable {
val uriString: String,
val description: String?,
val type: Type
) : Parcelable {
val uri: Uri
get() = uriString.toUri()

View file

@ -23,10 +23,10 @@ import com.keylesspalace.tusky.entity.Emoji
@Entity
@TypeConverters(Converters::class)
data class InstanceEntity(
@field:PrimaryKey var instance: String,
val emojiList: List<Emoji>?,
val maximumTootCharacters: Int?,
val maxPollOptions: Int?,
val maxPollOptionLength: Int?,
val version: String?
@field:PrimaryKey var instance: String,
val emojiList: List<Emoji>?,
val maximumTootCharacters: Int?,
val maxPollOptions: Int?,
val maxPollOptionLength: Int?,
val version: String?
)

View file

@ -17,11 +17,11 @@ abstract class TimelineDao {
@Insert(onConflict = REPLACE)
abstract fun insertStatus(timelineAccountEntity: TimelineStatusEntity): Long
@Insert(onConflict = IGNORE)
abstract fun insertStatusIfNotThere(timelineAccountEntity: TimelineStatusEntity): Long
@Query("""
@Query(
"""
SELECT s.serverId, s.url, s.timelineUserId,
s.authorServerId, s.inReplyToId, s.inReplyToAccountId, s.createdAt,
s.emojis, s.reblogsCount, s.favouritesCount, s.reblogged, s.favourited, s.bookmarked, s.sensitive,
@ -46,47 +46,62 @@ AND (CASE WHEN :sinceId IS NOT NULL THEN
(LENGTH(s.serverId) > LENGTH(:sinceId) OR LENGTH(s.serverId) == LENGTH(:sinceId) AND s.serverId > :sinceId)
ELSE 1 END)
ORDER BY LENGTH(s.serverId) DESC, s.serverId DESC
LIMIT :limit""")
LIMIT :limit"""
)
abstract fun getStatusesForAccount(account: Long, maxId: String?, sinceId: String?, limit: Int): Single<List<TimelineStatusWithAccount>>
@Transaction
open fun insertInTransaction(status: TimelineStatusEntity, account: TimelineAccountEntity,
reblogAccount: TimelineAccountEntity?) {
open fun insertInTransaction(
status: TimelineStatusEntity,
account: TimelineAccountEntity,
reblogAccount: TimelineAccountEntity?
) {
insertAccount(account)
reblogAccount?.let(this::insertAccount)
insertStatus(status)
}
@Query("""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND
@Query(
"""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND
(LENGTH(serverId) < LENGTH(:maxId) OR LENGTH(serverId) == LENGTH(:maxId) AND serverId < :maxId)
AND
(LENGTH(serverId) > LENGTH(:minId) OR LENGTH(serverId) == LENGTH(:minId) AND serverId > :minId)
""")
"""
)
abstract fun deleteRange(accountId: Long, minId: String, maxId: String)
@Query("""DELETE FROM TimelineStatusEntity WHERE authorServerId = null
@Query(
"""DELETE FROM TimelineStatusEntity WHERE authorServerId = null
AND timelineUserId = :account AND
(LENGTH(serverId) < LENGTH(:maxId) OR LENGTH(serverId) == LENGTH(:maxId) AND serverId < :maxId)
AND
(LENGTH(serverId) > LENGTH(:sinceId) OR LENGTH(serverId) == LENGTH(:sinceId) AND serverId > :sinceId)
""")
"""
)
abstract fun removeAllPlaceholdersBetween(account: Long, maxId: String, sinceId: String)
@Query("""UPDATE TimelineStatusEntity SET favourited = :favourited
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)""")
@Query(
"""UPDATE TimelineStatusEntity SET favourited = :favourited
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
)
abstract fun setFavourited(accountId: Long, statusId: String, favourited: Boolean)
@Query("""UPDATE TimelineStatusEntity SET bookmarked = :bookmarked
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)""")
@Query(
"""UPDATE TimelineStatusEntity SET bookmarked = :bookmarked
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
)
abstract fun setBookmarked(accountId: Long, statusId: String, bookmarked: Boolean)
@Query("""UPDATE TimelineStatusEntity SET reblogged = :reblogged
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)""")
@Query(
"""UPDATE TimelineStatusEntity SET reblogged = :reblogged
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
)
abstract fun setReblogged(accountId: Long, statusId: String, reblogged: Boolean)
@Query("""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND
(authorServerId = :userId OR reblogAccountId = :userId)""")
@Query(
"""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND
(authorServerId = :userId OR reblogAccountId = :userId)"""
)
abstract fun removeAllByUser(accountId: Long, userId: String)
@Query("DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId")
@ -95,14 +110,18 @@ WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId =
@Query("DELETE FROM TimelineAccountEntity WHERE timelineUserId = :accountId")
abstract fun removeAllUsersForAccount(accountId: Long)
@Query("""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId
AND serverId = :statusId""")
@Query(
"""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId
AND serverId = :statusId"""
)
abstract fun delete(accountId: Long, statusId: String)
@Query("""DELETE FROM TimelineStatusEntity WHERE createdAt < :olderThan""")
abstract fun cleanup(olderThan: Long)
@Query("""UPDATE TimelineStatusEntity SET poll = :poll
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)""")
@Query(
"""UPDATE TimelineStatusEntity SET poll = :poll
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
)
abstract fun setVoted(accountId: Long, statusId: String, poll: String)
}
}

View file

@ -1,6 +1,10 @@
package com.keylesspalace.tusky.db
import androidx.room.*
import androidx.room.Embedded
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.TypeConverters
import com.keylesspalace.tusky.entity.Status
/**
@ -15,62 +19,63 @@ import com.keylesspalace.tusky.entity.Status
* fields.
*/
@Entity(
primaryKeys = ["serverId", "timelineUserId"],
foreignKeys = ([
primaryKeys = ["serverId", "timelineUserId"],
foreignKeys = (
[
ForeignKey(
entity = TimelineAccountEntity::class,
parentColumns = ["serverId", "timelineUserId"],
childColumns = ["authorServerId", "timelineUserId"]
entity = TimelineAccountEntity::class,
parentColumns = ["serverId", "timelineUserId"],
childColumns = ["authorServerId", "timelineUserId"]
)
]),
// Avoiding rescanning status table when accounts table changes. Recommended by Room(c).
indices = [Index("authorServerId", "timelineUserId")]
]
),
// Avoiding rescanning status table when accounts table changes. Recommended by Room(c).
indices = [Index("authorServerId", "timelineUserId")]
)
@TypeConverters(Converters::class)
data class TimelineStatusEntity(
val serverId: String, // id never flips: we need it for sorting so it's a real id
val url: String?,
// our local id for the logged in user in case there are multiple accounts per instance
val timelineUserId: Long,
val authorServerId: String?,
val inReplyToId: String?,
val inReplyToAccountId: String?,
val content: String?,
val createdAt: Long,
val emojis: String?,
val reblogsCount: Int,
val favouritesCount: Int,
val reblogged: Boolean,
val bookmarked: Boolean,
val favourited: Boolean,
val sensitive: Boolean,
val spoilerText: String?,
val visibility: Status.Visibility?,
val attachments: String?,
val mentions: String?,
val application: String?,
val reblogServerId: String?, // if it has a reblogged status, it's id is stored here
val reblogAccountId: String?,
val poll: String?,
val muted: Boolean?
val serverId: String, // id never flips: we need it for sorting so it's a real id
val url: String?,
// our local id for the logged in user in case there are multiple accounts per instance
val timelineUserId: Long,
val authorServerId: String?,
val inReplyToId: String?,
val inReplyToAccountId: String?,
val content: String?,
val createdAt: Long,
val emojis: String?,
val reblogsCount: Int,
val favouritesCount: Int,
val reblogged: Boolean,
val bookmarked: Boolean,
val favourited: Boolean,
val sensitive: Boolean,
val spoilerText: String?,
val visibility: Status.Visibility?,
val attachments: String?,
val mentions: String?,
val application: String?,
val reblogServerId: String?, // if it has a reblogged status, it's id is stored here
val reblogAccountId: String?,
val poll: String?,
val muted: Boolean?
)
@Entity(
primaryKeys = ["serverId", "timelineUserId"]
primaryKeys = ["serverId", "timelineUserId"]
)
data class TimelineAccountEntity(
val serverId: String,
val timelineUserId: Long,
val localUsername: String,
val username: String,
val displayName: String,
val url: String,
val avatar: String,
val emojis: String,
val bot: Boolean
val serverId: String,
val timelineUserId: Long,
val localUsername: String,
val username: String,
val displayName: String,
val url: String,
val avatar: String,
val emojis: String,
val bot: Boolean
)
class TimelineStatusWithAccount {
@Embedded
lateinit var status: TimelineStatusEntity
@ -78,4 +83,4 @@ class TimelineStatusWithAccount {
lateinit var account: TimelineAccountEntity
@Embedded(prefix = "rb_")
var reblogAccount: TimelineAccountEntity? = null
}
}