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) { private fun TextView.setClickableTextWithoutUnderlines(@StringRes textId: Int) {
val text = SpannableString(context.getText(textId)) val text = SpannableString(context.getText(textId))
Linkify.addLinks(text, Linkify.WEB_URLS) Linkify.addLinks(text, Linkify.WEB_URLS)

View file

@ -153,12 +153,14 @@ class AccountsInListFragment : DialogFragment(), Injectable {
if (error is IOException) { if (error is IOException) {
binding.messageView.setup( binding.messageView.setup(
R.drawable.elephant_offline, R.drawable.elephant_offline,
R.string.error_network, retryAction R.string.error_network,
retryAction
) )
} else { } else {
binding.messageView.setup( binding.messageView.setup(
R.drawable.elephant_error, 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 { enum class PostLookupFallbackBehavior {
OPEN_IN_BROWSER, OPEN_IN_BROWSER,
DISPLAY_ERROR, DISPLAY_ERROR
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -306,8 +306,9 @@ class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener
isCreating = false isCreating = false
invalidateOptionsMenu() invalidateOptionsMenu()
binding.progressBarShare.visibility = View.GONE binding.progressBarShare.visibility = View.GONE
if (result) if (result) {
shareFile(file, "image/png") shareFile(file, "image/png")
}
}, },
{ error -> { error ->
isCreating = false 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) { class ListSelectionAdapter(context: Context) : ArrayAdapter<MastoList>(context, R.layout.item_picker_list) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val binding = if (convertView == null) { val binding = if (convertView == null) {
ItemPickerListBinding.inflate(LayoutInflater.from(context), parent, false) ItemPickerListBinding.inflate(LayoutInflater.from(context), parent, false)
} else { } else {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -35,23 +35,23 @@ import javax.inject.Inject
data class AccountListState( data class AccountListState(
val list: MastoList, val list: MastoList,
val includesAccount: Boolean, val includesAccount: Boolean
) )
data class ActionError( data class ActionError(
val error: Throwable, val error: Throwable,
val type: Type, val type: Type,
val listId: String, val listId: String
) : Throwable(error) { ) : Throwable(error) {
enum class Type { enum class Type {
ADD, ADD,
REMOVE, REMOVE
} }
} }
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
class ListsForAccountViewModel @Inject constructor( class ListsForAccountViewModel @Inject constructor(
private val mastodonApi: MastodonApi, private val mastodonApi: MastodonApi
) : ViewModel() { ) : ViewModel() {
private lateinit var accountId: String private lateinit var accountId: String
@ -75,14 +75,14 @@ class ListsForAccountViewModel @Inject constructor(
runCatching { runCatching {
val (all, includes) = listOf( val (all, includes) = listOf(
async { mastodonApi.getLists() }, async { mastodonApi.getLists() },
async { mastodonApi.getListsIncludesAccount(accountId) }, async { mastodonApi.getListsIncludesAccount(accountId) }
).awaitAll() ).awaitAll()
_states.emit( _states.emit(
all.getOrThrow().map { list -> all.getOrThrow().map { list ->
AccountListState( AccountListState(
list = list, 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 fun getRefreshKey(state: PagingState<String, AttachmentViewData>): String? = null
override suspend fun load(params: LoadParams<String>): LoadResult<String, AttachmentViewData> { override suspend fun load(params: LoadParams<String>): LoadResult<String, AttachmentViewData> {
return if (params is LoadParams.Refresh) { return if (params is LoadParams.Refresh) {
val list = viewModel.attachmentData.toList() val list = viewModel.attachmentData.toList()
LoadResult.Page(list, null, list.lastOrNull()?.statusId) LoadResult.Page(list, null, list.lastOrNull()?.statusId)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -27,14 +27,16 @@ class FocusIndicatorView
fun setImageSize(width: Int, height: Int) { fun setImageSize(width: Int, height: Int) {
this.imageSize = Point(width, height) this.imageSize = Point(width, height)
if (focus != null) if (focus != null) {
invalidate() invalidate()
}
} }
fun setFocus(focus: Attachment.Focus) { fun setFocus(focus: Attachment.Focus) {
this.focus = focus this.focus = focus
if (imageSize != null) if (imageSize != null) {
invalidate() invalidate()
}
} }
// Assumes setFocus called first // Assumes setFocus called first
@ -46,8 +48,9 @@ class FocusIndicatorView
// so base it on the view width/height whenever the first access occurs. // so base it on the view width/height whenever the first access occurs.
private fun getCircleRadius(): Float { private fun getCircleRadius(): Float {
val circleRadius = this.circleRadius val circleRadius = this.circleRadius
if (circleRadius != null) if (circleRadius != null) {
return circleRadius return circleRadius
}
val newCircleRadius = min(this.width, this.height).toFloat() / 4.0f val newCircleRadius = min(this.width, this.height).toFloat() / 4.0f
this.circleRadius = newCircleRadius this.circleRadius = newCircleRadius
return 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. @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 { override fun onTouchEvent(event: MotionEvent): Boolean {
if (event.actionMasked == MotionEvent.ACTION_CANCEL) if (event.actionMasked == MotionEvent.ACTION_CANCEL) {
return false return false
}
val imageSize = this.imageSize ?: return false val imageSize = this.imageSize ?: return false

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -55,7 +55,7 @@ class EditFilterActivity : BaseActivity() {
filterContextNotifications to Filter.Kind.NOTIFICATIONS, filterContextNotifications to Filter.Kind.NOTIFICATIONS,
filterContextPublic to Filter.Kind.PUBLIC, filterContextPublic to Filter.Kind.PUBLIC,
filterContextThread to Filter.Kind.THREAD, filterContextThread to Filter.Kind.THREAD,
filterContextAccount to Filter.Kind.ACCOUNT, filterContextAccount to Filter.Kind.ACCOUNT
) )
} }
@ -213,7 +213,7 @@ class EditFilterActivity : BaseActivity() {
FilterKeyword( FilterKeyword(
"", "",
binding.phraseEditText.text.toString(), binding.phraseEditText.text.toString(),
binding.phraseWholeWord.isChecked, binding.phraseWholeWord.isChecked
) )
) )
} }
@ -234,7 +234,7 @@ class EditFilterActivity : BaseActivity() {
keyword, keyword,
keyword.copy( keyword.copy(
keyword = binding.phraseEditText.text.toString(), 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, title = title,
context = contexts, context = contexts,
filterAction = action, filterAction = action,
expiresInSeconds = expiresInSeconds, expiresInSeconds = expiresInSeconds
).fold( ).fold(
{ newFilter -> { newFilter ->
// This is _terrible_, but the all-in-one update filter api Just Doesn't Work // 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, title = title,
context = contexts, context = contexts,
filterAction = action, filterAction = action,
expiresInSeconds = expiresInSeconds, expiresInSeconds = expiresInSeconds
).fold( ).fold(
{ {
// This is _terrible_, but the all-in-one update filter api Just Doesn't Work // 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, context = context,
irreversible = false, irreversible = false,
wholeWord = keyword.wholeWord, 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() Snackbar.make(parent, "Error deleting filter '${filter.title}'", Snackbar.LENGTH_SHORT).show()
}, }
) )
} else { } else {
Snackbar.make(parent, "Error deleting filter '${filter.title}'", Snackbar.LENGTH_SHORT).show() 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( class FollowedTagsAdapter(
private val actionListener: HashtagActionListener, private val actionListener: HashtagActionListener,
private val viewModel: FollowedTagsViewModel, private val viewModel: FollowedTagsViewModel
) : PagingDataAdapter<String, BindingHolder<ItemFollowedHashtagBinding>>(STRING_COMPARATOR) { ) : PagingDataAdapter<String, BindingHolder<ItemFollowedHashtagBinding>>(STRING_COMPARATOR) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingHolder<ItemFollowedHashtagBinding> = override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingHolder<ItemFollowedHashtagBinding> =
BindingHolder(ItemFollowedHashtagBinding.inflate(LayoutInflater.from(parent.context), parent, false)) BindingHolder(ItemFollowedHashtagBinding.inflate(LayoutInflater.from(parent.context), parent, false))

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -14,6 +14,7 @@
* see <http://www.gnu.org/licenses>. */ * see <http://www.gnu.org/licenses>. */
@file:JvmName("PushNotificationHelper") @file:JvmName("PushNotificationHelper")
package com.keylesspalace.tusky.components.notifications package com.keylesspalace.tusky.components.notifications
import android.app.NotificationManager import android.app.NotificationManager
@ -163,7 +164,6 @@ suspend fun registerUnifiedPushEndpoint(
account: AccountEntity, account: AccountEntity,
endpoint: String endpoint: String
) = withContext(Dispatchers.IO) { ) = withContext(Dispatchers.IO) {
// Generate a prime256v1 key pair for WebPush // Generate a prime256v1 key pair for WebPush
// Decryption is unimplemented for now, since Mastodon uses an old WebPush // Decryption is unimplemented for now, since Mastodon uses an old WebPush
// standard which does not send needed information for decryption in the payload // standard which does not send needed information for decryption in the payload
@ -173,8 +173,11 @@ suspend fun registerUnifiedPushEndpoint(
val auth = CryptoUtil.secureRandomBytesEncoded(16) val auth = CryptoUtil.secureRandomBytesEncoded(16)
api.subscribePushNotifications( api.subscribePushNotifications(
"Bearer ${account.accessToken}", account.domain, "Bearer ${account.accessToken}",
endpoint, keyPair.pubkey, auth, account.domain,
endpoint,
keyPair.pubkey,
auth,
buildSubscriptionData(context, account) buildSubscriptionData(context, account)
).onFailure { throwable -> ).onFailure { throwable ->
Log.w(TAG, "Error setting push endpoint for account ${account.id}", 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) { suspend fun updateUnifiedPushSubscription(context: Context, api: MastodonApi, accountManager: AccountManager, account: AccountEntity) {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
api.updatePushNotificationSubscription( api.updatePushNotificationSubscription(
"Bearer ${account.accessToken}", account.domain, "Bearer ${account.accessToken}",
account.domain,
buildSubscriptionData(context, account) buildSubscriptionData(context, account)
).onSuccess { ).onSuccess {
Log.d(TAG, "UnifiedPush subscription updated for account ${account.id}") 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>) { override fun onResponse(call: Call<Account>, response: Response<Account>) {
val account = response.body() val account = response.body()
if (response.isSuccessful && account != null) { if (response.isSuccessful && account != null) {
accountManager.activeAccount?.let { accountManager.activeAccount?.let {
it.defaultPostPrivacy = account.source?.privacy it.defaultPostPrivacy = account.source?.privacy
?: Status.Visibility.PUBLIC ?: Status.Visibility.PUBLIC

View file

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

View file

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

View file

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

View file

@ -75,7 +75,7 @@ class SearchActivity : BottomSheetActivity(), HasAndroidInjector, MenuProvider {
binding.pages.isUserInputEnabled = enableSwipeForTabs binding.pages.isUserInputEnabled = enableSwipeForTabs
TabLayoutMediator(binding.tabs, binding.pages) { TabLayoutMediator(binding.tabs, binding.pages) {
tab, position -> tab, position ->
tab.text = getPageTitle(position) tab.text = getPageTitle(position)
}.attach() }.attach()
} }

View file

@ -54,7 +54,6 @@ class SearchPagingSource<T : Any>(
val currentKey = params.key ?: 0 val currentKey = params.key ?: 0
try { try {
val data = mastodonApi.searchObservable( val data = mastodonApi.searchObservable(
query = searchRequest, query = searchRequest,
type = searchType.apiParameter, 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 -> { Attachment.Type.GIFV, Attachment.Type.VIDEO, Attachment.Type.IMAGE, Attachment.Type.AUDIO -> {
val attachments = AttachmentViewData.list(actionable) val attachments = AttachmentViewData.list(actionable)
val intent = ViewMediaActivity.newIntent( val intent = ViewMediaActivity.newIntent(
context, attachments, context,
attachments,
attachmentIndex attachmentIndex
) )
if (view != null) { if (view != null) {
@ -141,7 +142,8 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status
ViewCompat.setTransitionName(view, url) ViewCompat.setTransitionName(view, url)
val options = ActivityOptionsCompat.makeSceneTransitionAnimation( val options = ActivityOptionsCompat.makeSceneTransitionAnimation(
requireActivity(), requireActivity(),
view, url view,
url
) )
startActivity(intent, options.toBundle()) startActivity(intent, options.toBundle())
} else { } else {
@ -399,7 +401,8 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status
private fun showOpenAsDialog(statusUrl: String, dialogTitle: CharSequence?) { private fun showOpenAsDialog(statusUrl: String, dialogTitle: CharSequence?) {
bottomSheetActivity?.showAccountChooserDialog( bottomSheetActivity?.showAccountChooserDialog(
dialogTitle, false, dialogTitle,
false,
object : AccountSelectionListener { object : AccountSelectionListener {
override fun onAccountSelected(account: AccountEntity) { override fun onAccountSelected(account: AccountEntity) {
bottomSheetActivity?.openAsAccount(statusUrl, account) bottomSheetActivity?.openAsAccount(statusUrl, account)
@ -515,7 +518,7 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status
language = status.language, language = status.language,
statusId = source.id, statusId = source.id,
poll = status.poll?.toNewPoll(status.createdAt), poll = status.poll?.toNewPoll(status.createdAt),
kind = ComposeActivity.ComposeKind.EDIT_POSTED, kind = ComposeActivity.ComposeKind.EDIT_POSTED
) )
startActivity(ComposeActivity.startIntent(requireContext(), composeOptions)) startActivity(ComposeActivity.startIntent(requireContext(), composeOptions))
}, },

View file

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

View file

@ -131,8 +131,10 @@ class TimelinePagingAdapter(
return if (oldItem == newItem) { return if (oldItem == newItem) {
// If items are equal - update timestamp only // If items are equal - update timestamp only
listOf(StatusBaseViewHolder.Key.KEY_CREATED) 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 null
}
} }
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -302,7 +302,7 @@ abstract class TimelineViewModel(
} else { } else {
Log.e(TAG, "Error getting filters", throwable) 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 import com.keylesspalace.tusky.viewdata.TrendingViewData
class TrendingAdapter( class TrendingAdapter(
private val trendingListener: LinkListener, private val trendingListener: LinkListener
) : ListAdapter<TrendingViewData, RecyclerView.ViewHolder>(TrendingDifferCallback) { ) : ListAdapter<TrendingViewData, RecyclerView.ViewHolder>(TrendingDifferCallback) {
init { init {

View file

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

View file

@ -93,8 +93,10 @@ class ThreadAdapter(
return if (oldItem == newItem) { return if (oldItem == newItem) {
// If items are equal - update timestamp only // If items are equal - update timestamp only
listOf(StatusBaseViewHolder.Key.KEY_CREATED) 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 null
}
} }
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -85,7 +85,7 @@ data class TimelineStatusEntity(
val pinned: Boolean, val pinned: Boolean,
val card: String?, val card: String?,
val language: String?, val language: String?,
val filtered: List<FilterResult>?, val filtered: List<FilterResult>?
) { ) {
val isPlaceholder: Boolean val isPlaceholder: Boolean
get() = this.authorServerId == null 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_38_39, AppDatabase.MIGRATION_39_40, AppDatabase.MIGRATION_40_41,
AppDatabase.MIGRATION_41_42, AppDatabase.MIGRATION_42_43, AppDatabase.MIGRATION_43_44, 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_44_45, AppDatabase.MIGRATION_45_46, AppDatabase.MIGRATION_46_47,
AppDatabase.MIGRATION_47_48, AppDatabase.MIGRATION_47_48
) )
.build() .build()
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -5,5 +5,5 @@ import com.google.gson.annotations.SerializedName
data class FilterResult( data class FilterResult(
val filter: Filter, val filter: Filter,
@SerializedName("keyword_matches") val keywordMatches: List<String>?, @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( FilterKeyword(
id = id, id = id,
keyword = phrase, keyword = phrase,
wholeWord = wholeWord, wholeWord = wholeWord
) )
) )
) )

View file

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

View file

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

View file

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

View file

@ -20,5 +20,5 @@ import com.google.gson.annotations.SerializedName
data class NotificationSubscribeResult( data class NotificationSubscribeResult(
val id: Int, val id: Int,
val endpoint: String, 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 category: String,
val status_ids: List<String>?, val status_ids: List<String>?,
@SerializedName("created_at") val createdAt: Date, @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 poll: Poll?,
val card: Card?, val card: Card?,
val language: String?, val language: String?,
val filtered: List<FilterResult>?, val filtered: List<FilterResult>?
) { ) {
val actionableId: String val actionableId: String
@ -69,12 +69,16 @@ data class Status(
enum class Visibility(val num: Int) { enum class Visibility(val num: Int) {
UNKNOWN(0), UNKNOWN(0),
@SerializedName("public") @SerializedName("public")
PUBLIC(1), PUBLIC(1),
@SerializedName("unlisted") @SerializedName("unlisted")
UNLISTED(2), UNLISTED(2),
@SerializedName("private") @SerializedName("private")
PRIVATE(3), PRIVATE(3),
@SerializedName("direct") @SerializedName("direct")
DIRECT(4); DIRECT(4);
@ -134,7 +138,7 @@ data class Status(
attachments = attachments, attachments = attachments,
poll = poll, poll = poll,
createdAt = createdAt, createdAt = createdAt,
language = language, language = language
) )
} }

View file

@ -20,5 +20,5 @@ import com.google.gson.annotations.SerializedName
data class StatusSource( data class StatusSource(
val id: String, val id: String,
val text: 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 url: String,
val avatar: String, val avatar: String,
val bot: Boolean = false, 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 val name: String
get() = if (displayName.isNullOrEmpty()) { get() = if (displayName.isNullOrEmpty()) {
localUsername localUsername
} else displayName } else {
displayName
}
} }

View file

@ -29,7 +29,7 @@ data class TrendingTag(
val name: String, val name: String,
val url: String, val url: String,
val history: List<TrendingTagHistory>, val history: List<TrendingTagHistory>,
val following: Boolean, val following: Boolean
) )
/** /**
@ -42,7 +42,7 @@ data class TrendingTag(
data class TrendingTagHistory( data class TrendingTagHistory(
val day: String, val day: String,
val accounts: String, val accounts: String,
val uses: String, val uses: String
) )
fun TrendingTag.start() = Date(history.last().day.toLong() * 1000L) 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) { private fun onMute(accountId: String, accountUsername: String) {
showMuteAccountDialog(this.requireActivity(), accountUsername) { notifications: Boolean?, duration: Int? -> showMuteAccountDialog(this.requireActivity(), accountUsername) { notifications: Boolean?, duration: Int? ->
lifecycleScope.launch { lifecycleScope.launch {
timelineCases.mute(accountId, notifications == true, duration) timelineCases.mute(accountId, notifications == true, duration)
@ -339,7 +338,8 @@ abstract class SFragment : Fragment(), Injectable {
view.transitionName = url view.transitionName = url
val options = ActivityOptionsCompat.makeSceneTransitionAnimation( val options = ActivityOptionsCompat.makeSceneTransitionAnimation(
requireActivity(), requireActivity(),
view, url view,
url
) )
startActivity(intent, options.toBundle()) startActivity(intent, options.toBundle())
} else { } else {

View file

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

View file

@ -42,6 +42,7 @@ abstract class ViewMediaFragment : Fragment() {
@JvmStatic @JvmStatic
protected val ARG_ATTACHMENT = "attach" protected val ARG_ATTACHMENT = "attach"
@JvmStatic @JvmStatic
protected val ARG_SINGLE_IMAGE_URL = "singleImageUrl" 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 return GregorianCalendar(year, month - 1, day).time
} }
if (hasT) { if (hasT) {
// extract hours, minutes, seconds and milliseconds // extract hours, minutes, seconds and milliseconds
hour = parseInt(this, 1.let { offset += it; offset }, 2.let { offset += it; offset }) hour = parseInt(this, 1.let { offset += it; offset }, 2.let { offset += it; offset })
if (checkOffset(this, offset, ':')) { if (checkOffset(this, offset, ':')) {

View file

@ -29,8 +29,9 @@ class FilterModel @Inject constructor() {
// Patterns are expensive and thread-safe, matchers are neither. // Patterns are expensive and thread-safe, matchers are neither.
val matcher = pattern?.matcher("") ?: return Filter.Action.NONE 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 return Filter.Action.HIDE
}
val spoilerText = status.actionableStatus.spoilerText val spoilerText = status.actionableStatus.spoilerText
val attachmentsDescriptions = status.attachments.mapNotNull { it.description } 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 // only switch domains if the request comes from retrofit
return if (originalRequest.url.host == MastodonApi.PLACEHOLDER_DOMAIN) { return if (originalRequest.url.host == MastodonApi.PLACEHOLDER_DOMAIN) {
val builder: Request.Builder = originalRequest.newBuilder() val builder: Request.Builder = originalRequest.newBuilder()
val instanceHeader = originalRequest.header(MastodonApi.DOMAIN_HEADER) val instanceHeader = originalRequest.header(MastodonApi.DOMAIN_HEADER)

View file

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

View file

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

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