Merge branch 'tuskyapp:develop' into bookwyrm-urls

This commit is contained in:
Mike Barnes 2023-08-08 20:05:04 +10:00 committed by GitHub
commit 5596e31769
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 75 additions and 32 deletions

View File

@ -60,8 +60,7 @@ android {
lint {
lintConfig file("lint.xml")
// Regenerate by deleting app/lint-baseline.xml, then run:
// ./gradlew lintBlueDebug
// Regenerate by running `./gradlew app:newLintBaseline`
baseline = file("lint-baseline.xml")
}
@ -203,3 +202,18 @@ tasks.withType(org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask) {
"--add-opens", "jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED",
"--add-opens", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED"])
}
tasks.register("newLintBaseline") {
description 'Deletes and then recreates the lint baseline'
// This task should always run, irrespective of caching
notCompatibleWithConfigurationCache("Is always out of date")
outputs.upToDateWhen { false }
doLast {
delete android.lint.baseline.path
}
// Regenerate the lint baseline
it.finalizedBy tasks.named("lintBlueDebug")
}

View File

@ -82,13 +82,10 @@ class AccountMediaFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
requireActivity().addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.RESUMED)
val alwaysShowSensitiveMedia = accountManager.activeAccount!!.alwaysShowSensitiveMedia
val preferences = PreferenceManager.getDefaultSharedPreferences(view.context)
val useBlurhash = preferences.getBoolean(PrefKeys.USE_BLURHASH, true)
adapter = AccountMediaGridAdapter(
alwaysShowSensitiveMedia = alwaysShowSensitiveMedia,
useBlurhash = useBlurhash,
context = view.context,
onAttachmentClickListener = ::onAttachmentClick

View File

@ -24,7 +24,6 @@ import com.keylesspalace.tusky.viewdata.AttachmentViewData
import java.util.Random
class AccountMediaGridAdapter(
private val alwaysShowSensitiveMedia: Boolean,
private val useBlurhash: Boolean,
context: Context,
private val onAttachmentClickListener: (AttachmentViewData, View) -> Unit
@ -80,7 +79,7 @@ class AccountMediaGridAdapter(
.into(imageView)
imageView.contentDescription = item.attachment.getFormattedDescription(context)
} else if (item.sensitive && !item.isRevealed && !alwaysShowSensitiveMedia) {
} else if (item.sensitive && !item.isRevealed) {
overlay.show()
overlay.setImageDrawable(mediaHiddenDrawable)

View File

@ -20,6 +20,7 @@ import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import com.keylesspalace.tusky.components.timeline.util.ifExpected
import com.keylesspalace.tusky.db.AccountEntity
import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.viewdata.AttachmentViewData
import retrofit2.HttpException
@ -27,9 +28,9 @@ import retrofit2.HttpException
@OptIn(ExperimentalPagingApi::class)
class AccountMediaRemoteMediator(
private val api: MastodonApi,
private val activeAccount: AccountEntity,
private val viewModel: AccountMediaViewModel
) : RemoteMediator<String, AttachmentViewData>() {
override suspend fun load(
loadType: LoadType,
state: PagingState<String, AttachmentViewData>
@ -58,7 +59,7 @@ class AccountMediaRemoteMediator(
}
val attachments = statuses.flatMap { status ->
AttachmentViewData.list(status)
AttachmentViewData.list(status, activeAccount.alwaysShowSensitiveMedia ?: false)
}
if (loadType == LoadType.REFRESH) {

View File

@ -21,11 +21,13 @@ import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import com.keylesspalace.tusky.db.AccountManager
import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.viewdata.AttachmentViewData
import javax.inject.Inject
class AccountMediaViewModel @Inject constructor(
private val accountManager: AccountManager,
api: MastodonApi
) : ViewModel() {
@ -35,6 +37,8 @@ class AccountMediaViewModel @Inject constructor(
var currentSource: AccountMediaPagingSource? = null
val activeAccount = accountManager.activeAccount!!
@OptIn(ExperimentalPagingApi::class)
val media = Pager(
config = PagingConfig(
@ -48,7 +52,7 @@ class AccountMediaViewModel @Inject constructor(
currentSource = source
}
},
remoteMediator = AccountMediaRemoteMediator(api, this)
remoteMediator = AccountMediaRemoteMediator(api, activeAccount, this)
).flow
.cachedIn(viewModelScope)

View File

@ -57,7 +57,9 @@ class ComposeScheduleView
).apply {
timeZone = TimeZone.getTimeZone("UTC")
}
private var scheduleDateTime: Calendar? = null
/** The date/time the user has chosen to schedule the status, in UTC */
private var scheduleDateTimeUtc: Calendar? = null
init {
binding.scheduledDateTime.setOnClickListener { openPickDateDialog() }
@ -71,13 +73,13 @@ class ComposeScheduleView
}
private fun updateScheduleUi() {
if (scheduleDateTime == null) {
if (scheduleDateTimeUtc == null) {
binding.scheduledDateTime.text = ""
binding.invalidScheduleWarning.visibility = GONE
return
}
val scheduled = scheduleDateTime!!.time
val scheduled = scheduleDateTimeUtc!!.time
binding.scheduledDateTime.text = String.format(
"%s %s",
dateFormat.format(scheduled),
@ -98,21 +100,37 @@ class ComposeScheduleView
}
fun resetSchedule() {
scheduleDateTime = null
scheduleDateTimeUtc = null
updateScheduleUi()
}
fun openPickDateDialog() {
val yesterday = Calendar.getInstance().timeInMillis - 24 * 60 * 60 * 1000
// The earliest point in time the calendar should display. Start with current date/time
val earliest = calendar().apply {
// Add the minimum scheduling interval. This may roll the calendar over to the
// next day (e.g. if the current time is 23:57).
add(Calendar.SECOND, MINIMUM_SCHEDULED_SECONDS)
// Clear out the time components, so it's midnight
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}
val calendarConstraints = CalendarConstraints.Builder()
.setValidator(
DateValidatorPointForward.from(yesterday)
)
.setValidator(DateValidatorPointForward.from(earliest.timeInMillis))
.build()
initializeSuggestedTime()
// Work around a misfeature in MaterialDatePicker. The `selection` is treated as
// millis-from-epoch, in UTC, which is good. However, it is also *displayed* in UTC
// instead of converting to the user's local timezone.
//
// So we have to add the TZ offset before setting it in the picker
val tzOffset = TimeZone.getDefault().getOffset(scheduleDateTimeUtc!!.timeInMillis)
val picker = MaterialDatePicker.Builder
.datePicker()
.setSelection(scheduleDateTime!!.timeInMillis)
.setSelection(scheduleDateTimeUtc!!.timeInMillis + tzOffset)
.setCalendarConstraints(calendarConstraints)
.build()
picker.addOnPositiveButtonClickListener { selection: Long -> onDateSet(selection) }
@ -129,11 +147,12 @@ class ComposeScheduleView
private fun openPickTimeDialog() {
val pickerBuilder = MaterialTimePicker.Builder()
scheduleDateTime?.let {
scheduleDateTimeUtc?.let {
pickerBuilder.setHour(it[Calendar.HOUR_OF_DAY])
.setMinute(it[Calendar.MINUTE])
}
pickerBuilder.setTitleText(dateFormat.format(scheduleDateTimeUtc!!.timeInMillis))
pickerBuilder.setTimeFormat(getTimeFormat(context))
val picker = pickerBuilder.build()
@ -154,7 +173,7 @@ class ComposeScheduleView
fun setDateTime(scheduledAt: String?) {
val date = getDateTime(scheduledAt) ?: return
initializeSuggestedTime()
scheduleDateTime!!.time = date
scheduleDateTimeUtc!!.time = date
updateScheduleUi()
}
@ -180,24 +199,24 @@ class ComposeScheduleView
// see https://github.com/material-components/material-components-android/issues/882
newDate.timeZone = TimeZone.getTimeZone("UTC")
newDate.timeInMillis = selection
scheduleDateTime!![newDate[Calendar.YEAR], newDate[Calendar.MONTH]] = newDate[Calendar.DATE]
scheduleDateTimeUtc!![newDate[Calendar.YEAR], newDate[Calendar.MONTH]] = newDate[Calendar.DATE]
openPickTimeDialog()
}
private fun onTimeSet(hourOfDay: Int, minute: Int) {
initializeSuggestedTime()
scheduleDateTime?.set(Calendar.HOUR_OF_DAY, hourOfDay)
scheduleDateTime?.set(Calendar.MINUTE, minute)
scheduleDateTimeUtc?.set(Calendar.HOUR_OF_DAY, hourOfDay)
scheduleDateTimeUtc?.set(Calendar.MINUTE, minute)
updateScheduleUi()
listener?.onTimeSet(time)
}
val time: String?
get() = scheduleDateTime?.time?.let { iso8601.format(it) }
get() = scheduleDateTimeUtc?.time?.let { iso8601.format(it) }
private fun initializeSuggestedTime() {
if (scheduleDateTime == null) {
scheduleDateTime = calendar().apply {
if (scheduleDateTimeUtc == null) {
scheduleDateTimeUtc = calendar().apply {
add(Calendar.MINUTE, 15)
}
}

View File

@ -518,7 +518,11 @@ class NotificationsFragment :
override fun onViewMedia(position: Int, attachmentIndex: Int, view: View?) {
val status = adapter.peek(position)?.statusViewData?.status ?: return
super.viewMedia(attachmentIndex, list(status), view)
super.viewMedia(
attachmentIndex,
list(status, viewModel.statusDisplayOptions.value.showSensitiveMedia),
view
)
}
override fun onViewThread(position: Int) {

View File

@ -336,7 +336,11 @@ class ViewThreadFragment :
override fun onViewMedia(position: Int, attachmentIndex: Int, view: View?) {
val status = adapter.currentList[position].status
super.viewMedia(attachmentIndex, list(status), view)
super.viewMedia(
attachmentIndex,
list(status, alwaysShowSensitiveMedia),
view
)
}
override fun onViewThread(position: Int) {

View File

@ -35,7 +35,7 @@ data class AttachmentViewData(
companion object {
@JvmStatic
fun list(status: Status): List<AttachmentViewData> {
fun list(status: Status, alwaysShowSensitiveMedia: Boolean = false): List<AttachmentViewData> {
val actionable = status.actionableStatus
return actionable.attachments.map { attachment ->
AttachmentViewData(
@ -43,7 +43,7 @@ data class AttachmentViewData(
statusId = actionable.id,
statusUrl = actionable.url!!,
sensitive = actionable.sensitive,
isRevealed = !actionable.sensitive
isRevealed = alwaysShowSensitiveMedia || !actionable.sensitive
)
}
}

View File

@ -89,6 +89,7 @@
android:importantForAccessibility="no"
android:lineSpacingMultiplier="1.1"
android:textColor="?android:textColorPrimary"
android:textIsSelectable="true"
android:textSize="?attr/status_text_large"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

@ -60,7 +60,7 @@ google-ksp = "com.google.devtools.ksp:1.9.0-1.0.13"
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }
kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
ktlint = "org.jlleitschuh.gradle.ktlint:11.5.0"
ktlint = "org.jlleitschuh.gradle.ktlint:11.5.1"
[libraries]
android-material = { module = "com.google.android.material:material", version.ref = "material" }