chore(deps): update plugin ktlint to v12 (#357)
This commit is contained in:
parent
d4fe1dff9e
commit
d8be70a465
|
@ -7,14 +7,21 @@ indent_style = space
|
|||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# Disable wildcard imports
|
||||
[*.{java,kt}]
|
||||
ktlint_code_style = android_studio
|
||||
|
||||
ij_kotlin_imports_layout = *
|
||||
|
||||
# Disable wildcard imports
|
||||
ij_kotlin_name_count_to_use_star_import = 999
|
||||
ij_kotlin_name_count_to_use_star_import_for_members = 999
|
||||
ij_java_class_count_to_use_import_on_demand = 999
|
||||
|
||||
# Require trailing comma
|
||||
ij_kotlin_allow_trailing_comma = true
|
||||
ij_kotlin_allow_trailing_comma_on_call_site = true
|
||||
|
||||
max_line_length = off
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
|
|
@ -22,8 +22,8 @@ import app.pachli.util.NoUnderlineURLSpan
|
|||
import app.pachli.util.hide
|
||||
import app.pachli.util.show
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@AndroidEntryPoint
|
||||
class AboutActivity : BottomSheetActivity() {
|
||||
|
|
|
@ -45,8 +45,8 @@ import app.pachli.util.viewBinding
|
|||
import app.pachli.viewmodel.AccountsInListViewModel
|
||||
import app.pachli.viewmodel.State
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
private typealias AccountInfo = Pair<TimelineAccount, Boolean>
|
||||
|
||||
|
|
|
@ -51,8 +51,8 @@ import dagger.hilt.InstallIn
|
|||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import dagger.hilt.android.EntryPointAccessors.fromApplication
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import timber.log.Timber
|
||||
|
||||
@AndroidEntryPoint
|
||||
abstract class BaseActivity : AppCompatActivity() {
|
||||
|
|
|
@ -30,8 +30,8 @@ import app.pachli.util.looksLikeMastodonUrl
|
|||
import app.pachli.util.openLink
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/** this is the base class for all activities that open links
|
||||
* links are checked against the api if they are mastodon links so they can be opened in Tusky
|
||||
|
@ -97,7 +97,7 @@ abstract class BottomSheetActivity : BaseActivity() {
|
|||
onEndSearch(url)
|
||||
performUrlFallbackAction(url, lookupFallbackBehavior)
|
||||
}
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,10 @@ class EditProfileActivity : BaseActivity() {
|
|||
binding.fieldList.layoutManager = LinearLayoutManager(this)
|
||||
binding.fieldList.adapter = accountFieldEditAdapter
|
||||
|
||||
val plusDrawable = IconicsDrawable(this, GoogleMaterial.Icon.gmd_add).apply { sizeDp = 12; colorInt = Color.WHITE }
|
||||
val plusDrawable = IconicsDrawable(this, GoogleMaterial.Icon.gmd_add).apply {
|
||||
sizeDp = 12
|
||||
colorInt = Color.WHITE
|
||||
}
|
||||
|
||||
binding.addFieldButton.setCompoundDrawablesRelativeWithIntrinsicBounds(plusDrawable, null, null, null)
|
||||
|
||||
|
|
|
@ -237,7 +237,10 @@ class ListsActivity : BaseActivity() {
|
|||
.apply {
|
||||
val iconColor = MaterialColors.getColor(nameTextView, android.R.attr.textColorTertiary)
|
||||
val context = nameTextView.context
|
||||
val icon = IconicsDrawable(context, GoogleMaterial.Icon.gmd_list).apply { sizeDp = 20; colorInt = iconColor }
|
||||
val icon = IconicsDrawable(context, GoogleMaterial.Icon.gmd_list).apply {
|
||||
sizeDp = 20
|
||||
colorInt = iconColor
|
||||
}
|
||||
|
||||
nameTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null)
|
||||
}
|
||||
|
|
|
@ -153,9 +153,9 @@ import com.mikepenz.materialdrawer.widget.AccountHeaderView
|
|||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import de.c1710.filemojicompat_ui.helpers.EMOJI_PREFERENCE
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
||||
|
|
|
@ -40,11 +40,11 @@ import de.c1710.filemojicompat_defaults.DefaultEmojiPackList
|
|||
import de.c1710.filemojicompat_ui.helpers.EmojiPackHelper
|
||||
import de.c1710.filemojicompat_ui.helpers.EmojiPreference
|
||||
import io.reactivex.rxjava3.plugins.RxJavaPlugins
|
||||
import org.conscrypt.Conscrypt
|
||||
import timber.log.Timber
|
||||
import java.security.Security
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
import org.conscrypt.Conscrypt
|
||||
import timber.log.Timber
|
||||
|
||||
@HiltAndroidApp
|
||||
class PachliApplication : Application() {
|
||||
|
|
|
@ -41,10 +41,10 @@ import com.google.android.material.appbar.AppBarLayout
|
|||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Show a list of statuses of a particular type; containing a particular hashtag,
|
||||
|
|
|
@ -60,14 +60,14 @@ import com.google.android.material.snackbar.Snackbar
|
|||
import com.google.android.material.transition.MaterialArcMotion
|
||||
import com.google.android.material.transition.MaterialContainerTransform
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import java.util.regex.Pattern
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.awaitCancellation
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.util.regex.Pattern
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class TabPreferenceActivity : BaseActivity(), ItemInteractionListener {
|
||||
|
|
|
@ -63,12 +63,12 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.util.Locale
|
||||
import timber.log.Timber
|
||||
|
||||
typealias ToolbarVisibilityListener = (isVisible: Boolean) -> Unit
|
||||
|
||||
|
|
|
@ -3,12 +3,12 @@ package app.pachli.appstore
|
|||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.database.dao.TimelineDao
|
||||
import com.google.gson.Gson
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class CacheUpdater @Inject constructor(
|
||||
eventHub: EventHub,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package app.pachli.appstore
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
|
||||
interface Event
|
||||
|
||||
|
|
|
@ -20,11 +20,11 @@ import app.pachli.util.Success
|
|||
import app.pachli.util.getDomain
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class AccountViewModel @Inject constructor(
|
||||
|
@ -137,8 +137,8 @@ class AccountViewModel @Inject constructor(
|
|||
|
||||
fun changeSubscribingState() {
|
||||
val relationship = relationshipData.value?.data
|
||||
if (relationship?.notifying == true || /* Mastodon 3.3.0rc1 */
|
||||
relationship?.subscribing == true /* Pleroma */
|
||||
if (relationship?.notifying == true || // Mastodon 3.3.0rc1
|
||||
relationship?.subscribing == true // Pleroma
|
||||
) {
|
||||
changeRelationship(RelationShipAction.UNSUBSCRIBE)
|
||||
} else {
|
||||
|
@ -156,7 +156,7 @@ class AccountViewModel @Inject constructor(
|
|||
}
|
||||
}, { e ->
|
||||
Timber.e("Error muting $instance", e)
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ class AccountViewModel @Inject constructor(
|
|||
}
|
||||
}, { e ->
|
||||
Timber.e("Error unmuting $instance", e)
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,6 +317,13 @@ class AccountViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
enum class RelationShipAction {
|
||||
FOLLOW, UNFOLLOW, BLOCK, UNBLOCK, MUTE, UNMUTE, SUBSCRIBE, UNSUBSCRIBE
|
||||
FOLLOW,
|
||||
UNFOLLOW,
|
||||
BLOCK,
|
||||
UNBLOCK,
|
||||
MUTE,
|
||||
UNMUTE,
|
||||
SUBSCRIBE,
|
||||
UNSUBSCRIBE,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import at.connyduck.calladapter.networkresult.onFailure
|
|||
import at.connyduck.calladapter.networkresult.onSuccess
|
||||
import at.connyduck.calladapter.networkresult.runCatching
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
|
@ -32,7 +33,6 @@ import kotlinx.coroutines.flow.MutableSharedFlow
|
|||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
data class AccountListState(
|
||||
val list: MastoList,
|
||||
|
|
|
@ -50,9 +50,9 @@ import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
|||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Fragment with multiple columns of media previews for the specified account.
|
||||
|
|
|
@ -64,11 +64,11 @@ import com.google.android.material.color.MaterialColors
|
|||
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.Response
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class AccountListFragment :
|
||||
|
@ -228,7 +228,7 @@ class AccountListFragment :
|
|||
onBlockSuccess(block, id, position)
|
||||
}, {
|
||||
onBlockFailure(block, id, it)
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -130,7 +130,13 @@ class AnnouncementAdapter(
|
|||
spanBuilder.setSpan(span, 0, 1, 0)
|
||||
Glide.with(this)
|
||||
.asDrawable()
|
||||
.load(if (animateEmojis) { reaction.url } else { reaction.staticUrl })
|
||||
.load(
|
||||
if (animateEmojis) {
|
||||
reaction.url
|
||||
} else {
|
||||
reaction.staticUrl
|
||||
},
|
||||
)
|
||||
.into(span.getTarget(animateEmojis))
|
||||
this.text = spanBuilder
|
||||
}
|
||||
|
|
|
@ -32,9 +32,9 @@ import app.pachli.util.Resource
|
|||
import app.pachli.util.Success
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class AnnouncementsViewModel @Inject constructor(
|
||||
|
|
|
@ -111,17 +111,17 @@ import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
|||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.text.DecimalFormat
|
||||
import java.util.Locale
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Compose a status, either by creating one from scratch, or by editing an existing
|
||||
|
@ -186,7 +186,8 @@ class ComposeActivity :
|
|||
uriNew,
|
||||
size,
|
||||
itemOld.description,
|
||||
null, // Intentionally reset focus when cropping
|
||||
// Intentionally reset focus when cropping
|
||||
null,
|
||||
itemOld,
|
||||
)
|
||||
}
|
||||
|
@ -515,13 +516,22 @@ class ComposeActivity :
|
|||
|
||||
val textColor = MaterialColors.getColor(binding.root, android.R.attr.textColorTertiary)
|
||||
|
||||
val cameraIcon = IconicsDrawable(this, GoogleMaterial.Icon.gmd_camera_alt).apply { colorInt = textColor; sizeDp = 18 }
|
||||
val cameraIcon = IconicsDrawable(this, GoogleMaterial.Icon.gmd_camera_alt).apply {
|
||||
colorInt = textColor
|
||||
sizeDp = 18
|
||||
}
|
||||
binding.actionPhotoTake.setCompoundDrawablesRelativeWithIntrinsicBounds(cameraIcon, null, null, null)
|
||||
|
||||
val imageIcon = IconicsDrawable(this, GoogleMaterial.Icon.gmd_image).apply { colorInt = textColor; sizeDp = 18 }
|
||||
val imageIcon = IconicsDrawable(this, GoogleMaterial.Icon.gmd_image).apply {
|
||||
colorInt = textColor
|
||||
sizeDp = 18
|
||||
}
|
||||
binding.actionPhotoPick.setCompoundDrawablesRelativeWithIntrinsicBounds(imageIcon, null, null, null)
|
||||
|
||||
val pollIcon = IconicsDrawable(this, GoogleMaterial.Icon.gmd_poll).apply { colorInt = textColor; sizeDp = 18 }
|
||||
val pollIcon = IconicsDrawable(this, GoogleMaterial.Icon.gmd_poll).apply {
|
||||
colorInt = textColor
|
||||
sizeDp = 18
|
||||
}
|
||||
binding.addPollTextActionTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(pollIcon, null, null, null)
|
||||
|
||||
binding.actionPhotoTake.visible(Intent(MediaStore.ACTION_IMAGE_CAPTURE).resolveActivity(packageManager) != null)
|
||||
|
@ -1274,10 +1284,15 @@ class ComposeActivity :
|
|||
val state: State,
|
||||
) {
|
||||
enum class Type {
|
||||
IMAGE, VIDEO, AUDIO;
|
||||
IMAGE,
|
||||
VIDEO,
|
||||
AUDIO,
|
||||
}
|
||||
enum class State {
|
||||
UPLOADING, UNPROCESSED, PROCESSED, PUBLISHED
|
||||
UPLOADING,
|
||||
UNPROCESSED,
|
||||
PROCESSED,
|
||||
PUBLISHED,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ import app.pachli.service.ServiceClient
|
|||
import app.pachli.service.StatusToSend
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
|
@ -53,7 +54,6 @@ import kotlinx.coroutines.flow.update
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ComposeViewModel @Inject constructor(
|
||||
|
@ -168,7 +168,11 @@ class ComposeViewModel @Inject constructor(
|
|||
item.copy(
|
||||
id = event.mediaId,
|
||||
uploadPercent = -1,
|
||||
state = if (event.processed) { QueuedMedia.State.PROCESSED } else { QueuedMedia.State.UNPROCESSED },
|
||||
state = if (event.processed) {
|
||||
QueuedMedia.State.PROCESSED
|
||||
} else {
|
||||
QueuedMedia.State.UNPROCESSED
|
||||
},
|
||||
)
|
||||
is UploadEvent.ErrorEvent -> {
|
||||
media.update { mediaList -> mediaList.filter { it.localId != mediaItem.localId } }
|
||||
|
@ -383,7 +387,7 @@ class ComposeViewModel @Inject constructor(
|
|||
}, { e ->
|
||||
Timber.e("Autocomplete search for $token failed.", e)
|
||||
emptyList()
|
||||
},)
|
||||
})
|
||||
}
|
||||
'#' -> {
|
||||
return api.searchSync(query = token, type = SearchType.Hashtag.apiParameter, limit = 10)
|
||||
|
@ -392,7 +396,7 @@ class ComposeViewModel @Inject constructor(
|
|||
}, { e ->
|
||||
Timber.e("Autocomplete search for $token failed.", e)
|
||||
emptyList()
|
||||
},)
|
||||
})
|
||||
}
|
||||
':' -> {
|
||||
val emojiList = emoji.replayCache.firstOrNull() ?: return emptyList()
|
||||
|
|
|
@ -52,10 +52,10 @@ fun downsizeImage(
|
|||
// Get EXIF data, for orientation info.
|
||||
val orientation = getImageOrientation(uri, contentResolver)
|
||||
/* Unfortunately, there isn't a determined worst case compression ratio for image
|
||||
* formats. So, the only way to tell if they're too big is to compress them and
|
||||
* test, and keep trying at smaller sizes. The initial estimate should be good for
|
||||
* many cases, so it should only iterate once, but the loop is used to be absolutely
|
||||
* sure it gets downsized to below the limit. */
|
||||
* formats. So, the only way to tell if they're too big is to compress them and
|
||||
* test, and keep trying at smaller sizes. The initial estimate should be good for
|
||||
* many cases, so it should only iterate once, but the loop is used to be absolutely
|
||||
* sure it gets downsized to below the limit. */
|
||||
var scaledImageSize = 1024
|
||||
do {
|
||||
val outputStream = try {
|
||||
|
|
|
@ -38,6 +38,13 @@ import app.pachli.util.getImageSquarePixels
|
|||
import app.pachli.util.getMediaSize
|
||||
import app.pachli.util.getServerErrorMessage
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
|
@ -56,13 +63,6 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
|||
import okhttp3.MultipartBody
|
||||
import retrofit2.HttpException
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
sealed interface FinalUploadEvent
|
||||
|
||||
|
@ -85,9 +85,9 @@ fun createNewImageFile(context: Context, suffix: String = ".jpg"): File {
|
|||
val imageFileName = "Pachli_${randomId}_"
|
||||
val storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
|
||||
return File.createTempFile(
|
||||
imageFileName, /* prefix */
|
||||
suffix, /* suffix */
|
||||
storageDir, /* directory */
|
||||
imageFileName,
|
||||
suffix,
|
||||
storageDir,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -259,9 +259,9 @@ class MediaUploader @Inject constructor(
|
|||
// .m4a files. See https://github.com/tuskyapp/Tusky/issues/3189 for details.
|
||||
// Sniff the content of the file to determine the actual type.
|
||||
if (mimeType != null && (
|
||||
mimeType.startsWith("audio/", ignoreCase = true) ||
|
||||
mimeType.startsWith("video/", ignoreCase = true)
|
||||
)
|
||||
mimeType.startsWith("audio/", ignoreCase = true) ||
|
||||
mimeType.startsWith("video/", ignoreCase = true)
|
||||
)
|
||||
) {
|
||||
val retriever = MediaMetadataRetriever()
|
||||
retriever.setDataSource(context, media.uri)
|
||||
|
|
|
@ -25,6 +25,8 @@ import app.pachli.R
|
|||
import app.pachli.core.network.model.NewPoll
|
||||
import app.pachli.databinding.DialogAddPollBinding
|
||||
|
||||
const val DAY_SECONDS = 60 * 60 * 24
|
||||
|
||||
fun showAddPollDialog(
|
||||
context: Context,
|
||||
poll: NewPoll?,
|
||||
|
@ -74,7 +76,6 @@ fun showAddPollDialog(
|
|||
}
|
||||
}
|
||||
|
||||
val DAY_SECONDS = 60 * 60 * 24
|
||||
val desiredDuration = poll?.expiresIn ?: DAY_SECONDS
|
||||
val pollDurationId = durations.indexOfLast {
|
||||
it <= desiredDuration
|
||||
|
|
|
@ -225,7 +225,7 @@ class ComposeScheduleView
|
|||
}
|
||||
|
||||
companion object {
|
||||
var MINIMUM_SCHEDULED_SECONDS = 330 // Minimum is 5 minutes, pad 30 seconds for posting
|
||||
const val MINIMUM_SCHEDULED_SECONDS = 330 // Minimum is 5 minutes, pad 30 seconds for posting
|
||||
fun calendar(): Calendar = Calendar.getInstance(TimeZone.getDefault())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,10 @@ class TootButton
|
|||
Status.Visibility.DIRECT,
|
||||
-> {
|
||||
setText(R.string.action_send)
|
||||
IconicsDrawable(context, GoogleMaterial.Icon.gmd_lock).apply { sizeDp = 18; colorInt = Color.WHITE }
|
||||
IconicsDrawable(context, GoogleMaterial.Icon.gmd_lock).apply {
|
||||
sizeDp = 18
|
||||
colorInt = Color.WHITE
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
null
|
||||
|
|
|
@ -61,13 +61,13 @@ import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
|||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.toDuration
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.toDuration
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ConversationsFragment :
|
||||
|
|
|
@ -32,10 +32,10 @@ import app.pachli.usecase.TimelineCases
|
|||
import app.pachli.util.EmptyPagingSource
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ConversationsViewModel @Inject constructor(
|
||||
|
@ -81,7 +81,7 @@ class ConversationsViewModel @Inject constructor(
|
|||
saveConversationToDb(newConversation)
|
||||
}, { e ->
|
||||
Timber.w("failed to favourite status", e)
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ class ConversationsViewModel @Inject constructor(
|
|||
saveConversationToDb(newConversation)
|
||||
}, { e ->
|
||||
Timber.w("failed to bookmark status", e)
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ class ConversationsViewModel @Inject constructor(
|
|||
saveConversationToDb(newConversation)
|
||||
}, { e ->
|
||||
Timber.w("failed to vote in poll", e)
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,12 @@ import app.pachli.core.network.model.NewPoll
|
|||
import app.pachli.core.network.model.Status
|
||||
import app.pachli.util.copyToFile
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.OkHttpClient
|
||||
|
@ -37,12 +43,6 @@ import okhttp3.Request
|
|||
import okio.buffer
|
||||
import okio.sink
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
class DraftHelper @Inject constructor(
|
||||
@ApplicationContext val context: Context,
|
||||
|
|
|
@ -37,11 +37,11 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|||
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class DraftsActivity : BaseActivity(), DraftActionListener {
|
||||
|
|
|
@ -28,8 +28,8 @@ import app.pachli.core.network.model.Status
|
|||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import at.connyduck.calladapter.networkresult.NetworkResult
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@HiltViewModel
|
||||
class DraftsViewModel @Inject constructor(
|
||||
|
|
|
@ -27,10 +27,10 @@ import com.google.android.material.chip.Chip
|
|||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
|
||||
/**
|
||||
* Edit a single server-side filter.
|
||||
|
@ -302,7 +302,11 @@ class EditFilterActivity : BaseActivity() {
|
|||
// but create/edit take a number of seconds (relative to the time the operation is posted)
|
||||
fun getSecondsForDurationIndex(index: Int, context: Context?, default: Date? = null): Int? {
|
||||
return when (index) {
|
||||
-1 -> if (default == null) { default } else { ((default.time - System.currentTimeMillis()) / 1000).toInt() }
|
||||
-1 -> if (default == null) {
|
||||
default
|
||||
} else {
|
||||
((default.time - System.currentTimeMillis()) / 1000).toInt()
|
||||
}
|
||||
0 -> null
|
||||
else -> context?.resources?.getIntArray(R.array.filter_duration_values)?.get(index)
|
||||
}
|
||||
|
|
|
@ -10,10 +10,10 @@ import app.pachli.core.network.model.FilterKeyword
|
|||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.withContext
|
||||
import retrofit2.HttpException
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class EditFilterViewModel @Inject constructor(val api: MastodonApi, val eventHub: EventHub) : ViewModel() {
|
||||
|
|
|
@ -10,11 +10,11 @@ import app.pachli.core.network.retrofit.MastodonApi
|
|||
import at.connyduck.calladapter.networkresult.fold
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class FiltersViewModel @Inject constructor(
|
||||
|
@ -23,7 +23,11 @@ class FiltersViewModel @Inject constructor(
|
|||
) : ViewModel() {
|
||||
|
||||
enum class LoadingState {
|
||||
INITIAL, LOADING, LOADED, ERROR_NETWORK, ERROR_OTHER
|
||||
INITIAL,
|
||||
LOADING,
|
||||
LOADED,
|
||||
ERROR_NETWORK,
|
||||
ERROR_OTHER,
|
||||
}
|
||||
|
||||
data class State(val filters: List<Filter>, val loadingState: LoadingState)
|
||||
|
|
|
@ -27,10 +27,10 @@ import at.connyduck.calladapter.networkresult.fold
|
|||
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class FollowedTagsActivity :
|
||||
|
|
|
@ -12,8 +12,8 @@ import app.pachli.core.network.model.HashTag
|
|||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import timber.log.Timber
|
||||
|
||||
@HiltViewModel
|
||||
class FollowedTagsViewModel @Inject constructor(
|
||||
|
@ -43,6 +43,6 @@ class FollowedTagsViewModel @Inject constructor(
|
|||
}, { e ->
|
||||
Timber.e("Autocomplete search for $token failed.", e)
|
||||
emptyList()
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,10 @@ import app.pachli.core.network.retrofit.MastodonApi
|
|||
import at.connyduck.calladapter.networkresult.fold
|
||||
import at.connyduck.calladapter.networkresult.getOrElse
|
||||
import at.connyduck.calladapter.networkresult.onSuccess
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class InstanceInfoRepository @Inject constructor(
|
||||
private val api: MastodonApi,
|
||||
|
@ -77,12 +77,18 @@ class InstanceInfoRepository @Inject constructor(
|
|||
maxFieldNameLength = instance.pleroma?.metadata?.fieldLimits?.nameLength,
|
||||
maxFieldValueLength = instance.pleroma?.metadata?.fieldLimits?.valueLength,
|
||||
)
|
||||
try { instanceDao.upsert(instanceEntity) } catch (_: Exception) { }
|
||||
try {
|
||||
instanceDao.upsert(instanceEntity)
|
||||
} catch (_: Exception) { }
|
||||
instanceEntity
|
||||
},
|
||||
{ throwable ->
|
||||
Timber.w("failed to instance, falling back to cache and default values", throwable)
|
||||
try { instanceDao.getInstanceInfo(instanceName) } catch (_: Exception) { null }
|
||||
try {
|
||||
instanceDao.getInstanceInfo(instanceName)
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
},
|
||||
).let { instanceInfo: InstanceInfoEntity? ->
|
||||
InstanceInfo(
|
||||
|
|
|
@ -20,9 +20,9 @@ import at.connyduck.calladapter.networkresult.fold
|
|||
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class InstanceListFragment :
|
||||
|
@ -71,7 +71,7 @@ class InstanceListFragment :
|
|||
adapter.addItem(instance)
|
||||
}, { e ->
|
||||
Timber.e("Error muting domain $instance", e)
|
||||
},)
|
||||
})
|
||||
} else {
|
||||
api.unblockDomain(instance).fold({
|
||||
adapter.removeItem(position)
|
||||
|
@ -82,7 +82,7 @@ class InstanceListFragment :
|
|||
.show()
|
||||
}, { e ->
|
||||
Timber.e("Error unmuting domain $instance", e)
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,10 +44,10 @@ import app.pachli.util.viewBinding
|
|||
import at.connyduck.calladapter.networkresult.fold
|
||||
import com.bumptech.glide.Glide
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.HttpUrl
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Main login page, the first thing that users see.
|
||||
|
@ -333,7 +333,7 @@ class LoginActivity : BaseActivity() {
|
|||
binding.domainTextInputLayout.error =
|
||||
getString(R.string.error_loading_account_details)
|
||||
Timber.e(getString(R.string.error_loading_account_details), e)
|
||||
},)
|
||||
})
|
||||
}
|
||||
|
||||
private fun setLoading(loadingState: Boolean) {
|
||||
|
|
|
@ -21,10 +21,10 @@ import androidx.lifecycle.viewModelScope
|
|||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class LoginWebViewViewModel @Inject constructor(
|
||||
|
@ -43,7 +43,7 @@ class LoginWebViewViewModel @Inject constructor(
|
|||
instanceRules.value = instance.rules?.map { rule -> rule.text }.orEmpty()
|
||||
}, { throwable ->
|
||||
Timber.w("failed to load instance info", throwable)
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,11 +28,11 @@ import app.pachli.core.network.model.Marker
|
|||
import app.pachli.core.network.model.Notification
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.delay
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.min
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlinx.coroutines.delay
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Fetch Mastodon notifications and show Android notifications, with summaries, for them.
|
||||
|
|
|
@ -57,9 +57,9 @@ import app.pachli.viewdata.calculatePercent
|
|||
import app.pachli.worker.NotificationWorker
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.ExecutionException
|
||||
import java.util.concurrent.TimeUnit
|
||||
import timber.log.Timber
|
||||
|
||||
/** ID of notification shown when fetching notifications */
|
||||
const val NOTIFICATION_ID_FETCH_NOTIFICATION = 0
|
||||
|
|
|
@ -324,7 +324,8 @@ class NotificationsFragment :
|
|||
when (it) {
|
||||
is UiSuccess.Block, is UiSuccess.Mute, is UiSuccess.MuteConversation ->
|
||||
adapter.refresh()
|
||||
else -> { /* nothing to do */
|
||||
else -> {
|
||||
/* nothing to do */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,12 @@ import app.pachli.core.network.model.Links
|
|||
import app.pachli.core.network.model.Notification
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import com.google.gson.Gson
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import okhttp3.Headers
|
||||
import retrofit2.Response
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
private val INVALID = LoadResult.Invalid<String, Notification>()
|
||||
|
||||
|
|
|
@ -26,13 +26,13 @@ import app.pachli.core.common.di.ApplicationScope
|
|||
import app.pachli.core.network.model.Notification
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import com.google.gson.Gson
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.Response
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class NotificationsRepository @Inject constructor(
|
||||
private val mastodonApi: MastodonApi,
|
||||
|
|
|
@ -49,6 +49,8 @@ import app.pachli.viewdata.NotificationViewData
|
|||
import app.pachli.viewdata.StatusViewData
|
||||
import at.connyduck.calladapter.networkresult.getOrThrow
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
@ -72,8 +74,6 @@ import kotlinx.coroutines.flow.stateIn
|
|||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
data class UiState(
|
||||
/** Filtered notification types */
|
||||
|
@ -333,6 +333,7 @@ class NotificationsViewModel @Inject constructor(
|
|||
// message, as it will be confusing to the user.
|
||||
val uiSuccess = MutableSharedFlow<UiSuccess>()
|
||||
|
||||
@Suppress("ktlint:standard:property-naming")
|
||||
/** Channel for error results */
|
||||
// Errors are sent to a channel to ensure that any errors that occur *before* there are any
|
||||
// subscribers are retained. If this was a SharedFlow any errors would be dropped, and if it
|
||||
|
|
|
@ -55,11 +55,11 @@ import com.google.android.material.snackbar.Snackbar
|
|||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class AccountPreferencesFragment : PreferenceFragmentCompat() {
|
||||
|
|
|
@ -36,10 +36,10 @@ import app.pachli.core.preferences.PrefKeys.APP_THEME
|
|||
import app.pachli.databinding.ActivityPreferencesBinding
|
||||
import app.pachli.util.setAppNightMode
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Show specific preferences.
|
||||
|
|
|
@ -40,12 +40,12 @@ import app.pachli.util.Success
|
|||
import app.pachli.viewdata.StatusViewData
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ReportViewModel @Inject constructor(
|
||||
|
@ -195,7 +195,7 @@ class ReportViewModel @Inject constructor(
|
|||
}
|
||||
}, { t ->
|
||||
blockStateMutable.value = Error(false, t.message)
|
||||
},)
|
||||
})
|
||||
}
|
||||
blockStateMutable.value = Loading()
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ class ReportViewModel @Inject constructor(
|
|||
reportingStateMutable.value = Success(true)
|
||||
}, { error ->
|
||||
reportingStateMutable.value = Error(cause = error)
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,9 +55,9 @@ import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
|||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ReportStatusesFragment :
|
||||
|
|
|
@ -44,9 +44,9 @@ import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
|||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ScheduledStatusActivity :
|
||||
|
|
|
@ -26,9 +26,9 @@ import app.pachli.core.network.model.ScheduledStatus
|
|||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ScheduledStatusViewModel @Inject constructor(
|
||||
|
|
|
@ -33,11 +33,11 @@ import at.connyduck.calladapter.networkresult.NetworkResult
|
|||
import at.connyduck.calladapter.networkresult.fold
|
||||
import at.connyduck.calladapter.networkresult.onFailure
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class SearchViewModel @Inject constructor(
|
||||
|
@ -127,7 +127,7 @@ class SearchViewModel @Inject constructor(
|
|||
)
|
||||
}, { t ->
|
||||
Timber.d("Failed to reblog status ${statusViewData.id}", t)
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,8 +26,8 @@ import app.pachli.core.preferences.PrefKeys
|
|||
import app.pachli.core.preferences.SharedPreferencesRepository
|
||||
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@AndroidEntryPoint
|
||||
class SearchAccountsFragment : SearchFragment<TimelineAccount>() {
|
||||
|
|
|
@ -32,10 +32,10 @@ import com.mikepenz.iconics.IconicsDrawable
|
|||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class SearchFragment<T : Any> :
|
||||
Fragment(R.layout.fragment_search),
|
||||
|
|
|
@ -58,10 +58,10 @@ import at.connyduck.calladapter.networkresult.fold
|
|||
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class SearchStatusesFragment : SearchFragment<StatusViewData>(), StatusActionListener {
|
||||
|
|
|
@ -41,14 +41,14 @@ import app.pachli.viewdata.StatusViewData
|
|||
import at.connyduck.calladapter.networkresult.NetworkResult
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import com.google.gson.Gson
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
// TODO: This is very similar to NetworkTimelineRepository. They could be merged (and the use
|
||||
// of the cache be made a parameter to getStatusStream), except that they return Pagers of
|
||||
|
@ -213,7 +213,7 @@ class CachedTimelineRepository @Inject constructor(
|
|||
}, {
|
||||
// Reset the translation state
|
||||
saveStatusViewData(statusViewData)
|
||||
},)
|
||||
})
|
||||
return translation
|
||||
}
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ import app.pachli.core.network.model.FilterV1
|
|||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import at.connyduck.calladapter.networkresult.getOrThrow
|
||||
import retrofit2.HttpException
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import retrofit2.HttpException
|
||||
|
||||
sealed interface FilterKind {
|
||||
/** API v1 filter, filtering happens client side */
|
||||
|
|
|
@ -31,10 +31,10 @@ import app.pachli.core.network.model.Status
|
|||
import app.pachli.core.network.model.TimelineKind
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import app.pachli.util.getDomain
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
// Things that make this more difficult than it should be:
|
||||
//
|
||||
|
|
|
@ -82,6 +82,7 @@ import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
|||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
|
@ -91,7 +92,6 @@ import kotlinx.coroutines.flow.onEach
|
|||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@AndroidEntryPoint
|
||||
class TimelineFragment :
|
||||
|
@ -212,7 +212,10 @@ class TimelineFragment :
|
|||
*/
|
||||
// TODO: Copied from NotificationsFragment
|
||||
val updateTimestampFlow = flow {
|
||||
while (true) { delay(60.seconds); emit(Unit) }
|
||||
while (true) {
|
||||
delay(60.seconds)
|
||||
emit(Unit)
|
||||
}
|
||||
}.onEach {
|
||||
adapter.notifyItemRangeChanged(0, adapter.itemCount, listOf(StatusBaseViewHolder.Key.KEY_CREATED))
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package app.pachli.components.timeline.util
|
||||
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
import retrofit2.HttpException
|
||||
|
||||
fun Throwable.isExpected() = this is IOException || this is HttpException
|
||||
|
||||
|
|
|
@ -37,13 +37,13 @@ import app.pachli.core.network.model.Links
|
|||
import app.pachli.core.network.model.Status
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import com.google.gson.Gson
|
||||
import java.io.IOException
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import okhttp3.Headers
|
||||
import retrofit2.HttpException
|
||||
import retrofit2.Response
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
|
||||
@OptIn(ExperimentalPagingApi::class)
|
||||
class CachedTimelineRemoteMediator(
|
||||
|
|
|
@ -39,13 +39,13 @@ import app.pachli.util.StatusDisplayOptionsRepository
|
|||
import app.pachli.viewdata.StatusViewData
|
||||
import com.google.gson.Gson
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* TimelineViewModel that caches all statuses in a local database
|
||||
|
|
|
@ -21,8 +21,8 @@ import androidx.paging.PagingSource
|
|||
import androidx.paging.PagingSource.LoadResult
|
||||
import androidx.paging.PagingState
|
||||
import app.pachli.core.network.model.Status
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import timber.log.Timber
|
||||
|
||||
private val INVALID = LoadResult.Invalid<String, Status>()
|
||||
|
||||
|
|
|
@ -27,11 +27,11 @@ import app.pachli.core.accounts.AccountManager
|
|||
import app.pachli.core.network.model.Status
|
||||
import app.pachli.core.network.model.TimelineKind
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import java.io.IOException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import retrofit2.HttpException
|
||||
import retrofit2.Response
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
|
||||
/** Remote mediator for accessing timelines that are not backed by the database. */
|
||||
@OptIn(ExperimentalPagingApi::class)
|
||||
|
|
|
@ -38,13 +38,13 @@ import app.pachli.usecase.TimelineCases
|
|||
import app.pachli.util.StatusDisplayOptionsRepository
|
||||
import app.pachli.viewdata.StatusViewData
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* TimelineViewModel that caches all statuses in an in-memory list
|
||||
|
|
|
@ -21,12 +21,12 @@ import app.pachli.BuildConfig
|
|||
import app.pachli.core.common.string.isLessThan
|
||||
import app.pachli.core.network.model.Links
|
||||
import app.pachli.core.network.model.Status
|
||||
import retrofit2.HttpException
|
||||
import retrofit2.Response
|
||||
import timber.log.Timber
|
||||
import java.util.TreeMap
|
||||
import kotlin.Result.Companion.failure
|
||||
import kotlin.Result.Companion.success
|
||||
import retrofit2.HttpException
|
||||
import retrofit2.Response
|
||||
import timber.log.Timber
|
||||
|
||||
/** A page of data from the Mastodon API */
|
||||
data class Page(
|
||||
|
|
|
@ -57,6 +57,7 @@ import app.pachli.util.StatusDisplayOptionsRepository
|
|||
import app.pachli.util.throttleFirst
|
||||
import app.pachli.viewdata.StatusViewData
|
||||
import at.connyduck.calladapter.networkresult.getOrThrow
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
|
@ -75,7 +76,6 @@ import kotlinx.coroutines.flow.receiveAsFlow
|
|||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
data class UiState(
|
||||
/** True if the FAB should be shown while scrolling */
|
||||
|
@ -287,6 +287,7 @@ abstract class TimelineViewModel(
|
|||
// message, as it will be confusing to the user.
|
||||
val uiSuccess = MutableSharedFlow<UiSuccess>()
|
||||
|
||||
@Suppress("ktlint:standard:property-naming")
|
||||
/** Channel for error results */
|
||||
// Errors are sent to a channel to ensure that any errors that occur *before* there are any
|
||||
// subscribers are retained. If this was a SharedFlow any errors would be dropped, and if it
|
||||
|
|
|
@ -26,6 +26,8 @@ import app.pachli.util.StatusDisplayOptionsRepository
|
|||
import app.pachli.util.throttleFirst
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
@ -34,8 +36,6 @@ import kotlinx.coroutines.flow.filterIsInstance
|
|||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
sealed interface UiAction
|
||||
|
||||
|
|
|
@ -28,14 +28,14 @@ import app.pachli.core.network.retrofit.MastodonApi
|
|||
import app.pachli.viewdata.TrendingViewData
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.filterIsInstance
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class TrendingTagsViewModel @Inject constructor(
|
||||
|
@ -43,7 +43,12 @@ class TrendingTagsViewModel @Inject constructor(
|
|||
private val eventHub: EventHub,
|
||||
) : ViewModel() {
|
||||
enum class LoadingState {
|
||||
INITIAL, LOADING, REFRESHING, LOADED, ERROR_NETWORK, ERROR_OTHER
|
||||
INITIAL,
|
||||
LOADING,
|
||||
REFRESHING,
|
||||
LOADED,
|
||||
ERROR_NETWORK,
|
||||
ERROR_OTHER,
|
||||
}
|
||||
|
||||
data class TrendingTagsUiState(
|
||||
|
|
|
@ -49,6 +49,7 @@ import at.connyduck.calladapter.networkresult.getOrElse
|
|||
import at.connyduck.calladapter.networkresult.getOrThrow
|
||||
import com.google.gson.Gson
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
|
@ -59,7 +60,6 @@ import kotlinx.coroutines.flow.update
|
|||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ViewThreadViewModel @Inject constructor(
|
||||
|
@ -235,7 +235,7 @@ class ViewThreadViewModel @Inject constructor(
|
|||
detailedStatusPosition = 0,
|
||||
revealButton = RevealButtonState.NO_BUTTON,
|
||||
)
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -473,7 +473,7 @@ class ViewThreadViewModel @Inject constructor(
|
|||
if (it is HttpException && it.code() == 403) return@fold
|
||||
|
||||
_errors.emit(it)
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -643,5 +643,7 @@ sealed interface ThreadUiState {
|
|||
}
|
||||
|
||||
enum class RevealButtonState {
|
||||
NO_BUTTON, REVEAL, HIDE
|
||||
NO_BUTTON,
|
||||
REVEAL,
|
||||
HIDE,
|
||||
}
|
||||
|
|
|
@ -50,9 +50,9 @@ import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
|||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ViewEditsFragment :
|
||||
|
|
|
@ -25,6 +25,7 @@ import app.pachli.core.network.model.StatusEdit
|
|||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import at.connyduck.calladapter.networkresult.getOrElse
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
@ -44,7 +45,6 @@ import org.pageseeder.diffx.token.impl.SpaceToken
|
|||
import org.pageseeder.diffx.xml.NamespaceSet
|
||||
import org.pageseeder.xmlwriter.XML.NamespaceAware
|
||||
import org.pageseeder.xmlwriter.XMLStringWriter
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ViewEditsViewModel @Inject constructor(private val api: MastodonApi) : ViewModel() {
|
||||
|
|
|
@ -26,10 +26,10 @@ import app.pachli.R
|
|||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.database.dao.DraftDao
|
||||
import app.pachli.core.navigation.DraftsActivityIntent
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* This class manages an alert popup when a post has failed and been saved to drafts.
|
||||
|
|
|
@ -66,9 +66,9 @@ import at.connyduck.calladapter.networkresult.fold
|
|||
import at.connyduck.calladapter.networkresult.onFailure
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import io.github.z4kn4fein.semver.constraints.toConstraint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/* Note from Andrew on Jan. 22, 2017: This class is a design problem for me, so I left it with an
|
||||
* awkward name. TimelineFragment and NotificationFragment have significant overlap but the nature
|
||||
|
|
|
@ -59,9 +59,9 @@ import com.bumptech.glide.request.target.CustomTarget
|
|||
import com.bumptech.glide.request.transition.Transition
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import okhttp3.OkHttpClient
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
/**
|
||||
* Plays a video, showing media description if available.
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
|
||||
package app.pachli.network
|
||||
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import okio.BufferedSink
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
||||
class ProgressRequestBody(
|
||||
private val content: InputStream,
|
||||
|
|
|
@ -23,12 +23,12 @@ import app.pachli.core.network.ServerCapabilities
|
|||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import com.github.michaelbull.result.getOr
|
||||
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 javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class ServerCapabilitiesRepository @Inject constructor(
|
||||
|
@ -58,7 +58,7 @@ class ServerCapabilitiesRepository @Inject constructor(
|
|||
{
|
||||
mastodonApi.getInstanceV1().fold({ instance ->
|
||||
ServerCapabilities.from(instance).getOr { null }
|
||||
}, { null },)
|
||||
}, { null })
|
||||
},
|
||||
) ?: ServerCapabilities()
|
||||
}
|
||||
|
|
|
@ -27,10 +27,10 @@ import app.pachli.components.notifications.updateUnifiedPushSubscription
|
|||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@DelicateCoroutinesApi
|
||||
@AndroidEntryPoint
|
||||
|
|
|
@ -43,8 +43,8 @@ import app.pachli.core.network.model.Status
|
|||
import app.pachli.service.SendStatusService
|
||||
import app.pachli.service.StatusToSend
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import timber.log.Timber
|
||||
|
||||
@AndroidEntryPoint
|
||||
class SendStatusBroadcastReceiver : BroadcastReceiver() {
|
||||
|
|
|
@ -25,12 +25,12 @@ import app.pachli.core.accounts.AccountManager
|
|||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import app.pachli.worker.NotificationWorker
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.unifiedpush.android.connector.MessagingReceiver
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@DelicateCoroutinesApi
|
||||
@AndroidEntryPoint
|
||||
|
|
|
@ -38,6 +38,9 @@ import app.pachli.core.network.retrofit.MastodonApi
|
|||
import app.pachli.util.unsafeLazy
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
|
@ -48,9 +51,6 @@ import kotlinx.coroutines.runBlocking
|
|||
import kotlinx.parcelize.Parcelize
|
||||
import retrofit2.HttpException
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class SendStatusService : Service() {
|
||||
|
@ -194,7 +194,7 @@ class SendStatusService : Service() {
|
|||
failOrRetry(throwable, statusId)
|
||||
|
||||
return@launch
|
||||
},)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ class SendStatusService : Service() {
|
|||
}, { throwable ->
|
||||
Timber.w("failed sending status", throwable)
|
||||
failOrRetry(throwable, statusId)
|
||||
},)
|
||||
})
|
||||
stopSelfWhenDone()
|
||||
}
|
||||
}
|
||||
|
@ -480,7 +480,8 @@ data class StatusToSend(
|
|||
@Parcelize
|
||||
data class MediaToSend(
|
||||
val localId: Int,
|
||||
val id: String?, // null if media is not yet completely uploaded
|
||||
// null if media is not yet completely uploaded
|
||||
val id: String?,
|
||||
val uri: String,
|
||||
val description: String?,
|
||||
val focus: Attachment.Focus?,
|
||||
|
|
|
@ -5,10 +5,10 @@ import app.pachli.core.accounts.AccountManager
|
|||
import app.pachli.core.common.di.ApplicationScope
|
||||
import app.pachli.core.database.model.AccountEntity
|
||||
import app.pachli.core.preferences.PrefKeys
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class AccountPreferenceDataStore @Inject constructor(
|
||||
private val accountManager: AccountManager,
|
||||
|
|
|
@ -35,7 +35,10 @@ inline fun PreferenceParent.listPreference(builder: ListPreference.() -> Unit):
|
|||
return pref
|
||||
}
|
||||
|
||||
inline fun <A> PreferenceParent.emojiPreference(activity: A, builder: EmojiPickerPreference.() -> Unit): EmojiPickerPreference
|
||||
inline fun <A> PreferenceParent.emojiPreference(
|
||||
activity: A,
|
||||
builder: EmojiPickerPreference.() -> Unit,
|
||||
): EmojiPickerPreference
|
||||
where A : Context, A : ActivityResultRegistryOwner, A : LifecycleOwner {
|
||||
val pref = EmojiPickerPreference.get(activity)
|
||||
builder(pref)
|
||||
|
|
|
@ -39,8 +39,8 @@ import at.connyduck.calladapter.networkresult.NetworkResult
|
|||
import at.connyduck.calladapter.networkresult.fold
|
||||
import at.connyduck.calladapter.networkresult.onFailure
|
||||
import at.connyduck.calladapter.networkresult.onSuccess
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import timber.log.Timber
|
||||
|
||||
class TimelineCases @Inject constructor(
|
||||
private val mastodonApi: MastodonApi,
|
||||
|
@ -123,7 +123,7 @@ class TimelineCases @Inject constructor(
|
|||
}, { e ->
|
||||
Timber.w("Failed to change pin state", e)
|
||||
NetworkResult.failure(TimelineError(e.getServerErrorMessage()))
|
||||
},)
|
||||
})
|
||||
}
|
||||
|
||||
suspend fun voteInPoll(statusId: String, pollId: String, choices: List<Int>): NetworkResult<Poll> {
|
||||
|
|
|
@ -121,8 +121,6 @@ enum class UserRefreshState {
|
|||
|
||||
/** A refresh or prepend operation was [LoadState.Error] */
|
||||
ERROR,
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,7 +183,9 @@ fun Flow<CombinedLoadStates>.asRefreshState(): Flow<UserRefreshState> {
|
|||
refresh = when (loadState.refresh) {
|
||||
is LoadState.Loading -> if (refresh == UserRefreshState.WAITING) UserRefreshState.ACTIVE else refresh
|
||||
is LoadState.NotLoading -> if (refresh == UserRefreshState.ACTIVE) UserRefreshState.COMPLETE else refresh
|
||||
else -> { throw IllegalStateException("can't happen, LoadState.Error is already handled") }
|
||||
else -> {
|
||||
throw IllegalStateException("can't happen, LoadState.Error is already handled")
|
||||
}
|
||||
}
|
||||
|
||||
// Prepend can only transition to active if there is an active or complete refresh
|
||||
|
|
|
@ -17,13 +17,13 @@
|
|||
package app.pachli.util
|
||||
|
||||
import android.util.Base64
|
||||
import java.security.KeyPairGenerator
|
||||
import java.security.SecureRandom
|
||||
import java.security.Security
|
||||
import org.bouncycastle.jce.ECNamedCurveTable
|
||||
import org.bouncycastle.jce.interfaces.ECPrivateKey
|
||||
import org.bouncycastle.jce.interfaces.ECPublicKey
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
import java.security.KeyPairGenerator
|
||||
import java.security.SecureRandom
|
||||
import java.security.Security
|
||||
|
||||
object CryptoUtil {
|
||||
const val CURVE_PRIME256_V1 = "prime256v1"
|
||||
|
|
|
@ -55,7 +55,13 @@ fun CharSequence.emojify(emojis: List<Emoji>?, view: View, animate: Boolean): Ch
|
|||
builder.setSpan(span, matcher.start(), matcher.end(), 0)
|
||||
Glide.with(view)
|
||||
.asDrawable()
|
||||
.load(if (animate) { url } else { staticUrl })
|
||||
.load(
|
||||
if (animate) {
|
||||
url
|
||||
} else {
|
||||
staticUrl
|
||||
},
|
||||
)
|
||||
.into(span.getTarget(animate))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
|
||||
package app.pachli.util
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.TimeMark
|
||||
import kotlin.time.TimeSource
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
|
||||
/**
|
||||
* Returns a flow that mirrors the original flow, but filters out values that occur within
|
||||
|
|
|
@ -48,10 +48,10 @@ import com.mikepenz.iconics.IconicsSize
|
|||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||
import com.mikepenz.iconics.utils.color
|
||||
import com.mikepenz.iconics.utils.size
|
||||
import timber.log.Timber
|
||||
import java.lang.ref.WeakReference
|
||||
import java.net.URI
|
||||
import java.net.URISyntaxException
|
||||
import timber.log.Timber
|
||||
|
||||
fun getDomain(urlString: String?): String {
|
||||
val host = urlString?.toUri()?.host ?: return ""
|
||||
|
|
|
@ -19,8 +19,8 @@ package app.pachli.util
|
|||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import app.pachli.core.database.model.AccountEntity
|
||||
import timber.log.Timber
|
||||
import java.util.Locale
|
||||
import timber.log.Timber
|
||||
|
||||
private const val TAG: String = "LocaleUtils"
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import android.graphics.Matrix
|
|||
import android.net.Uri
|
||||
import android.provider.OpenableColumns
|
||||
import androidx.exifinterface.media.ExifInterface
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
|
@ -32,6 +31,7 @@ import java.text.SimpleDateFormat
|
|||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Helper methods for obtaining and resizing media files
|
||||
|
|
|
@ -4,9 +4,9 @@ sealed interface Resource<T> {
|
|||
val data: T?
|
||||
}
|
||||
|
||||
class Loading<T> (override val data: T? = null) : Resource<T>
|
||||
class Loading<T>(override val data: T? = null) : Resource<T>
|
||||
|
||||
class Success<T> (override val data: T? = null) : Resource<T>
|
||||
class Success<T>(override val data: T? = null) : Resource<T>
|
||||
|
||||
class Error<T>(
|
||||
override val data: T? = null,
|
||||
|
|
|
@ -43,7 +43,8 @@ private val finders = mapOf(
|
|||
FoundMatchType.HTTP_URL to PatternFinder(':', HTTP_URL_REGEX, 5, Character::isWhitespace),
|
||||
FoundMatchType.HTTPS_URL to PatternFinder(':', HTTPS_URL_REGEX, 6, Character::isWhitespace),
|
||||
FoundMatchType.TAG to PatternFinder('#', TAG_REGEX, 1, ::isValidForTagPrefix),
|
||||
FoundMatchType.MENTION to PatternFinder('@', MENTION_REGEX, 1, Character::isWhitespace), // TODO: We also need a proper validator for mentions
|
||||
// TODO: We also need a proper validator for mentions
|
||||
FoundMatchType.MENTION to PatternFinder('@', MENTION_REGEX, 1, Character::isWhitespace),
|
||||
)
|
||||
|
||||
private enum class FoundMatchType {
|
||||
|
|
|
@ -28,6 +28,8 @@ import app.pachli.core.preferences.SharedPreferencesRepository
|
|||
import app.pachli.network.ServerCapabilitiesRepository
|
||||
import app.pachli.settings.AccountPreferenceDataStore
|
||||
import io.github.z4kn4fein.semver.constraints.toConstraint
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
@ -35,8 +37,6 @@ import kotlinx.coroutines.flow.filter
|
|||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Repository for [StatusDisplayOptions], exposed through the [flow] property.
|
||||
|
@ -125,7 +125,9 @@ class StatusDisplayOptionsRepository @Inject constructor(
|
|||
PrefKeys.SHOW_STATS_INLINE -> prev.copy(
|
||||
showStatsInline = sharedPreferencesRepository.getBoolean(key, default.showStatsInline),
|
||||
)
|
||||
else -> { prev }
|
||||
else -> {
|
||||
prev
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +148,9 @@ class StatusDisplayOptionsRepository @Inject constructor(
|
|||
PrefKeys.MEDIA_PREVIEW_ENABLED -> prev.copy(mediaPreviewEnabled = value)
|
||||
PrefKeys.ALWAYS_SHOW_SENSITIVE_MEDIA -> prev.copy(showSensitiveMedia = value)
|
||||
PrefKeys.ALWAYS_OPEN_SPOILER -> prev.copy(openSpoiler = value)
|
||||
else -> { prev }
|
||||
else -> {
|
||||
prev
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@ package app.pachli.util
|
|||
|
||||
import android.content.Context
|
||||
import app.pachli.R
|
||||
import java.io.IOException
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* checks if this throwable indicates an error causes by a 4xx/5xx server response and
|
||||
|
|
|
@ -38,10 +38,10 @@ import androidx.appcompat.widget.AppCompatTextView
|
|||
import androidx.core.view.doOnLayout
|
||||
import app.pachli.BuildConfig
|
||||
import app.pachli.R
|
||||
import timber.log.Timber
|
||||
import java.lang.Float.max
|
||||
import java.lang.Float.min
|
||||
import kotlin.math.abs
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Displays text to the user with optional [ClickableSpan]s. Extends the touchable area of the spans
|
||||
|
|
|
@ -62,7 +62,7 @@ class SliderPreference @JvmOverloads constructor(
|
|||
* @see Slider.getValue
|
||||
* @see Slider.setValue
|
||||
*/
|
||||
var value: Float = defaultValue
|
||||
var value: Float = DEFAULT_VALUE
|
||||
get() = _value
|
||||
set(v) {
|
||||
val clamped = max(max(v, valueFrom), min(v, valueTo))
|
||||
|
@ -85,7 +85,7 @@ class SliderPreference @JvmOverloads constructor(
|
|||
* Format string to be applied to values before setting the summary. For more control set
|
||||
* [SliderPreference.formatter]
|
||||
*/
|
||||
var format: String = defaultFormat
|
||||
var format: String = DEFAULT_FORMAT
|
||||
|
||||
/**
|
||||
* Function that will be used to format the summary. The default formatter formats using the
|
||||
|
@ -115,11 +115,11 @@ class SliderPreference @JvmOverloads constructor(
|
|||
|
||||
val a = context.obtainStyledAttributes(attrs, R.styleable.SliderPreference, defStyleAttr, defStyleRes)
|
||||
|
||||
value = a.getFloat(R.styleable.SliderPreference_android_value, defaultValue)
|
||||
valueFrom = a.getFloat(R.styleable.SliderPreference_android_valueFrom, defaultValueFrom)
|
||||
valueTo = a.getFloat(R.styleable.SliderPreference_android_valueTo, defaultValueTo)
|
||||
stepSize = a.getFloat(R.styleable.SliderPreference_android_stepSize, defaultStepSize)
|
||||
format = a.getString(R.styleable.SliderPreference_format) ?: defaultFormat
|
||||
value = a.getFloat(R.styleable.SliderPreference_android_value, DEFAULT_VALUE)
|
||||
valueFrom = a.getFloat(R.styleable.SliderPreference_android_valueFrom, DEFAULT_VALUE_FROM)
|
||||
valueTo = a.getFloat(R.styleable.SliderPreference_android_valueTo, DEFAULT_VALUE_TO)
|
||||
stepSize = a.getFloat(R.styleable.SliderPreference_android_stepSize, DEFAULT_STEP_SIZE)
|
||||
format = a.getString(R.styleable.SliderPreference_format) ?: DEFAULT_FORMAT
|
||||
|
||||
val decrementIconResource = a.getResourceId(R.styleable.SliderPreference_iconStart, -1)
|
||||
if (decrementIconResource != -1) {
|
||||
|
@ -135,11 +135,11 @@ class SliderPreference @JvmOverloads constructor(
|
|||
}
|
||||
|
||||
override fun onGetDefaultValue(a: TypedArray, i: Int): Any {
|
||||
return a.getFloat(i, defaultValue)
|
||||
return a.getFloat(i, DEFAULT_VALUE)
|
||||
}
|
||||
|
||||
override fun onSetInitialValue(defaultValue: Any?) {
|
||||
value = getPersistedFloat((defaultValue ?: Companion.defaultValue) as Float)
|
||||
value = getPersistedFloat((defaultValue ?: Companion.DEFAULT_VALUE) as Float)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: PreferenceViewHolder) {
|
||||
|
@ -195,10 +195,10 @@ class SliderPreference @JvmOverloads constructor(
|
|||
}
|
||||
|
||||
companion object {
|
||||
private const val defaultValueFrom = 0F
|
||||
private const val defaultValueTo = 1F
|
||||
private const val defaultValue = 0.5F
|
||||
private const val defaultStepSize = 0.1F
|
||||
private const val defaultFormat = "%3.1f"
|
||||
private const val DEFAULT_VALUE_FROM = 0F
|
||||
private const val DEFAULT_VALUE_TO = 1F
|
||||
private const val DEFAULT_VALUE = 0.5F
|
||||
private const val DEFAULT_STEP_SIZE = 0.1F
|
||||
private const val DEFAULT_FORMAT = "%3.1f"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,12 +66,12 @@ data class StatusViewData(
|
|||
*/
|
||||
val isDetailed: Boolean = false,
|
||||
|
||||
/** Whether this status should be filtered, and if so, how */
|
||||
// TODO: This means that null checks are required elsewhere in the code to deal with
|
||||
// the possibility that this might not be NONE, but that status.filtered is null or
|
||||
// empty (e.g., StatusBaseViewHolder.setupFilterPlaceholder()). It would be better
|
||||
// if the Filter.Action class subtypes carried the FilterResult information with them,
|
||||
// and it's impossible to construct them with an empty list.
|
||||
/** Whether this status should be filtered, and if so, how */
|
||||
var filterAction: Filter.Action = Filter.Action.NONE,
|
||||
|
||||
/** True if the translated content should be shown (if it exists) */
|
||||
|
@ -90,12 +90,15 @@ data class StatusViewData(
|
|||
|
||||
private val _content: Spanned
|
||||
|
||||
@Suppress("ktlint:standard:property-naming")
|
||||
private val _translatedContent: Spanned
|
||||
|
||||
val content: Spanned
|
||||
get() = if (translationState == TranslationState.SHOW_TRANSLATION) _translatedContent else _content
|
||||
|
||||
private val _spoilerText: String
|
||||
|
||||
@Suppress("ktlint:standard:property-naming")
|
||||
private val _translatedSpoilerText: String
|
||||
|
||||
/** The content warning, may be the empty string */
|
||||
|
@ -251,7 +254,8 @@ data class StatusViewData(
|
|||
isExpanded = conversationStatusEntity.expanded,
|
||||
isShowingContent = conversationStatusEntity.showingHiddenContent,
|
||||
isCollapsed = conversationStatusEntity.collapsed,
|
||||
translationState = TranslationState.SHOW_ORIGINAL, // TODO: Include this in conversationStatusEntity
|
||||
// TODO: Include translationState in conversationStatusEntity
|
||||
translationState = TranslationState.SHOW_ORIGINAL,
|
||||
)
|
||||
|
||||
fun from(
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue