update ktlint plugin to 11.3.1, format code (#3442)

This commit is contained in:
Konrad Pozniak 2023-03-13 13:16:39 +01:00 committed by GitHub
parent 774d79d666
commit d839f18267
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
141 changed files with 589 additions and 428 deletions

View file

@ -51,7 +51,6 @@ class AboutActivity : BottomSheetActivity(), Injectable {
}
private fun TextView.setClickableTextWithoutUnderlines(@StringRes textId: Int) {
val text = SpannableString(context.getText(textId))
Linkify.addLinks(text, Linkify.WEB_URLS)

View file

@ -153,12 +153,14 @@ class AccountsInListFragment : DialogFragment(), Injectable {
if (error is IOException) {
binding.messageView.setup(
R.drawable.elephant_offline,
R.string.error_network, retryAction
R.string.error_network,
retryAction
)
} else {
binding.messageView.setup(
R.drawable.elephant_error,
R.string.error_generic, retryAction
R.string.error_generic,
retryAction
)
}
}

View file

@ -177,5 +177,5 @@ abstract class BottomSheetActivity : BaseActivity() {
enum class PostLookupFallbackBehavior {
OPEN_IN_BROWSER,
DISPLAY_ERROR,
DISPLAY_ERROR
}

View file

@ -136,7 +136,6 @@ class EditProfileActivity : BaseActivity(), Injectable {
is Success -> {
val me = profileRes.data
if (me != null) {
binding.displayNameEditText.setText(me.displayName)
binding.noteEditText.setText(me.source?.note)
binding.lockedCheckBox.isChecked = me.locked

View file

@ -44,7 +44,6 @@ class LicenseActivity : BaseActivity() {
}
private fun loadFileIntoTextView(@RawRes fileId: Int, textView: TextView) {
val sb = StringBuilder()
val br = BufferedReader(InputStreamReader(resources.openRawResource(fileId)))

View file

@ -134,8 +134,11 @@ class ListsActivity : BaseActivity(), Injectable, HasAndroidInjector {
val dialog = AlertDialog.Builder(this)
.setView(layout)
.setPositiveButton(
if (list == null) R.string.action_create_list
else R.string.action_rename_list
if (list == null) {
R.string.action_create_list
} else {
R.string.action_rename_list
}
) { _, _ ->
onPickedDialogName(editText.text, list?.id)
}
@ -181,7 +184,8 @@ class ListsActivity : BaseActivity(), Injectable, HasAndroidInjector {
if (state.lists.isEmpty()) {
binding.messageView.show()
binding.messageView.setup(
R.drawable.elephant_friend_empty, R.string.message_empty,
R.drawable.elephant_friend_empty,
R.string.message_empty,
null
)
} else {
@ -192,7 +196,9 @@ class ListsActivity : BaseActivity(), Injectable, HasAndroidInjector {
private fun showMessage(@StringRes messageId: Int) {
Snackbar.make(
binding.listsRecycler, messageId, Snackbar.LENGTH_SHORT
binding.listsRecycler,
messageId,
Snackbar.LENGTH_SHORT
).show()
}

View file

@ -215,7 +215,8 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
} else {
// No account was provided, show the chooser
showAccountChooserDialog(
getString(R.string.action_share_as), true,
getString(R.string.action_share_as),
true,
object : AccountSelectionListener {
override fun onAccountSelected(account: AccountEntity) {
val requestedId = account.id
@ -295,7 +296,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
is MainTabsChangedEvent -> {
refreshMainDrawerItems(
addSearchButton = hideTopToolbar,
addTrendingButton = !event.newTabs.hasTab(TRENDING),
addTrendingButton = !event.newTabs.hasTab(TRENDING)
)
setupTabs(false)
@ -407,7 +408,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
// FIXME: blackberry keyONE raises SHIFT key event even CTRL IS PRESSED
when (keyCode) {
KeyEvent.KEYCODE_N -> {
// open compose activity by pressing SHIFT + N (or CTRL + N)
val composeIntent = Intent(applicationContext, ComposeActivity::class.java)
startActivity(composeIntent)
@ -444,7 +444,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
addSearchButton: Boolean,
addTrendingButton: Boolean
) {
val drawerOpenClickListener = View.OnClickListener { binding.mainDrawerLayout.open() }
binding.mainToolbar.setNavigationOnClickListener(drawerOpenClickListener)
@ -881,7 +880,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
}
private fun loadDrawerAvatar(avatarUrl: String, showPlaceholder: Boolean) {
val hideTopToolbar = preferences.getBoolean(PrefKeys.HIDE_TOP_TOOLBAR, false)
val animateAvatars = preferences.getBoolean("animateGifAvatars", false)
@ -909,7 +907,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
.into(avatarView)
}
} else {
binding.bottomNavAvatar.hide()
binding.topNavAvatar.hide()
@ -1040,7 +1037,9 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
header.setActiveProfile(accountManager.activeAccount!!.id)
binding.mainToolbar.subtitle = if (accountManager.shouldDisplaySelfUsername(this)) {
accountManager.activeAccount!!.fullName
} else null
} else {
null
}
}
override fun getActionButton() = binding.composeButton

View file

@ -225,7 +225,7 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
title = "#$tag",
context = listOf(FilterV1.HOME),
filterAction = Filter.Action.WARN.action,
expiresInSeconds = null,
expiresInSeconds = null
).fold(
{ filter ->
if (mastodonApi.addFilterKeyword(filterId = filter.id, keyword = tag, wholeWord = true).isSuccess) {
@ -276,7 +276,7 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
// This filter exists in multiple contexts, just remove the home context
mastodonApi.updateFilter(
id = filter.id,
context = filter.context.filter { it != Filter.Kind.HOME.kind },
context = filter.context.filter { it != Filter.Kind.HOME.kind }
)
} else {
mastodonApi.deleteFilter(filter.id)
@ -291,7 +291,7 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
context = filter.context.filter { it != FilterV1.HOME },
irreversible = null,
wholeWord = null,
expiresInSeconds = null,
expiresInSeconds = null
)
} else {
mastodonApi.deleteFilterV1(filter.id)

View file

@ -59,6 +59,7 @@ class TabPreferenceActivity : BaseActivity(), Injectable, ItemInteractionListene
@Inject
lateinit var mastodonApi: MastodonApi
@Inject
lateinit var eventHub: EventHub
@ -161,7 +162,6 @@ class TabPreferenceActivity : BaseActivity(), Injectable, ItemInteractionListene
}
override fun onTabAdded(tab: TabData) {
if (currentTabs.size >= MAX_TAB_COUNT) {
return
}
@ -223,7 +223,6 @@ class TabPreferenceActivity : BaseActivity(), Injectable, ItemInteractionListene
}
private fun showAddHashtagDialog(tab: TabData? = null, tabPosition: Int = 0) {
val frameLayout = FrameLayout(this)
val padding = Utils.dpToPx(this, 8)
frameLayout.updatePadding(left = padding, right = padding)

View file

@ -306,8 +306,9 @@ class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener
isCreating = false
invalidateOptionsMenu()
binding.progressBarShare.visibility = View.GONE
if (result)
if (result) {
shareFile(file, "image/png")
}
},
{ error ->
isCreating = false

View file

@ -26,7 +26,6 @@ import com.keylesspalace.tusky.entity.MastoList
class ListSelectionAdapter(context: Context) : ArrayAdapter<MastoList>(context, R.layout.item_picker_list) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val binding = if (convertView == null) {
ItemPickerListBinding.inflate(LayoutInflater.from(context), parent, false)
} else {

View file

@ -75,7 +75,6 @@ class PollAdapter : RecyclerView.Adapter<BindingHolder<ItemPollBinding>>() {
override fun getItemCount() = pollOptions.size
override fun onBindViewHolder(holder: BindingHolder<ItemPollBinding>, position: Int) {
val option = pollOptions[position]
val resultTextView = holder.binding.statusPollOptionResult

View file

@ -35,7 +35,7 @@ import java.util.Date
class ReportNotificationViewHolder(
private val binding: ItemReportNotificationBinding,
private val notificationActionListener: NotificationActionListener,
private val notificationActionListener: NotificationActionListener
) : NotificationsPagingAdapter.ViewHolder, RecyclerView.ViewHolder(binding.root) {
override fun bind(

View file

@ -24,7 +24,7 @@ import java.util.Locale
import java.util.TimeZone
class TrendingDateViewHolder(
private val binding: ItemTrendingDateBinding,
private val binding: ItemTrendingDateBinding
) : RecyclerView.ViewHolder(binding.root) {
private val dateFormat = SimpleDateFormat("EEE dd MMM yyyy", Locale.getDefault()).apply {

View file

@ -32,7 +32,7 @@ class TrendingTagViewHolder(
fun setup(
tagViewData: TrendingViewData.Tag,
maxTrendingValue: Long,
trendingListener: LinkListener,
trendingListener: LinkListener
) {
val reversedHistory = tagViewData.tag.history.reversed()
setGraph(reversedHistory, maxTrendingValue)

View file

@ -107,8 +107,10 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvide
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Any>
@Inject
lateinit var viewModelFactory: ViewModelFactory
@Inject
lateinit var draftsAlert: DraftsAlert
@ -134,14 +136,18 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvide
// fields for scroll animation
private var hideFab: Boolean = false
private var oldOffset: Int = 0
@ColorInt
private var toolbarColor: Int = 0
@ColorInt
private var statusBarColorTransparent: Int = 0
@ColorInt
private var statusBarColorOpaque: Int = 0
private var avatarSize: Float = 0f
@Px
private var titleVisibleHeight: Int = 0
private lateinit var domain: String
@ -342,7 +348,6 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvide
binding.accountAppBarLayout.addOnOffsetChangedListener(object : AppBarLayout.OnOffsetChangedListener {
override fun onOffsetChanged(appBarLayout: AppBarLayout, verticalOffset: Int) {
if (verticalOffset == oldOffset) {
return
}
@ -650,11 +655,12 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvide
binding.accountSubscribeButton.setOnClickListener {
viewModel.changeSubscribingState()
}
if (relation.notifying != null)
if (relation.notifying != null) {
subscribing = relation.notifying
else if (relation.subscribing != null)
} else if (relation.subscribing != null) {
subscribing = relation.subscribing
}
}
// remove the listener so it doesn't fire on non-user changes
binding.accountNoteTextInputLayout.editText?.removeTextChangedListener(noteWatcher)
@ -717,7 +723,6 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvide
invalidateOptionsMenu()
if (loadedAccount?.moved == null) {
binding.accountFollowButton.show()
updateFollowButton()
updateSubscribeButton()
@ -750,7 +755,6 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvide
}
if (!viewModel.isSelf) {
val block = menu.findItem(R.id.action_block)
block.title = if (blocking) {
getString(R.string.action_unblock)
@ -908,7 +912,8 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvide
R.id.action_open_as -> {
loadedAccount?.let { loadedAccount ->
showAccountChooserDialog(
item.title, false,
item.title,
false,
object : AccountSelectionListener {
override fun onAccountSelected(account: AccountEntity) {
openAsAccount(loadedAccount.url, account)
@ -979,7 +984,9 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvide
override fun getActionButton(): FloatingActionButton? {
return if (!blocking) {
binding.accountFloatingActionButton
} else null
} else {
null
}
}
private fun getFullUsername(account: Account): String {

View file

@ -80,7 +80,6 @@ class AccountViewModel @Inject constructor(
private fun obtainRelationship(reload: Boolean = false) {
if (relationshipData.value == null || reload) {
relationshipData.postValue(Loading())
mastodonApi.relationships(listOf(accountId))
@ -209,14 +208,18 @@ class AccountViewModel @Inject constructor(
RelationShipAction.MUTE -> relation.copy(muting = true)
RelationShipAction.UNMUTE -> relation.copy(muting = false)
RelationShipAction.SUBSCRIBE -> {
if (isMastodon)
if (isMastodon) {
relation.copy(notifying = true)
else relation.copy(subscribing = true)
} else {
relation.copy(subscribing = true)
}
}
RelationShipAction.UNSUBSCRIBE -> {
if (isMastodon)
if (isMastodon) {
relation.copy(notifying = false)
else relation.copy(subscribing = false)
} else {
relation.copy(subscribing = false)
}
}
}
relationshipData.postValue(Loading(newRelation))
@ -238,14 +241,18 @@ class AccountViewModel @Inject constructor(
)
RelationShipAction.UNMUTE -> mastodonApi.unmuteAccount(accountId)
RelationShipAction.SUBSCRIBE -> {
if (isMastodon)
if (isMastodon) {
mastodonApi.followAccount(accountId, notify = true)
else mastodonApi.subscribeAccount(accountId)
} else {
mastodonApi.subscribeAccount(accountId)
}
}
RelationShipAction.UNSUBSCRIBE -> {
if (isMastodon)
if (isMastodon) {
mastodonApi.followAccount(accountId, notify = false)
else mastodonApi.unsubscribeAccount(accountId)
} else {
mastodonApi.unsubscribeAccount(accountId)
}
}
}
@ -294,14 +301,16 @@ class AccountViewModel @Inject constructor(
}
private fun reload(isReload: Boolean = false) {
if (isDataLoading)
if (isDataLoading) {
return
}
accountId.let {
obtainAccount(isReload)
if (!isSelf)
if (!isSelf) {
obtainRelationship(isReload)
}
}
}
fun setAccountInfo(accountId: String) {
this.accountId = accountId

View file

@ -65,7 +65,7 @@ class ListsForAccountFragment : DialogFragment(), Injectable {
dialog?.apply {
window?.setLayout(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
}
}
@ -172,7 +172,7 @@ class ListsForAccountFragment : DialogFragment(), Injectable {
ListAdapter<AccountListState, BindingHolder<ItemAddOrRemoveFromListBinding>>(Differ) {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
viewType: Int
): BindingHolder<ItemAddOrRemoveFromListBinding> {
val binding =
ItemAddOrRemoveFromListBinding.inflate(LayoutInflater.from(parent.context), parent, false)

View file

@ -35,23 +35,23 @@ import javax.inject.Inject
data class AccountListState(
val list: MastoList,
val includesAccount: Boolean,
val includesAccount: Boolean
)
data class ActionError(
val error: Throwable,
val type: Type,
val listId: String,
val listId: String
) : Throwable(error) {
enum class Type {
ADD,
REMOVE,
REMOVE
}
}
@OptIn(ExperimentalCoroutinesApi::class)
class ListsForAccountViewModel @Inject constructor(
private val mastodonApi: MastodonApi,
private val mastodonApi: MastodonApi
) : ViewModel() {
private lateinit var accountId: String
@ -75,14 +75,14 @@ class ListsForAccountViewModel @Inject constructor(
runCatching {
val (all, includes) = listOf(
async { mastodonApi.getLists() },
async { mastodonApi.getListsIncludesAccount(accountId) },
async { mastodonApi.getListsIncludesAccount(accountId) }
).awaitAll()
_states.emit(
all.getOrThrow().map { list ->
AccountListState(
list = list,
includesAccount = includes.getOrThrow().any { it.id == list.id },
includesAccount = includes.getOrThrow().any { it.id == list.id }
)
}
)

View file

@ -26,7 +26,6 @@ class AccountMediaPagingSource(
override fun getRefreshKey(state: PagingState<String, AttachmentViewData>): String? = null
override suspend fun load(params: LoadParams<String>): LoadResult<String, AttachmentViewData> {
return if (params is LoadParams.Refresh) {
val list = viewModel.attachmentData.toList()
LoadResult.Page(list, null, list.lastOrNull()?.statusId)

View file

@ -34,7 +34,6 @@ class AccountMediaRemoteMediator(
loadType: LoadType,
state: PagingState<String, AttachmentViewData>
): MediatorResult {
try {
val statusResponse = when (loadType) {
LoadType.REFRESH -> {

View file

@ -63,6 +63,7 @@ class AccountListFragment : Fragment(R.layout.fragment_account_list), AccountAct
@Inject
lateinit var api: MastodonApi
@Inject
lateinit var accountManager: AccountManager
@ -83,7 +84,6 @@ class AccountListFragment : Fragment(R.layout.fragment_account_list), AccountAct
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding.recyclerView.setHasFixedSize(true)
val layoutManager = LinearLayoutManager(view.context)
binding.recyclerView.layoutManager = layoutManager
@ -227,7 +227,6 @@ class AccountListFragment : Fragment(R.layout.fragment_account_list), AccountAct
accountId: String,
position: Int
) {
if (accept) {
api.authorizeFollowRequest(accountId)
} else {

View file

@ -61,7 +61,7 @@ abstract class AccountAdapter<AVH : RecyclerView.ViewHolder> internal constructo
}
private fun createFooterViewHolder(
parent: ViewGroup,
parent: ViewGroup
): RecyclerView.ViewHolder {
val binding = ItemFooterBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return BindingHolder(binding)

View file

@ -30,7 +30,7 @@ class BlocksAdapter(
accountActionListener: AccountActionListener,
animateAvatar: Boolean,
animateEmojis: Boolean,
showBotOverlay: Boolean,
showBotOverlay: Boolean
) : AccountAdapter<BindingHolder<ItemBlockedUserBinding>>(
accountActionListener = accountActionListener,
animateAvatar = animateAvatar,

View file

@ -36,7 +36,9 @@ class FollowRequestsAdapter(
override fun createAccountViewHolder(parent: ViewGroup): FollowRequestViewHolder {
val binding = ItemFollowRequestBinding.inflate(
LayoutInflater.from(parent.context), parent, false
LayoutInflater.from(parent.context),
parent,
false
)
return FollowRequestViewHolder(
binding,

View file

@ -107,8 +107,7 @@ class AnnouncementsViewModel @Inject constructor(
} else {
listOf(
*announcement.reactions.toTypedArray(),
emojis.value!!.find { emoji -> emoji.shortcode == name }
!!.run {
emojis.value!!.find { emoji -> emoji.shortcode == name }!!.run {
Announcement.Reaction(
name,
1,

View file

@ -812,7 +812,8 @@ class ComposeActivity :
}
private fun onMediaPick() {
addMediaBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
addMediaBehavior.addBottomSheetCallback(
object : BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
// Wait until bottom sheet is not collapsed and show next screen after
if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
@ -953,7 +954,6 @@ class ComposeActivity :
binding.composeEditField.error = getString(R.string.error_empty)
enableButtons(true, viewModel.editing)
} else if (characterCount <= maximumTootCharacters) {
lifecycleScope.launch {
viewModel.sendStatus(contentText, spoilerText)
deleteDraftAndFinish()
@ -972,7 +972,8 @@ class ComposeActivity :
pickMediaFile.launch(true)
} else {
Snackbar.make(
binding.activityCompose, R.string.error_media_upload_permission,
binding.activityCompose,
R.string.error_media_upload_permission,
Snackbar.LENGTH_SHORT
).apply {
setAction(R.string.action_retry) { onMediaPick() }
@ -1006,9 +1007,13 @@ class ComposeActivity :
private fun enableButton(button: ImageButton, clickable: Boolean, colorActive: Boolean) {
button.isEnabled = clickable
setDrawableTint(
this, button.drawable,
if (colorActive) android.R.attr.textColorTertiary
else R.attr.textColorDisabled
this,
button.drawable,
if (colorActive) {
android.R.attr.textColorTertiary
} else {
R.attr.textColorDisabled
}
)
}
@ -1016,8 +1021,11 @@ class ComposeActivity :
binding.addPollTextActionTextView.isEnabled = enable
val textColor = MaterialColors.getColor(
binding.addPollTextActionTextView,
if (enable) android.R.attr.textColorTertiary
else R.attr.textColorDisabled
if (enable) {
android.R.attr.textColorTertiary
} else {
R.attr.textColorDisabled
}
)
binding.addPollTextActionTextView.setTextColor(textColor)
binding.addPollTextActionTextView.compoundDrawablesRelative[0].colorFilter = PorterDuffColorFilter(textColor, PorterDuff.Mode.SRC_IN)
@ -1193,8 +1201,11 @@ class ComposeActivity :
lifecycleScope.launch {
val dialog = if (viewModel.shouldShowSaveDraftDialog()) {
ProgressDialog.show(
this@ComposeActivity, null,
getString(R.string.saving_draft), true, false
this@ComposeActivity,
null,
getString(R.string.saving_draft),
true,
false
)
} else {
null

View file

@ -274,7 +274,7 @@ class ComposeViewModel @Inject constructor(
failedToSendAlert = false,
scheduledAt = scheduledAt.value,
language = postLanguage,
statusId = originalStatusId,
statusId = originalStatusId
)
}
@ -286,7 +286,6 @@ class ComposeViewModel @Inject constructor(
content: String,
spoilerText: String
) {
if (!scheduledTootId.isNullOrEmpty()) {
api.deleteScheduledStatus(scheduledTootId!!)
}
@ -405,7 +404,6 @@ class ComposeViewModel @Inject constructor(
}
fun setup(composeOptions: ComposeActivity.ComposeOptions?) {
if (setupComplete) {
return
}
@ -440,7 +438,8 @@ class ComposeViewModel @Inject constructor(
pickMedia(attachment.uri, attachment.description, attachment.focus)
}
}
} else composeOptions?.mediaAttachments?.forEach { a ->
} else {
composeOptions?.mediaAttachments?.forEach { a ->
// when coming from redraft or ScheduledTootActivity
val mediaType = when (a.type) {
Attachment.Type.VIDEO, Attachment.Type.GIFV -> QueuedMedia.Type.VIDEO
@ -449,6 +448,7 @@ class ComposeViewModel @Inject constructor(
}
addUploadedMedia(a.id, mediaType, a.url.toUri(), a.description, a.meta?.focus)
}
}
draftId = composeOptions?.draftId ?: 0
scheduledTootId = composeOptions?.scheduledTootId

View file

@ -41,7 +41,6 @@ fun downsizeImage(
contentResolver: ContentResolver,
tempFile: File
): Boolean {
val decodeBoundsInputStream = try {
contentResolver.openInputStream(uri)
} catch (e: FileNotFoundException) {

View file

@ -90,10 +90,11 @@ class MediaPreviewAdapter(
val imageView = holder.progressImageView
val focus = item.focus
if (focus != null)
if (focus != null) {
imageView.setFocalPoint(focus)
else
} else {
imageView.removeFocalPoint() // Probably unnecessary since we have no UI for removal once added.
}
var glide = Glide.with(holder.itemView.context)
.load(item.uri)
@ -101,8 +102,9 @@ class MediaPreviewAdapter(
.dontAnimate()
.centerInside()
if (focus != null)
if (focus != null) {
glide = glide.addListener(imageView)
}
glide.into(imageView)
}

View file

@ -159,7 +159,6 @@ class MediaUploader @Inject constructor(
try {
when (inUri.scheme) {
ContentResolver.SCHEME_CONTENT -> {
mimeType = contentResolver.getType(uri)
val suffix = "." + MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType ?: "tmp")
@ -278,7 +277,8 @@ class MediaUploader @Inject constructor(
var lastProgress = -1
val fileBody = ProgressRequestBody(
stream!!, media.mediaSize,
stream!!,
media.mediaSize,
mimeType.toMediaTypeOrNull()!!
) { percentage ->
if (percentage != lastProgress) {

View file

@ -35,7 +35,6 @@ fun showAddPollDialog(
maxDuration: Int,
onUpdatePoll: (NewPoll) -> Unit
) {
val binding = DialogAddPollBinding.inflate(LayoutInflater.from(context))
val dialog = AlertDialog.Builder(context)

View file

@ -67,7 +67,8 @@ class CaptionDialog : DialogFragment() {
input = EditText(context)
input.hint = resources.getQuantityString(
R.plurals.hint_describe_for_visually_impaired,
MEDIA_DESCRIPTION_CHARACTER_LIMIT, MEDIA_DESCRIPTION_CHARACTER_LIMIT
MEDIA_DESCRIPTION_CHARACTER_LIMIT,
MEDIA_DESCRIPTION_CHARACTER_LIMIT
)
dialogLayout.addView(input)
(input.layoutParams as LinearLayout.LayoutParams).setMargins(margin, margin, margin, margin)
@ -105,7 +106,7 @@ class CaptionDialog : DialogFragment() {
override fun onResourceReady(
resource: Drawable,
transition: Transition<in Drawable>?,
transition: Transition<in Drawable>?
) {
imageView.setImageDrawable(resource)
}
@ -122,7 +123,7 @@ class CaptionDialog : DialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
savedInstanceState: Bundle?
): View? {
savedInstanceState?.getString(DESCRIPTION_KEY)?.let {
input.setText(it)
@ -143,12 +144,12 @@ class CaptionDialog : DialogFragment() {
fun newInstance(
localId: Int,
existingDescription: String?,
previewUri: Uri,
previewUri: Uri
) = CaptionDialog().apply {
arguments = bundleOf(
LOCAL_ID_ARG to localId,
EXISTING_DESCRIPTION_ARG to existingDescription,
PREVIEW_URI_ARG to previewUri,
PREVIEW_URI_ARG to previewUri
)
}

View file

@ -27,15 +27,17 @@ class FocusIndicatorView
fun setImageSize(width: Int, height: Int) {
this.imageSize = Point(width, height)
if (focus != null)
if (focus != null) {
invalidate()
}
}
fun setFocus(focus: Attachment.Focus) {
this.focus = focus
if (imageSize != null)
if (imageSize != null) {
invalidate()
}
}
// Assumes setFocus called first
fun getFocus(): Attachment.Focus {
@ -46,8 +48,9 @@ class FocusIndicatorView
// so base it on the view width/height whenever the first access occurs.
private fun getCircleRadius(): Float {
val circleRadius = this.circleRadius
if (circleRadius != null)
if (circleRadius != null) {
return circleRadius
}
val newCircleRadius = min(this.width, this.height).toFloat() / 4.0f
this.circleRadius = newCircleRadius
return newCircleRadius
@ -67,8 +70,9 @@ class FocusIndicatorView
@SuppressLint("ClickableViewAccessibility") // Android Studio wants us to implement PerformClick for accessibility, but that unfortunately cannot be made meaningful for this widget.
override fun onTouchEvent(event: MotionEvent): Boolean {
if (event.actionMasked == MotionEvent.ACTION_CANCEL)
if (event.actionMasked == MotionEvent.ACTION_CANCEL) {
return false
}
val imageSize = this.imageSize ?: return false

View file

@ -48,7 +48,6 @@ class TootButton
fun setStatusVisibility(visibility: Status.Visibility) {
if (!smallStyle) {
icon = when (visibility) {
Status.Visibility.PUBLIC -> {
setText(R.string.action_send_public)

View file

@ -66,7 +66,7 @@ data class ConversationAccountEntity(
displayName = displayName,
url = "",
avatar = avatar,
emojis = emojis,
emojis = emojis
)
}
}
@ -96,7 +96,7 @@ data class ConversationStatusEntity(
val collapsed: Boolean,
val muted: Boolean,
val poll: Poll?,
val language: String?,
val language: String?
) {
fun toViewData(): StatusViewData.Concrete {
@ -130,11 +130,11 @@ data class ConversationStatusEntity(
poll = poll,
card = null,
language = language,
filtered = null,
filtered = null
),
isExpanded = expanded,
isShowingContent = showingHiddenContent,
isCollapsed = collapsed,
isCollapsed = collapsed
)
}
}
@ -178,7 +178,7 @@ fun Status.toEntity(
collapsed = contentCollapsed,
muted = muted ?: false,
poll = poll,
language = language,
language = language
)
fun Conversation.toEntity(

View file

@ -87,6 +87,6 @@ fun StatusViewData.Concrete.toConversationStatusEntity(
collapsed = collapsed,
muted = muted,
poll = poll,
language = status.language,
language = status.language
)
}

View file

@ -15,7 +15,7 @@ import retrofit2.HttpException
class ConversationsRemoteMediator(
private val api: MastodonApi,
private val db: AppDatabase,
accountManager: AccountManager,
accountManager: AccountManager
) : RemoteMediator<Int, ConversationEntity>() {
private var nextKey: String? = null
@ -28,7 +28,6 @@ class ConversationsRemoteMediator(
loadType: LoadType,
state: PagingState<Int, ConversationEntity>
): MediatorResult {
if (loadType == LoadType.PREPEND) {
return MediatorResult.Success(endOfPaginationReached = true)
}
@ -47,7 +46,6 @@ class ConversationsRemoteMediator(
}
db.withTransaction {
if (loadType == LoadType.REFRESH) {
db.conversationDao().deleteForAccount(activeAccount.id)
}

View file

@ -66,7 +66,7 @@ class DraftHelper @Inject constructor(
failedToSendAlert: Boolean,
scheduledAt: String?,
language: String?,
statusId: String?,
statusId: String?
) = withContext(Dispatchers.IO) {
val externalFilesDir = context.getExternalFilesDir("Tusky")
@ -127,7 +127,7 @@ class DraftHelper @Inject constructor(
failedToSendNew = failedToSendAlert,
scheduledAt = scheduledAt,
language = language,
statusId = statusId,
statusId = statusId
)
draftDao.insertOrReplace(draft)

View file

@ -51,18 +51,20 @@ class DraftMediaAdapter(
holder.imageView.clearFocus()
holder.imageView.setImageResource(R.drawable.ic_music_box_preview_24dp)
} else {
if (attachment.focus != null)
if (attachment.focus != null) {
holder.imageView.setFocalPoint(attachment.focus)
else
} else {
holder.imageView.clearFocus()
}
var glide = Glide.with(holder.itemView.context)
.load(attachment.uri)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.dontAnimate()
.centerInside()
if (attachment.focus != null)
if (attachment.focus != null) {
glide = glide.addListener(holder.imageView)
}
glide.into(holder.imageView)
}

View file

@ -48,7 +48,6 @@ class DraftsAdapter(
) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingHolder<ItemDraftBinding> {
val binding = ItemDraftBinding.inflate(LayoutInflater.from(parent.context), parent, false)
val viewHolder = BindingHolder(binding)

View file

@ -55,7 +55,7 @@ class EditFilterActivity : BaseActivity() {
filterContextNotifications to Filter.Kind.NOTIFICATIONS,
filterContextPublic to Filter.Kind.PUBLIC,
filterContextThread to Filter.Kind.THREAD,
filterContextAccount to Filter.Kind.ACCOUNT,
filterContextAccount to Filter.Kind.ACCOUNT
)
}
@ -213,7 +213,7 @@ class EditFilterActivity : BaseActivity() {
FilterKeyword(
"",
binding.phraseEditText.text.toString(),
binding.phraseWholeWord.isChecked,
binding.phraseWholeWord.isChecked
)
)
}
@ -234,7 +234,7 @@ class EditFilterActivity : BaseActivity() {
keyword,
keyword.copy(
keyword = binding.phraseEditText.text.toString(),
wholeWord = binding.phraseWholeWord.isChecked,
wholeWord = binding.phraseWholeWord.isChecked
)
)
}

View file

@ -98,7 +98,7 @@ class EditFilterViewModel @Inject constructor(val api: MastodonApi, val eventHub
title = title,
context = contexts,
filterAction = action,
expiresInSeconds = expiresInSeconds,
expiresInSeconds = expiresInSeconds
).fold(
{ newFilter ->
// This is _terrible_, but the all-in-one update filter api Just Doesn't Work
@ -123,7 +123,7 @@ class EditFilterViewModel @Inject constructor(val api: MastodonApi, val eventHub
title = title,
context = contexts,
filterAction = action,
expiresInSeconds = expiresInSeconds,
expiresInSeconds = expiresInSeconds
).fold(
{
// This is _terrible_, but the all-in-one update filter api Just Doesn't Work
@ -175,7 +175,7 @@ class EditFilterViewModel @Inject constructor(val api: MastodonApi, val eventHub
context = context,
irreversible = false,
wholeWord = keyword.wholeWord,
expiresInSeconds = expiresInSeconds,
expiresInSeconds = expiresInSeconds
)
}
}

View file

@ -62,7 +62,7 @@ class FiltersViewModel @Inject constructor(
},
{
Snackbar.make(parent, "Error deleting filter '${filter.title}'", Snackbar.LENGTH_SHORT).show()
},
}
)
} else {
Snackbar.make(parent, "Error deleting filter '${filter.title}'", Snackbar.LENGTH_SHORT).show()

View file

@ -13,7 +13,7 @@ import com.keylesspalace.tusky.util.BindingHolder
class FollowedTagsAdapter(
private val actionListener: HashtagActionListener,
private val viewModel: FollowedTagsViewModel,
private val viewModel: FollowedTagsViewModel
) : PagingDataAdapter<String, BindingHolder<ItemFollowedHashtagBinding>>(STRING_COMPARATOR) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingHolder<ItemFollowedHashtagBinding> =
BindingHolder(ItemFollowedHashtagBinding.inflate(LayoutInflater.from(parent.context), parent, false))

View file

@ -13,7 +13,7 @@ import retrofit2.Response
@OptIn(ExperimentalPagingApi::class)
class FollowedTagsRemoteMediator(
private val api: MastodonApi,
private val viewModel: FollowedTagsViewModel,
private val viewModel: FollowedTagsViewModel
) : RemoteMediator<String, String>() {
override suspend fun load(
loadType: LoadType,

View file

@ -30,8 +30,9 @@ class DomainMutesAdapter(
override fun getItemCount(): Int {
var count = instances.size
if (bottomLoading)
if (bottomLoading) {
++count
}
return count
}

View file

@ -99,7 +99,8 @@ class LoginActivity : BaseActivity(), Injectable {
}
preferences = getSharedPreferences(
getString(R.string.preferences_file_key), Context.MODE_PRIVATE
getString(R.string.preferences_file_key),
Context.MODE_PRIVATE
)
binding.loginButton.setOnClickListener { onLoginClick(true) }
@ -168,8 +169,11 @@ class LoginActivity : BaseActivity(), Injectable {
lifecycleScope.launch {
mastodonApi.authenticateApp(
domain, getString(R.string.app_name), oauthRedirectUri,
OAUTH_SCOPES, getString(R.string.tusky_website)
domain,
getString(R.string.app_name),
oauthRedirectUri,
OAUTH_SCOPES,
getString(R.string.tusky_website)
).fold(
{ credentials ->
// Before we open browser page we save the data.
@ -273,7 +277,12 @@ class LoginActivity : BaseActivity(), Injectable {
setLoading(true)
mastodonApi.fetchOAuthToken(
domain, clientId, clientSecret, oauthRedirectUri, code, "authorization_code"
domain,
clientId,
clientSecret,
oauthRedirectUri,
code,
"authorization_code"
).fold(
{ accessToken ->
fetchAccountDetails(accessToken, domain, clientId, clientSecret)
@ -293,7 +302,6 @@ class LoginActivity : BaseActivity(), Injectable {
clientId: String,
clientSecret: String
) {
mastodonApi.accountVerifyCredentials(
domain = domain,
auth = "Bearer ${accessToken.accessToken}"
@ -349,6 +357,7 @@ class LoginActivity : BaseActivity(), Injectable {
const val MODE_DEFAULT = 0
const val MODE_ADDITIONAL_LOGIN = 1
// "Migration" is used to update the OAuth scope granted to the client
const val MODE_MIGRATION = 2

View file

@ -85,7 +85,7 @@ class OauthLogin : ActivityResultContract<LoginData, LoginResult>() {
data class LoginData(
val domain: String,
val url: Uri,
val oauthRedirectUrl: Uri,
val oauthRedirectUrl: Uri
) : Parcelable
sealed class LoginResult : Parcelable {

View file

@ -30,7 +30,7 @@ import com.keylesspalace.tusky.viewdata.NotificationViewData
class FollowViewHolder(
private val binding: ItemFollowBinding,
private val notificationActionListener: NotificationActionListener,
private val notificationActionListener: NotificationActionListener
) : NotificationsPagingAdapter.ViewHolder, RecyclerView.ViewHolder(binding.root) {
private val avatarRadius42dp = itemView.context.resources.getDimensionPixelSize(
R.dimen.avatar_radius_42dp

View file

@ -14,6 +14,7 @@
* see <http://www.gnu.org/licenses>. */
@file:JvmName("PushNotificationHelper")
package com.keylesspalace.tusky.components.notifications
import android.app.NotificationManager
@ -163,7 +164,6 @@ suspend fun registerUnifiedPushEndpoint(
account: AccountEntity,
endpoint: String
) = withContext(Dispatchers.IO) {
// Generate a prime256v1 key pair for WebPush
// Decryption is unimplemented for now, since Mastodon uses an old WebPush
// standard which does not send needed information for decryption in the payload
@ -173,8 +173,11 @@ suspend fun registerUnifiedPushEndpoint(
val auth = CryptoUtil.secureRandomBytesEncoded(16)
api.subscribePushNotifications(
"Bearer ${account.accessToken}", account.domain,
endpoint, keyPair.pubkey, auth,
"Bearer ${account.accessToken}",
account.domain,
endpoint,
keyPair.pubkey,
auth,
buildSubscriptionData(context, account)
).onFailure { throwable ->
Log.w(TAG, "Error setting push endpoint for account ${account.id}", throwable)
@ -195,7 +198,8 @@ suspend fun registerUnifiedPushEndpoint(
suspend fun updateUnifiedPushSubscription(context: Context, api: MastodonApi, accountManager: AccountManager, account: AccountEntity) {
withContext(Dispatchers.IO) {
api.updatePushNotificationSubscription(
"Bearer ${account.accessToken}", account.domain,
"Bearer ${account.accessToken}",
account.domain,
buildSubscriptionData(context, account)
).onSuccess {
Log.d(TAG, "UnifiedPush subscription updated for account ${account.id}")

View file

@ -300,7 +300,6 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(), Injectable {
override fun onResponse(call: Call<Account>, response: Response<Account>) {
val account = response.body()
if (response.isSuccessful && account != null) {
accountManager.activeAccount?.let {
it.defaultPostPrivacy = account.source?.privacy
?: Status.Visibility.PUBLIC

View file

@ -85,8 +85,11 @@ class StatusViewHolder(
val sensitive = viewData.status.sensitive
statusViewHelper.setMediasPreview(
statusDisplayOptions, viewData.status.attachments,
sensitive, previewListener, viewState.isMediaShow(viewData.id, viewData.status.sensitive),
statusDisplayOptions,
viewData.status.attachments,
sensitive,
previewListener,
viewState.isMediaShow(viewData.id, viewData.status.sensitive),
mediaViewHeight
)
@ -97,8 +100,10 @@ class StatusViewHolder(
private fun updateTextView() {
viewdata()?.let { viewdata ->
setupCollapsedState(
shouldTrimStatus(viewdata.content), viewState.isCollapsed(viewdata.id, true),
viewState.isContentShow(viewdata.id, viewdata.status.sensitive), viewdata.spoilerText
shouldTrimStatus(viewdata.content),
viewState.isCollapsed(viewdata.id, true),
viewState.isContentShow(viewdata.id, viewdata.status.sensitive),
viewdata.spoilerText
)
if (viewdata.spoilerText.isBlank()) {

View file

@ -38,7 +38,10 @@ class StatusesAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StatusViewHolder {
val binding = ItemReportStatusBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return StatusViewHolder(
binding, statusDisplayOptions, statusViewState, adapterHandler,
binding,
statusDisplayOptions,
statusViewState,
adapterHandler,
statusForPosition
)
}

View file

@ -72,8 +72,9 @@ class ReportNoteFragment : Fragment(R.layout.fragment_report_note), Injectable {
binding.reportDescriptionRemoteInstance.hide()
}
if (viewModel.isRemoteAccount)
if (viewModel.isRemoteAccount) {
binding.checkIsNotifyRemote.text = getString(R.string.report_remote_instance, viewModel.remoteServer)
}
binding.checkIsNotifyRemote.isChecked = viewModel.isRemoteNotify
}

View file

@ -54,7 +54,6 @@ class SearchPagingSource<T : Any>(
val currentKey = params.key ?: 0
try {
val data = mastodonApi.searchObservable(
query = searchRequest,
type = searchType.apiParameter,

View file

@ -133,7 +133,8 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status
Attachment.Type.GIFV, Attachment.Type.VIDEO, Attachment.Type.IMAGE, Attachment.Type.AUDIO -> {
val attachments = AttachmentViewData.list(actionable)
val intent = ViewMediaActivity.newIntent(
context, attachments,
context,
attachments,
attachmentIndex
)
if (view != null) {
@ -141,7 +142,8 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status
ViewCompat.setTransitionName(view, url)
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(
requireActivity(),
view, url
view,
url
)
startActivity(intent, options.toBundle())
} else {
@ -399,7 +401,8 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status
private fun showOpenAsDialog(statusUrl: String, dialogTitle: CharSequence?) {
bottomSheetActivity?.showAccountChooserDialog(
dialogTitle, false,
dialogTitle,
false,
object : AccountSelectionListener {
override fun onAccountSelected(account: AccountEntity) {
bottomSheetActivity?.openAsAccount(statusUrl, account)
@ -515,7 +518,7 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status
language = status.language,
statusId = source.id,
poll = status.poll?.toNewPoll(status.createdAt),
kind = ComposeActivity.ComposeKind.EDIT_POSTED,
kind = ComposeActivity.ComposeKind.EDIT_POSTED
)
startActivity(ComposeActivity.startIntent(requireContext(), composeOptions))
},

View file

@ -170,7 +170,7 @@ class TimelineFragment :
viewModel.init(
kind,
id,
tags,
tags
)
isSwipeToRefreshEnabled = arguments.getBoolean(ARG_ENABLE_SWIPE_TO_REFRESH, true)
@ -188,7 +188,11 @@ class TimelineFragment :
PrefKeys.SHOW_CARDS_IN_TIMELINES,
false
)
) CardViewMode.INDENTED else CardViewMode.NONE,
) {
CardViewMode.INDENTED
} else {
CardViewMode.NONE
},
confirmReblogs = preferences.getBoolean(PrefKeys.CONFIRM_REBLOGS, true),
confirmFavourites = preferences.getBoolean(PrefKeys.CONFIRM_FAVOURITES, false),
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false),
@ -255,7 +259,9 @@ class TimelineFragment :
if (getView() != null) {
if (isSwipeToRefreshEnabled) {
binding.recyclerView.scrollBy(0, Utils.dpToPx(requireContext(), -30))
} else binding.recyclerView.scrollToPosition(0)
} else {
binding.recyclerView.scrollToPosition(0)
}
}
}
}

View file

@ -131,9 +131,11 @@ class TimelinePagingAdapter(
return if (oldItem == newItem) {
// If items are equal - update timestamp only
listOf(StatusBaseViewHolder.Key.KEY_CREATED)
} else // If items are different - update the whole view holder
} else {
// If items are different - update the whole view holder
null
}
}
}
}
}

View file

@ -105,7 +105,7 @@ fun Placeholder.toEntity(timelineUserId: Long): TimelineStatusEntity {
card = null,
repliesCount = 0,
language = null,
filtered = null,
filtered = null
)
}
@ -150,7 +150,7 @@ fun Status.toEntity(
card = actionableStatus.card?.let(gson::toJson),
repliesCount = actionableStatus.repliesCount,
language = actionableStatus.language,
filtered = actionableStatus.filtered,
filtered = actionableStatus.filtered
)
}
@ -198,7 +198,7 @@ fun TimelineStatusWithAccount.toViewData(gson: Gson, isDetailed: Boolean = false
card = card,
repliesCount = status.repliesCount,
language = status.language,
filtered = status.filtered,
filtered = status.filtered
)
}
val status = if (reblog != null) {
@ -231,7 +231,7 @@ fun TimelineStatusWithAccount.toViewData(gson: Gson, isDetailed: Boolean = false
card = null,
repliesCount = status.repliesCount,
language = status.language,
filtered = status.filtered,
filtered = status.filtered
)
} else {
Status(
@ -263,7 +263,7 @@ fun TimelineStatusWithAccount.toViewData(gson: Gson, isDetailed: Boolean = false
card = card,
repliesCount = status.repliesCount,
language = status.language,
filtered = status.filtered,
filtered = status.filtered
)
}
return StatusViewData.Concrete(

View file

@ -49,7 +49,6 @@ class CachedTimelineRemoteMediator(
loadType: LoadType,
state: PagingState<Int, TimelineStatusWithAccount>
): MediatorResult {
if (!activeAccount.isLoggedIn()) {
return MediatorResult.Success(endOfPaginationReached = true)
}

View file

@ -204,7 +204,6 @@ class CachedTimelineViewModel @Inject constructor(
}
db.withTransaction {
timelineDao.delete(activeAccount.id, placeholderId)
val overlappedStatuses = if (statuses.isNotEmpty()) {

View file

@ -26,7 +26,6 @@ class NetworkTimelinePagingSource(
override fun getRefreshKey(state: PagingState<String, StatusViewData>): String? = null
override suspend fun load(params: LoadParams<String>): LoadResult<String, StatusViewData> {
return if (params is LoadParams.Refresh) {
val list = viewModel.statusData.toList()
LoadResult.Page(list, null, viewModel.nextKey)

View file

@ -36,7 +36,6 @@ class NetworkTimelineRemoteMediator(
loadType: LoadType,
state: PagingState<String, StatusViewData>
): MediatorResult {
try {
val statusResponse = when (loadType) {
LoadType.REFRESH -> {
@ -80,7 +79,6 @@ class NetworkTimelineRemoteMediator(
}
if (loadType == LoadType.REFRESH && viewModel.statusData.isNotEmpty()) {
val insertPlaceholder = if (statuses.isNotEmpty()) {
!viewModel.statusData.removeAll { statusViewData ->
statuses.any { status -> status.id == statusViewData.asStatusOrNull()?.id }

View file

@ -183,7 +183,7 @@ class NetworkTimelineViewModel @Inject constructor(
.copy(
isShowingContent = oldStatus!!.isShowingContent,
isExpanded = oldStatus.isExpanded,
isCollapsed = oldStatus.isCollapsed,
isCollapsed = oldStatus.isCollapsed
)
}

View file

@ -302,7 +302,7 @@ abstract class TimelineViewModel(
} else {
Log.e(TAG, "Error getting filters", throwable)
}
},
}
)
}
}

View file

@ -28,7 +28,7 @@ import com.keylesspalace.tusky.interfaces.LinkListener
import com.keylesspalace.tusky.viewdata.TrendingViewData
class TrendingAdapter(
private val trendingListener: LinkListener,
private val trendingListener: LinkListener
) : ListAdapter<TrendingViewData, RecyclerView.ViewHolder>(TrendingDifferCallback) {
init {

View file

@ -95,7 +95,7 @@ class TrendingFragment :
super.onCreate(savedInstanceState)
adapter = TrendingAdapter(
this,
this
)
}
@ -208,7 +208,8 @@ class TrendingFragment :
binding.recyclerView.hide()
binding.messageView.show()
binding.messageView.setup(
R.drawable.elephant_friend_empty, R.string.message_empty,
R.drawable.elephant_friend_empty,
R.string.message_empty,
null
)
} else {
@ -242,7 +243,7 @@ class TrendingFragment :
binding.swipeRefreshLayout.isRefreshing = false
binding.messageView.setup(
R.drawable.elephant_offline,
R.string.error_network,
R.string.error_network
) { refreshContent() }
}
@ -254,7 +255,7 @@ class TrendingFragment :
binding.swipeRefreshLayout.isRefreshing = false
binding.messageView.setup(
R.drawable.elephant_error,
R.string.error_generic,
R.string.error_generic
) { refreshContent() }
}

View file

@ -93,9 +93,11 @@ class ThreadAdapter(
return if (oldItem == newItem) {
// If items are equal - update timestamp only
listOf(StatusBaseViewHolder.Key.KEY_CREATED)
} else // If items are different - update the whole view holder
} else {
// If items are different - update the whole view holder
null
}
}
}
}
}

View file

@ -167,7 +167,7 @@ class ViewThreadViewModel @Inject constructor(
_uiState.value = ThreadUiState.Success(
statusViewData = listOf(detailedStatus),
detailedStatusPosition = 0,
revealButton = RevealButtonState.NO_BUTTON,
revealButton = RevealButtonState.NO_BUTTON
)
})
}

View file

@ -82,7 +82,7 @@ data class AccountEntity(
var pushPubKey: String = "",
var pushPrivKey: String = "",
var pushAuth: String = "",
var pushServerKey: String = "",
var pushServerKey: String = ""
) {
val identifier: String

View file

@ -66,7 +66,6 @@ class AccountManager @Inject constructor(db: AppDatabase) {
oauthScopes: String,
newAccount: Account
) {
activeAccount?.let {
it.isActive = false
Log.d(TAG, "addAccount: saving account with id " + it.id)
@ -121,7 +120,6 @@ class AccountManager @Inject constructor(db: AppDatabase) {
* @return the new active account, or null if no other account was found
*/
fun logActiveAccountOut(): AccountEntity? {
return activeAccount?.let { account ->
account.logout()
@ -167,7 +165,6 @@ class AccountManager @Inject constructor(db: AppDatabase) {
* @param accountId the database id of the new active account
*/
fun setActiveAccount(accountId: Long) {
val newActiveAccount = accounts.find { (id) ->
id == accountId
} ?: return // invalid accountId passed, do nothing
@ -237,10 +234,12 @@ class AccountManager @Inject constructor(db: AppDatabase) {
fun shouldDisplaySelfUsername(context: Context): Boolean {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
val showUsernamePreference = sharedPreferences.getString(PrefKeys.SHOW_SELF_USERNAME, "disambiguate")
if (showUsernamePreference == "always")
if (showUsernamePreference == "always") {
return true
if (showUsernamePreference == "never")
}
if (showUsernamePreference == "never") {
return false
}
return accounts.size > 1 // "disambiguate"
}

View file

@ -43,7 +43,7 @@ data class DraftEntity(
val failedToSendNew: Boolean,
val scheduledAt: String?,
val language: String?,
val statusId: String?,
val statusId: String?
)
/**

View file

@ -85,7 +85,7 @@ data class TimelineStatusEntity(
val pinned: Boolean,
val card: String?,
val language: String?,
val filtered: List<FilterResult>?,
val filtered: List<FilterResult>?
) {
val isPlaceholder: Boolean
get() = this.authorServerId == null

View file

@ -68,7 +68,7 @@ class AppModule {
AppDatabase.MIGRATION_38_39, AppDatabase.MIGRATION_39_40, AppDatabase.MIGRATION_40_41,
AppDatabase.MIGRATION_41_42, AppDatabase.MIGRATION_42_43, AppDatabase.MIGRATION_43_44,
AppDatabase.MIGRATION_44_45, AppDatabase.MIGRATION_45_46, AppDatabase.MIGRATION_46_47,
AppDatabase.MIGRATION_47_48,
AppDatabase.MIGRATION_47_48
)
.build()
}

View file

@ -43,7 +43,9 @@ data class Account(
val name: String
get() = if (displayName.isNullOrEmpty()) {
localUsername
} else displayName
} else {
displayName
}
fun isRemote(): Boolean = this.username != this.localUsername
}
@ -53,7 +55,7 @@ data class AccountSource(
val sensitive: Boolean?,
val note: String?,
val fields: List<StringField>?,
val language: String?,
val language: String?
)
data class Field(

View file

@ -39,12 +39,16 @@ data class Attachment(
enum class Type {
@SerializedName("image")
IMAGE,
@SerializedName("gifv")
GIFV,
@SerializedName("video")
VIDEO,
@SerializedName("audio")
AUDIO,
@SerializedName("unknown")
UNKNOWN
}
@ -70,7 +74,7 @@ data class Attachment(
val focus: Focus?,
val duration: Float?,
val original: Size?,
val small: Size?,
val small: Size?
) : Parcelable
/**

View file

@ -28,7 +28,7 @@ data class DeletedStatus(
@SerializedName("media_attachments") val attachments: ArrayList<Attachment>?,
val poll: Poll?,
@SerializedName("created_at") val createdAt: Date,
val language: String?,
val language: String?
) {
fun isEmpty(): Boolean {
return text == null && attachments == null

View file

@ -12,7 +12,7 @@ data class Filter(
val context: List<String>,
@SerializedName("expires_at") val expiresAt: Date?,
@SerializedName("filter_action") private val filterAction: String,
val keywords: List<FilterKeyword>,
val keywords: List<FilterKeyword>
// val statuses: List<FilterStatus>,
) : Parcelable {
enum class Action(val action: String) {

View file

@ -8,5 +8,5 @@ import kotlinx.parcelize.Parcelize
data class FilterKeyword(
val id: String,
val keyword: String,
@SerializedName("whole_word") val wholeWord: Boolean,
@SerializedName("whole_word") val wholeWord: Boolean
) : Parcelable

View file

@ -5,5 +5,5 @@ import com.google.gson.annotations.SerializedName
data class FilterResult(
val filter: Filter,
@SerializedName("keyword_matches") val keywordMatches: List<String>?,
@SerializedName("status_matches") val statusMatches: String?,
@SerializedName("status_matches") val statusMatches: String?
)

View file

@ -57,7 +57,7 @@ data class FilterV1(
FilterKeyword(
id = id,
keyword = phrase,
wholeWord = wholeWord,
wholeWord = wholeWord
)
)
)

View file

@ -54,19 +54,19 @@ data class PollConfiguration(
@SerializedName("max_option_chars") val maxOptionChars: Int?,
@SerializedName("max_characters_per_option") val maxCharactersPerOption: Int?,
@SerializedName("min_expiration") val minExpiration: Int?,
@SerializedName("max_expiration") val maxExpiration: Int?,
@SerializedName("max_expiration") val maxExpiration: Int?
)
data class InstanceConfiguration(
val statuses: StatusConfiguration?,
@SerializedName("media_attachments") val mediaAttachments: MediaAttachmentConfiguration?,
val polls: PollConfiguration?,
val polls: PollConfiguration?
)
data class StatusConfiguration(
@SerializedName("max_characters") val maxCharacters: Int?,
@SerializedName("max_media_attachments") val maxMediaAttachments: Int?,
@SerializedName("characters_reserved_per_url") val charactersReservedPerUrl: Int?,
@SerializedName("characters_reserved_per_url") val charactersReservedPerUrl: Int?
)
data class MediaAttachmentConfiguration(
@ -75,7 +75,7 @@ data class MediaAttachmentConfiguration(
@SerializedName("image_matrix_limit") val imageMatrixLimit: Int?,
@SerializedName("video_size_limit") val videoSizeLimit: Int?,
@SerializedName("video_frame_rate_limit") val videoFrameRateLimit: Int?,
@SerializedName("video_matrix_limit") val videoMatrixLimit: Int?,
@SerializedName("video_matrix_limit") val videoMatrixLimit: Int?
)
data class PleromaConfiguration(

View file

@ -29,7 +29,7 @@ data class NewStatus(
@SerializedName("media_attributes") val mediaAttributes: List<MediaAttribute>?,
@SerializedName("scheduled_at") val scheduledAt: String?,
val poll: NewPoll?,
val language: String?,
val language: String?
)
@Parcelize
@ -46,5 +46,5 @@ data class MediaAttribute(
val id: String,
val description: String?,
val focus: String?,
val thumbnail: String?,
val thumbnail: String?
) : Parcelable

View file

@ -28,7 +28,7 @@ data class Notification(
val id: String,
val account: TimelineAccount,
val status: Status?,
val report: Report?,
val report: Report?
) {
/** From https://docs.joinmastodon.org/entities/Notification/#type */
@ -70,9 +70,10 @@ data class Notification(
@JvmStatic
fun byString(s: String): Type {
values().forEach {
if (s == it.presentation)
if (s == it.presentation) {
return it
}
}
return UNKNOWN
}
@ -115,7 +116,11 @@ data class Notification(
return if (status.mentions.any {
it.id == accountId
}
) this else copy(type = Type.STATUS)
) {
this
} else {
copy(type = Type.STATUS)
}
}
return this
}

View file

@ -20,5 +20,5 @@ import com.google.gson.annotations.SerializedName
data class NotificationSubscribeResult(
val id: Int,
val endpoint: String,
@SerializedName("server_key") val serverKey: String,
@SerializedName("server_key") val serverKey: String
)

View file

@ -8,5 +8,5 @@ data class Report(
val category: String,
val status_ids: List<String>?,
@SerializedName("created_at") val createdAt: Date,
@SerializedName("target_account") val targetAccount: TimelineAccount,
@SerializedName("target_account") val targetAccount: TimelineAccount
)

View file

@ -51,7 +51,7 @@ data class Status(
val poll: Poll?,
val card: Card?,
val language: String?,
val filtered: List<FilterResult>?,
val filtered: List<FilterResult>?
) {
val actionableId: String
@ -69,12 +69,16 @@ data class Status(
enum class Visibility(val num: Int) {
UNKNOWN(0),
@SerializedName("public")
PUBLIC(1),
@SerializedName("unlisted")
UNLISTED(2),
@SerializedName("private")
PRIVATE(3),
@SerializedName("direct")
DIRECT(4);
@ -134,7 +138,7 @@ data class Status(
attachments = attachments,
poll = poll,
createdAt = createdAt,
language = language,
language = language
)
}

View file

@ -20,5 +20,5 @@ import com.google.gson.annotations.SerializedName
data class StatusSource(
val id: String,
val text: String,
@SerializedName("spoiler_text") val spoilerText: String,
@SerializedName("spoiler_text") val spoilerText: String
)

View file

@ -29,11 +29,13 @@ data class TimelineAccount(
val url: String,
val avatar: String,
val bot: Boolean = false,
val emojis: List<Emoji>? = emptyList(), // nullable for backward compatibility
val emojis: List<Emoji>? = emptyList() // nullable for backward compatibility
) {
val name: String
get() = if (displayName.isNullOrEmpty()) {
localUsername
} else displayName
} else {
displayName
}
}

View file

@ -29,7 +29,7 @@ data class TrendingTag(
val name: String,
val url: String,
val history: List<TrendingTagHistory>,
val following: Boolean,
val following: Boolean
)
/**
@ -42,7 +42,7 @@ data class TrendingTag(
data class TrendingTagHistory(
val day: String,
val accounts: String,
val uses: String,
val uses: String
)
fun TrendingTag.start() = Date(history.last().day.toLong() * 1000L)

View file

@ -309,7 +309,6 @@ abstract class SFragment : Fragment(), Injectable {
}
private fun onMute(accountId: String, accountUsername: String) {
showMuteAccountDialog(this.requireActivity(), accountUsername) { notifications: Boolean?, duration: Int? ->
lifecycleScope.launch {
timelineCases.mute(accountId, notifications == true, duration)
@ -339,7 +338,8 @@ abstract class SFragment : Fragment(), Injectable {
view.transitionName = url
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(
requireActivity(),
view, url
view,
url
)
startActivity(intent, options.toBundle())
} else {

View file

@ -207,7 +207,7 @@ class ViewImageFragment : ViewMediaFragment() {
.dontAnimate()
.onlyRetrieveFromCache(true)
.let {
if (previewUrl != null)
if (previewUrl != null) {
it.thumbnail(
glide
.load(previewUrl)
@ -216,7 +216,9 @@ class ViewImageFragment : ViewMediaFragment() {
.centerInside()
.addListener(ImageRequestListener(true, isThumbnailRequest = true))
)
else it
} else {
it
}
}
// Request image from the network on fail load image from cache
.error(

View file

@ -42,6 +42,7 @@ abstract class ViewMediaFragment : Fragment() {
@JvmStatic
protected val ARG_ATTACHMENT = "attach"
@JvmStatic
protected val ARG_SINGLE_IMAGE_URL = "singleImageUrl"

View file

@ -108,7 +108,6 @@ internal fun String.parseIsoDate(): Date {
return GregorianCalendar(year, month - 1, day).time
}
if (hasT) {
// extract hours, minutes, seconds and milliseconds
hour = parseInt(this, 1.let { offset += it; offset }, 2.let { offset += it; offset })
if (checkOffset(this, offset, ':')) {

View file

@ -29,8 +29,9 @@ class FilterModel @Inject constructor() {
// Patterns are expensive and thread-safe, matchers are neither.
val matcher = pattern?.matcher("") ?: return Filter.Action.NONE
if (status.poll?.options?.any { matcher.reset(it.title).find() } == true)
if (status.poll?.options?.any { matcher.reset(it.title).find() } == true) {
return Filter.Action.HIDE
}
val spoilerText = status.actionableStatus.spoilerText
val attachmentsDescriptions = status.attachments.mapNotNull { it.description }

View file

@ -34,7 +34,6 @@ class InstanceSwitchAuthInterceptor(private val accountManager: AccountManager)
// only switch domains if the request comes from retrofit
return if (originalRequest.url.host == MastodonApi.PLACEHOLDER_DOMAIN) {
val builder: Request.Builder = originalRequest.newBuilder()
val instanceHeader = originalRequest.header(MastodonApi.DOMAIN_HEADER)

View file

@ -194,7 +194,7 @@ interface MastodonApi {
@Header("Authorization") auth: String,
@Header(DOMAIN_HEADER) domain: String,
@Header("Idempotency-Key") idempotencyKey: String,
@Body editedStatus: NewStatus,
@Body editedStatus: NewStatus
): NetworkResult<Status>
@GET("api/v1/statuses/{id}")
@ -298,7 +298,7 @@ interface MastodonApi {
@GET("api/v1/accounts/verify_credentials")
suspend fun accountVerifyCredentials(
@Header(DOMAIN_HEADER) domain: String? = null,
@Header("Authorization") auth: String? = null,
@Header("Authorization") auth: String? = null
): NetworkResult<Account>
@FormUrlEncoded
@ -306,7 +306,7 @@ interface MastodonApi {
fun accountUpdateSource(
@Field("source[privacy]") privacy: String?,
@Field("source[sensitive]") sensitive: Boolean?,
@Field("source[language]") language: String?,
@Field("source[language]") language: String?
): Call<Account>
@Multipart
@ -607,7 +607,7 @@ interface MastodonApi {
@Field("title") title: String,
@Field("context[]") context: List<String>,
@Field("filter_action") filterAction: String,
@Field("expires_in") expiresInSeconds: Int?,
@Field("expires_in") expiresInSeconds: Int?
): NetworkResult<Filter>
@FormUrlEncoded
@ -617,7 +617,7 @@ interface MastodonApi {
@Field("title") title: String? = null,
@Field("context[]") context: List<String>? = null,
@Field("filter_action") filterAction: String? = null,
@Field("expires_in") expiresInSeconds: Int? = null,
@Field("expires_in") expiresInSeconds: Int? = null
): NetworkResult<Filter>
@DELETE("api/v2/filters/{id}")
@ -630,7 +630,7 @@ interface MastodonApi {
suspend fun addFilterKeyword(
@Path("filterId") filterId: String,
@Field("keyword") keyword: String,
@Field("whole_word") wholeWord: Boolean,
@Field("whole_word") wholeWord: Boolean
): NetworkResult<FilterKeyword>
@FormUrlEncoded
@ -638,12 +638,12 @@ interface MastodonApi {
suspend fun updateFilterKeyword(
@Path("keywordId") keywordId: String,
@Field("keyword") keyword: String,
@Field("whole_word") wholeWord: Boolean,
@Field("whole_word") wholeWord: Boolean
): NetworkResult<FilterKeyword>
@DELETE("api/v2/filters/keywords/{keywordId}")
suspend fun deleteFilterKeyword(
@Path("keywordId") keywordId: String,
@Path("keywordId") keywordId: String
): NetworkResult<ResponseBody>
@FormUrlEncoded
@ -751,7 +751,7 @@ interface MastodonApi {
@DELETE("api/v1/push/subscription")
suspend fun unsubscribePushNotifications(
@Header("Authorization") auth: String,
@Header(DOMAIN_HEADER) domain: String,
@Header(DOMAIN_HEADER) domain: String
): NetworkResult<ResponseBody>
@GET("api/v1/tags/{name}")
@ -762,7 +762,7 @@ interface MastodonApi {
@Query("min_id") minId: String? = null,
@Query("since_id") sinceId: String? = null,
@Query("max_id") maxId: String? = null,
@Query("limit") limit: Int? = null,
@Query("limit") limit: Int? = null
): Response<List<HashTag>>
@POST("api/v1/tags/{name}/follow")

View file

@ -97,7 +97,7 @@ class SendStatusBroadcastReceiver : BroadcastReceiver() {
idempotencyKey = randomAlphanumericString(16),
retries = 0,
language = null,
statusId = null,
statusId = null
)
)

View file

@ -53,12 +53,16 @@ class SendStatusService : Service(), Injectable {
@Inject
lateinit var mastodonApi: MastodonApi
@Inject
lateinit var accountManager: AccountManager
@Inject
lateinit var eventHub: EventHub
@Inject
lateinit var draftHelper: DraftHelper
@Inject
lateinit var mediaUploader: MediaUploader
@ -111,7 +115,6 @@ class SendStatusService : Service(), Injectable {
statusesToSend[sendingNotificationId] = statusToSend
sendStatus(sendingNotificationId--)
} else {
if (intent.hasExtra(KEY_CANCEL)) {
cancelSending(intent.getIntExtra(KEY_CANCEL, 0))
}
@ -121,7 +124,6 @@ class SendStatusService : Service(), Injectable {
}
private fun sendStatus(statusId: Int) {
// when statusToSend == null, sending has been canceled
val statusToSend = statusesToSend[statusId] ?: return
@ -138,7 +140,6 @@ class SendStatusService : Service(), Injectable {
statusToSend.retries++
sendJobs[statusId] = serviceScope.launch {
// first, wait for media uploads to finish
val media = statusToSend.media.map { mediaItem ->
if (mediaItem.id == null) {
@ -174,7 +175,7 @@ class SendStatusService : Service(), Injectable {
}
}
}
mediaCheckRetries ++
mediaCheckRetries++
}
} catch (e: Exception) {
Log.w(TAG, "failed getting media status", e)
@ -198,9 +199,9 @@ class SendStatusService : Service(), Injectable {
id = media.id!!,
description = media.description,
focus = media.focus?.toMastodonApiString(),
thumbnail = null,
thumbnail = null
)
},
}
)
val editing = (statusToSend.statusId != null)
@ -266,7 +267,6 @@ class SendStatusService : Service(), Injectable {
}
private fun stopSelfWhenDone() {
if (statusesToSend.isEmpty()) {
ServiceCompat.stopForeground(this@SendStatusService, ServiceCompat.STOP_FOREGROUND_REMOVE)
stopSelf()
@ -276,7 +276,6 @@ class SendStatusService : Service(), Injectable {
private suspend fun failSending(statusId: Int) {
val failedStatus = statusesToSend.remove(statusId)
if (failedStatus != null) {
mediaUploader.cancelUploadScope(*failedStatus.media.map { it.localId }.toIntArray())
saveStatusToDrafts(failedStatus, failedToSendAlert = true)
@ -296,7 +295,6 @@ class SendStatusService : Service(), Injectable {
private fun cancelSending(statusId: Int) = serviceScope.launch {
val statusToCancel = statusesToSend.remove(statusId)
if (statusToCancel != null) {
mediaUploader.cancelUploadScope(*statusToCancel.media.map { it.localId }.toIntArray())
val sendJob = sendJobs.remove(statusId)
@ -336,7 +334,7 @@ class SendStatusService : Service(), Injectable {
failedToSendAlert = failedToSendAlert,
scheduledAt = status.scheduledAt,
language = status.language,
statusId = status.statusId,
statusId = status.statusId
)
}
@ -357,7 +355,6 @@ class SendStatusService : Service(), Injectable {
accountId: Long,
statusId: Int
): Notification {
val intent = Intent(this, MainActivity::class.java)
intent.putExtra(NotificationHelper.ACCOUNT_ID, accountId)
intent.putExtra(MainActivity.OPEN_DRAFTS, true)
@ -442,7 +439,7 @@ data class StatusToSend(
val idempotencyKey: String,
var retries: Int,
val language: String?,
val statusId: String?,
val statusId: String?
) : Parcelable
@Parcelize

Some files were not shown because too many files have changed in this diff Show more