chore(deps): update plugin ktlint to v12.1.0 (#358)

This commit is contained in:
Nik Clayton 2024-01-09 17:50:20 +01:00 committed by GitHub
parent d8be70a465
commit 993b74691a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 218 additions and 107 deletions

View File

@ -24,11 +24,11 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.create
import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
@Module
@ -37,7 +37,7 @@ object UpdateCheckModule {
@Singleton
fun providesFdroidService(
httpClient: OkHttpClient,
gson: Gson
gson: Gson,
): FdroidService = Retrofit.Builder()
.baseUrl("https://f-droid.org")
.client(httpClient)

View File

@ -25,19 +25,19 @@ import retrofit2.http.Path
@Keep
data class FdroidPackageVersion(
val versionName: String,
val versionCode: Int
val versionCode: Int,
)
@Keep
data class FdroidPackage(
val packageName: String,
val suggestedVersionCode: Int,
val packages: List<FdroidPackageVersion>
val packages: List<FdroidPackageVersion>,
)
interface FdroidService {
@GET("/api/v1/packages/{package}")
suspend fun getPackage(
@Path("package") pkg: String
@Path("package") pkg: String,
): NetworkResult<FdroidPackage>
}

View File

@ -27,7 +27,7 @@ import javax.inject.Singleton
@Singleton
class UpdateCheck @Inject constructor(
sharedPreferencesRepository: SharedPreferencesRepository,
private val fdroidService: FdroidService
private val fdroidService: FdroidService,
) : UpdateCheckBase(sharedPreferencesRepository) {
override val updateIntent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("market://details?id=${BuildConfig.APPLICATION_ID}")

View File

@ -24,11 +24,11 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.create
import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
@Module
@ -37,7 +37,7 @@ object UpdateCheckModule {
@Singleton
fun providesGitHubService(
httpClient: OkHttpClient,
gson: Gson
gson: Gson,
): GitHubService = Retrofit.Builder()
.baseUrl("https://api.github.com")
.client(httpClient)

View File

@ -29,20 +29,20 @@ data class GitHubReleaseAsset(
val name: String,
/** MIME content type for the asset, e.g., "application/vnd.android.package-archive" */
@SerializedName("content_type") val contentType: String
@SerializedName("content_type") val contentType: String,
)
@Keep
data class GitHubRelease(
/** URL for the release's web page */
@SerializedName("html_url") val htmlUrl: String,
val assets: List<GitHubReleaseAsset>
val assets: List<GitHubReleaseAsset>,
)
interface GitHubService {
@GET("/repos/{owner}/{repo}/releases/latest")
suspend fun getLatestRelease(
@Path("owner") owner: String,
@Path("repo") repo: String
@Path("repo") repo: String,
): NetworkResult<GitHubRelease>
}

View File

@ -24,7 +24,7 @@ import javax.inject.Inject
class UpdateCheck @Inject constructor(
sharedPreferencesRepository: SharedPreferencesRepository,
private val gitHubService: GitHubService
private val gitHubService: GitHubService,
) : UpdateCheckBase(sharedPreferencesRepository) {
private val versionCodeExtractor = """(\d+)\.apk""".toRegex()

View File

@ -33,6 +33,6 @@ object UpdateCheckModule {
@Provides
@Singleton
fun providesAppUpdateManager(
@ApplicationContext context: Context
@ApplicationContext context: Context,
): AppUpdateManager = AppUpdateManagerFactory.create(context)
}

View File

@ -22,16 +22,17 @@ import android.net.Uri
import app.pachli.BuildConfig
import app.pachli.core.preferences.SharedPreferencesRepository
import com.google.android.play.core.appupdate.AppUpdateManager
import kotlinx.coroutines.suspendCancellableCoroutine
import javax.inject.Inject
import kotlinx.coroutines.suspendCancellableCoroutine
class UpdateCheck @Inject constructor(
sharedPreferencesRepository: SharedPreferencesRepository,
private val appUpdateManager: AppUpdateManager
private val appUpdateManager: AppUpdateManager,
) : UpdateCheckBase(sharedPreferencesRepository) {
override val updateIntent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse(
"https://play.google.com/store/apps/details?id=${BuildConfig.APPLICATION_ID}")
"https://play.google.com/store/apps/details?id=${BuildConfig.APPLICATION_ID}",
)
setPackage("com.android.vending")
}

View File

@ -27,14 +27,14 @@ import app.pachli.core.network.model.Status
import app.pachli.core.network.retrofit.InstanceSwitchAuthInterceptor
import app.pachli.core.preferences.PrefKeys
import app.pachli.core.preferences.SharedPreferencesRepository
import java.util.Locale
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import timber.log.Timber
import java.util.Locale
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AccountManager @Inject constructor(
@ -54,7 +54,7 @@ class AccountManager @Inject constructor(
instanceSwitchAuthInterceptor.credentials = value?.let {
InstanceSwitchAuthInterceptor.Credentials(
accessToken = it.accessToken,
domain = it.domain
domain = it.domain,
)
}
externalScope.launch { _activeAccountFlow.emit(value) }

View File

@ -21,10 +21,10 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Qualifier
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import javax.inject.Qualifier
/**
* Scope for potentially long-running tasks that should outlive the viewmodel that

View File

@ -17,14 +17,14 @@
package app.pachli.core.common.util
import org.junit.AfterClass
import org.junit.Assert.assertEquals
import org.junit.BeforeClass
import org.junit.Test
import java.time.Instant
import java.util.Date
import java.util.Locale
import java.util.TimeZone
import org.junit.AfterClass
import org.junit.Assert.assertEquals
import org.junit.BeforeClass
import org.junit.Test
class AbsoluteTimeFormatterTest {
companion object {

View File

@ -17,14 +17,14 @@
package app.pachli.core.common.util
import java.util.Locale
import kotlin.math.pow
import org.junit.AfterClass
import org.junit.Assert
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import java.util.Locale
import kotlin.math.pow
@RunWith(Parameterized::class)
class NumberUtilsTest(private val input: Long, private val want: String) {

View File

@ -69,7 +69,8 @@ class Converters @Inject constructor(
return str?.split(";")
?.map {
val data = it.split(":")
TabData.from(data[0], data.drop(1).map { s -> URLDecoder.decode(s, "UTF-8") }) }
TabData.from(data[0], data.drop(1).map { s -> URLDecoder.decode(s, "UTF-8") })
}
}
@TypeConverter

View File

@ -269,8 +269,14 @@ WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId =
WHERE timelineUserId = :accountId
AND serverId IN (:serverIds)""",
)
abstract suspend fun getStatusViewData(accountId: Long, serverIds: List<String>):
Map<@MapColumn(columnName = "serverId") String, StatusViewDataEntity>
abstract suspend fun getStatusViewData(
accountId: Long,
serverIds: List<String>,
): Map<
@MapColumn(columnName = "serverId")
String,
StatusViewDataEntity,
>
@Query(
"""UPDATE TimelineStatusEntity SET pinned = :pinned

View File

@ -37,6 +37,12 @@ interface TranslatedStatusDao {
WHERE timelineUserId = :accountId
AND serverId IN (:serverIds)""",
)
suspend fun getTranslations(accountId: Long, serverIds: List<String>):
Map<@MapColumn(columnName = "serverId") String, TranslatedStatusEntity>
suspend fun getTranslations(
accountId: Long,
serverIds: List<String>,
): Map<
@MapColumn(columnName = "serverId")
String,
TranslatedStatusEntity,
>
}

View File

@ -39,8 +39,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 = "",

View File

@ -65,6 +65,8 @@ data class DraftAttachment(
get() = uriString.toUri()
enum class Type {
IMAGE, VIDEO, AUDIO;
IMAGE,
VIDEO,
AUDIO,
}
}

View File

@ -33,7 +33,7 @@ enum class TabKind(val repr: String) {
TRENDING_STATUSES("Trending_Statuses"),
HASHTAG("Hashtag"),
LIST("List"),
BOOKMARKS("Bookmarks")
BOOKMARKS("Bookmarks"),
}
/** this would be a good case for a sealed class, but that does not work nice with Room */
@ -46,7 +46,7 @@ data class TabData(val kind: TabKind, val arguments: List<String> = emptyList())
fun from(kind: String, arguments: List<String> = emptyList()): TabData {
// Work around for https://github.com/pachli/pachli-android/issues/329,
// as the Trending... kinds may have been serialised without the `_`
return when(kind) {
return when (kind) {
"TrendingTags" -> TabData(TabKind.TRENDING_TAGS, arguments)
"TrendingLinks" -> TabData(TabKind.TRENDING_LINKS, arguments)
"TrendingStatuses" -> TabData(TabKind.TRENDING_STATUSES, arguments)
@ -60,5 +60,5 @@ fun defaultTabs() = listOf(
TabData.from(TabKind.HOME),
TabData.from(TabKind.NOTIFICATIONS),
TabData.from(TabKind.LOCAL),
TabData.from(TabKind.DIRECT)
TabData.from(TabKind.DIRECT),
)

View File

@ -64,7 +64,8 @@ import java.util.Date
)
@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,
@ -88,7 +89,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?,
@ -222,8 +224,9 @@ data class TimelineStatusWithAccount(
val status: TimelineStatusEntity,
@Embedded(prefix = "a_")
val account: TimelineAccountEntity,
// null when no reblog
@Embedded(prefix = "rb_")
val reblogAccount: TimelineAccountEntity? = null, // null when no reblog
val reblogAccount: TimelineAccountEntity? = null,
@Embedded(prefix = "svd_")
val viewData: StatusViewDataEntity? = null,
@Embedded(prefix = "t_")
@ -286,13 +289,15 @@ data class TimelineStatusWithAccount(
return if (reblog != null) {
Status(
id = status.serverId,
url = null, // no url for reblogs
// no url for reblogs
url = null,
account = reblogAccount!!.toTimelineAccount(gson),
inReplyToId = null,
inReplyToAccountId = null,
reblog = reblog,
content = "",
createdAt = Date(status.createdAt), // lie but whatever?
// lie but whatever?
createdAt = Date(status.createdAt),
editedAt = null,
emojis = listOf(),
reblogsCount = 0,

View File

@ -44,26 +44,26 @@ data class TranslatedStatusEntity(
/** The translated text of the status (HTML), equivalent to [Status.content] */
val content: String,
// Not documented, see https://github.com/mastodon/documentation/issues/1248
/**
* The translated spoiler text of the status (text), if it exists, equivalent to
* [app.pachli.core.network.model.Status.spoilerText]
*/
// Not documented, see https://github.com/mastodon/documentation/issues/1248
val spoilerText: String,
// Not documented, see https://github.com/mastodon/documentation/issues/1248
/**
* The translated poll (if it exists). Does not contain all the poll data, only the
* translated text. Vote counts and other metadata has to be determined from the original
* poll object.
*/
// Not documented, see https://github.com/mastodon/documentation/issues/1248
val poll: TranslatedPoll?,
// Not documented, see https://github.com/mastodon/documentation/issues/1248
/**
* Translated descriptions for media attachments, if any were attached. Other metadata has
* to be determined from the original attachment.
*/
// Not documented, see https://github.com/mastodon/documentation/issues/1248
val attachments: List<TranslatedAttachment>,
/** The service that provided the machine translation */

View File

@ -26,13 +26,13 @@ import app.pachli.core.database.model.TimelineStatusWithAccount
import app.pachli.core.network.model.Status
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import javax.inject.Inject
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import javax.inject.Inject
@HiltAndroidTest
@RunWith(AndroidJUnit4::class)

View File

@ -288,8 +288,10 @@ class ReportActivityIntent(context: Context, accountId: String, userName: String
/** @return the `accountId` passed to this intent */
fun getAccountId(intent: Intent) = intent.getStringExtra(EXTRA_ACCOUNT_ID)!!
/** @return the `userName` passed to this intent */
fun getAccountUserName(intent: Intent) = intent.getStringExtra(EXTRA_ACCOUNT_USERNAME)!!
/** @return the `statusId` passed to this intent, or null */
fun getStatusId(intent: Intent) = intent.getStringExtra(EXTRA_STATUS_ID)
}
@ -298,7 +300,7 @@ class ReportActivityIntent(context: Context, accountId: String, userName: String
/**
* Use one of [bookmarks], [favourites], [hashtag], or [list] to construct.
*/
class StatusListActivityIntent private constructor (context: Context) : Intent() {
class StatusListActivityIntent private constructor(context: Context) : Intent() {
init {
setClassName(context, "app.pachli${QuadrantConstants.STATUS_LIST_ACTIVITY}")
}
@ -412,71 +414,104 @@ class ViewThreadActivityIntent(context: Context, statusId: String, statusUrl: St
/** @return the `statusId` passed to this intent */
fun getStatusId(intent: Intent) = intent.getStringExtra(EXTRA_STATUS_ID)!!
/** @return the `statusUrl` passed to this intent, or null */
fun getUrl(intent: Intent) = intent.getStringExtra(EXTRA_STATUS_URL)
}
}
class AboutActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.ABOUT_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.ABOUT_ACTIVITY}")
}
}
class AnnouncementsActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.ANNOUNCEMENTS_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.ANNOUNCEMENTS_ACTIVITY}")
}
}
class DraftsActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.DRAFTS_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.DRAFTS_ACTIVITY}")
}
}
class EditProfileActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.EDIT_PROFILE_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.EDIT_PROFILE_ACTIVITY}")
}
}
class FiltersActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.FILTERS_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.FILTERS_ACTIVITY}")
}
}
class FollowedTagsActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.FOLLOWED_TAGS_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.FOLLOWED_TAGS_ACTIVITY}")
}
}
class InstanceListActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.INSTANCE_LIST_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.INSTANCE_LIST_ACTIVITY}")
}
}
class LicenseActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.LICENSE_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.LICENSE_ACTIVITY}")
}
}
class ListActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.LISTS_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.LISTS_ACTIVITY}")
}
}
class LoginWebViewActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.LOGIN_WEB_VIEW_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.LOGIN_WEB_VIEW_ACTIVITY}")
}
}
class MainActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.MAIN_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.MAIN_ACTIVITY}")
}
}
class PrivacyPolicyActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.PRIVACY_POLICY_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.PRIVACY_POLICY_ACTIVITY}")
}
}
class ScheduledStatusActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.SCHEDULED_STATUS_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.SCHEDULED_STATUS_ACTIVITY}")
}
}
class SearchActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.SEARCH_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.SEARCH_ACTIVITY}")
}
}
class TabPreferenceActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.TAB_PREFERENCE_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.TAB_PREFERENCE_ACTIVITY}")
}
}
class TrendingActivityIntent(context: Context) : Intent() {
init { setClassName(context, "app.pachli${QuadrantConstants.TRENDING_ACTIVITY}") }
init {
setClassName(context, "app.pachli${QuadrantConstants.TRENDING_ACTIVITY}")
}
}

View File

@ -22,9 +22,9 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
import retrofit2.Retrofit
import retrofit2.create
import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
@Module

View File

@ -39,6 +39,12 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import java.net.IDN
import java.net.InetSocketAddress
import java.net.Proxy
import java.util.Date
import java.util.concurrent.TimeUnit
import javax.inject.Singleton
import okhttp3.Cache
import okhttp3.OkHttp
import okhttp3.OkHttpClient
@ -47,12 +53,6 @@ import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.create
import timber.log.Timber
import java.net.IDN
import java.net.InetSocketAddress
import java.net.Proxy
import java.util.Date
import java.util.concurrent.TimeUnit
import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
@Module

View File

@ -99,19 +99,40 @@ internal fun String.parseIsoDate(): Date {
var offset = 0
// extract year
val year = parseInt(this, offset, 4.let { offset += it; offset })
val year = parseInt(
this,
offset,
4.let {
offset += it
offset
},
)
if (checkOffset(this, offset, '-')) {
offset += 1
}
// extract month
val month = parseInt(this, offset, 2.let { offset += it; offset })
val month = parseInt(
this,
offset,
2.let {
offset += it
offset
},
)
if (checkOffset(this, offset, '-')) {
offset += 1
}
// extract day
val day = parseInt(this, offset, 2.let { offset += it; offset })
val day = parseInt(
this,
offset,
2.let {
offset += it
offset
},
)
// default time value
var hour = 0
var minutes = 0
@ -126,11 +147,27 @@ internal fun String.parseIsoDate(): Date {
}
if (hasT) {
// extract hours, minutes, seconds and milliseconds
hour = parseInt(this, 1.let { offset += it; offset }, 2.let { offset += it; offset })
hour = parseInt(
this,
1.let {
offset += it
offset
},
2.let {
offset += it
offset
},
)
if (checkOffset(this, offset, ':')) {
offset += 1
}
minutes = parseInt(this, offset, 2.let { offset += it; offset })
minutes = parseInt(
this, offset,
2.let {
offset += it
offset
},
)
if (checkOffset(this, offset, ':')) {
offset += 1
}
@ -138,7 +175,13 @@ internal fun String.parseIsoDate(): Date {
if (this.length > offset) {
val c = this[offset]
if (c != 'Z' && c != '+' && c != '-') {
seconds = parseInt(this, offset, 2.let { offset += it; offset })
seconds = parseInt(
this, offset,
2.let {
offset += it
offset
},
)
if (seconds in 60..62) seconds = 59 // truncate up to 3 leap seconds
// milliseconds can be optional in the format
if (checkOffset(this, offset, '.')) {

View File

@ -21,9 +21,9 @@ import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter
import timber.log.Timber
import java.io.IOException
import java.util.Date
import timber.log.Timber
class Rfc3339DateJsonAdapter : TypeAdapter<Date?>() {

View File

@ -23,8 +23,10 @@ data class Account(
val id: String,
@SerializedName("username") val localUsername: String,
@SerializedName("acct") val username: String,
@SerializedName("display_name") val displayName: String?, // should never be null per API definition, but some servers break the contract
@SerializedName("created_at") val createdAt: Date?, // should never be null per API definition, but some servers break the contract
// should never be null per API definition, but some servers break the contract
@SerializedName("display_name") val displayName: String?,
// should never be null per API definition, but some servers break the contract
@SerializedName("created_at") val createdAt: Date?,
val note: String,
val url: String,
val avatar: String,
@ -35,10 +37,12 @@ data class Account(
@SerializedName("statuses_count") val statusesCount: Int = 0,
val source: AccountSource? = null,
val bot: Boolean = false,
val emojis: List<Emoji>? = emptyList(), // nullable for backward compatibility
val fields: List<Field>? = emptyList(), // nullable for backward compatibility
// nullable for backward compatibility
val emojis: List<Emoji>? = emptyList(),
// nullable for backward compatibility
val fields: List<Field>? = emptyList(),
val moved: Account? = null,
val roles: List<Role>? = emptyList()
val roles: List<Role>? = emptyList(),
) {
val name: String

View File

@ -30,7 +30,8 @@ import kotlinx.parcelize.Parcelize
data class Attachment(
val id: String,
val url: String,
@SerializedName("preview_url") val previewUrl: String?, // can be null for e.g. audio attachments
// can be null for e.g. audio attachments
@SerializedName("preview_url") val previewUrl: String?,
val meta: MetaData?,
val type: Type,
val description: String?,

View File

@ -21,6 +21,7 @@ import com.google.gson.annotations.SerializedName
data class Conversation(
val id: String,
val accounts: List<TimelineAccount>,
@SerializedName("last_status") val lastStatus: Status?, // should never be null, but apparently its possible https://github.com/tuskyapp/Tusky/issues/1038
// should never be null, but apparently its possible https://github.com/tuskyapp/Tusky/issues/1038
@SerializedName("last_status") val lastStatus: Status?,
val unread: Boolean,
)

View File

@ -2,8 +2,8 @@ package app.pachli.core.network.model
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
import java.util.Date
import kotlinx.parcelize.Parcelize
@Parcelize
data class Filter(

View File

@ -117,8 +117,8 @@ data class Notification(
fun rewriteToStatusTypeIfNeeded(accountId: String): Notification {
if (type == Type.MENTION && status != null) {
return if (status.mentions.any {
it.id == accountId
}
it.id == accountId
}
) {
this
} else {

View File

@ -9,7 +9,8 @@ data class Poll(
val expired: Boolean,
val multiple: Boolean,
@SerializedName("votes_count") val votesCount: Int,
@SerializedName("voters_count") val votersCount: Int?, // nullable for compatibility with Pleroma
// nullable for compatibility with Pleroma
@SerializedName("voters_count") val votersCount: Int?,
val options: List<PollOption>,
val voted: Boolean,
@SerializedName("own_votes") val ownVotes: List<Int>?,

View File

@ -36,6 +36,8 @@ data class Relationship(
*/
@JsonAdapter(GuardedBooleanAdapter::class) val subscribing: Boolean? = null,
@SerializedName("domain_blocking") val blockingDomain: Boolean,
val note: String?, // nullable for backward compatibility / feature detection
val notifying: Boolean?, // since 3.3.0rc
// nullable for backward compatibility / feature detection
val note: String?,
// since 3.3.0rc
val notifying: Boolean?,
)

View File

@ -25,7 +25,8 @@ import java.util.Date
data class Status(
val id: String,
val url: String?, // not present if it's reblog
// not present if it's reblog
val url: String?,
val account: TimelineAccount,
@SerializedName("in_reply_to_id") val inReplyToId: String?,
@SerializedName("in_reply_to_account_id") val inReplyToAccountId: String?,

View File

@ -27,15 +27,15 @@ data class TimelineAccount(
val id: String,
@SerializedName("username") val localUsername: String,
@SerializedName("acct") val username: String,
// should never be null per Api definition, but some servers break the contract
@Deprecated("prefer the `name` property, which is not-null and not-empty")
@SerializedName("display_name")
val displayName: String?, // should never be null per Api definition, but some servers break the contract
val displayName: String?,
val url: String,
val avatar: String,
val note: String,
val bot: Boolean = false,
val emojis: List<Emoji>? = emptyList(), // nullable for backward compatibility
// nullable for backward compatibility
val emojis: List<Emoji>? = emptyList(),
) {
@Suppress("DEPRECATION")

View File

@ -30,22 +30,22 @@ data class Translation(
*/
@SerializedName("detected_source_language") val detectedSourceLanguage: String,
// Not documented, see https://github.com/mastodon/documentation/issues/1248
/**
* The translated spoiler text of the status (text), if it exists, equivalent to
* [Status.spoilerText]
*/
// Not documented, see https://github.com/mastodon/documentation/issues/1248
@SerializedName("spoiler_text") val spoilerText: String,
/** The translated poll (if it exists) */
// Not documented, see https://github.com/mastodon/documentation/issues/1248
/** The translated poll (if it exists) */
val poll: TranslatedPoll?,
// Not documented, see https://github.com/mastodon/documentation/issues/1248
/**
* Translated descriptions for media attachments, if any were attached. Other metadata has
* to be determined from the original attachment.
*/
// Not documented, see https://github.com/mastodon/documentation/issues/1248
@SerializedName("media_attachments") val attachments: List<TranslatedAttachment>,
/** The service that provided the machine translation */

View File

@ -17,6 +17,9 @@
package app.pachli.core.network.retrofit
import java.io.IOException
import javax.inject.Inject
import javax.inject.Singleton
import okhttp3.HttpUrl
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
@ -25,9 +28,6 @@ import okhttp3.Request
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import timber.log.Timber
import java.io.IOException
import javax.inject.Inject
import javax.inject.Singleton
// AccountManager can not be used here as that would create a circular dependency
// between core.network and core.accounts. Instead, the singleton instance of this

View File

@ -69,7 +69,7 @@ class InstanceV1SwitchAuthInterceptorTest {
val interceptor = InstanceSwitchAuthInterceptor()
interceptor.credentials = InstanceSwitchAuthInterceptor.Credentials(
accessToken = "fakeToken",
domain = "test.domain"
domain = "test.domain",
)
val okHttpClient = OkHttpClient.Builder()
@ -96,7 +96,7 @@ class InstanceV1SwitchAuthInterceptorTest {
val interceptor = InstanceSwitchAuthInterceptor()
interceptor.credentials = InstanceSwitchAuthInterceptor.Credentials(
accessToken = "fakeToken",
domain = mockWebServer.hostName
domain = mockWebServer.hostName,
)
val okHttpClient = OkHttpClient.Builder()

View File

@ -20,12 +20,12 @@ package app.pachli.core.preferences
import android.content.SharedPreferences
import androidx.annotation.Keep
import app.pachli.core.common.di.ApplicationScope
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
/**
* An implementation of [SharedPreferences] that exposes all changes to the

View File

@ -77,7 +77,7 @@ hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
ktlint = "org.jlleitschuh.gradle.ktlint:12.0.3"
ktlint = "org.jlleitschuh.gradle.ktlint:12.1.0"
room = { id = "androidx.room", version.ref = "androidx-room" }
quadrant = { id = "com.gaelmarhic.quadrant", version.ref = "quadrant" }