add ktlint plugin to project and apply default code style (#2209)
* add ktlint plugin to project and apply default code style * some manual adjustments, fix wildcard imports * update CONTRIBUTING.md * fix formatting
This commit is contained in:
parent
955267199e
commit
16ffcca748
227 changed files with 3933 additions and 3371 deletions
|
@ -31,17 +31,17 @@ import com.keylesspalace.tusky.util.BindingHolder
|
|||
import com.keylesspalace.tusky.util.LinkHelper
|
||||
import com.keylesspalace.tusky.util.emojify
|
||||
|
||||
interface AnnouncementActionListener: LinkListener {
|
||||
interface AnnouncementActionListener : LinkListener {
|
||||
fun openReactionPicker(announcementId: String, target: View)
|
||||
fun addReaction(announcementId: String, name: String)
|
||||
fun removeReaction(announcementId: String, name: String)
|
||||
}
|
||||
|
||||
class AnnouncementAdapter(
|
||||
private var items: List<Announcement> = emptyList(),
|
||||
private val listener: AnnouncementActionListener,
|
||||
private val wellbeingEnabled: Boolean = false,
|
||||
private val animateEmojis: Boolean = false
|
||||
private var items: List<Announcement> = emptyList(),
|
||||
private val listener: AnnouncementActionListener,
|
||||
private val wellbeingEnabled: Boolean = false,
|
||||
private val animateEmojis: Boolean = false
|
||||
) : RecyclerView.Adapter<BindingHolder<ItemAnnouncementBinding>>() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingHolder<ItemAnnouncementBinding> {
|
||||
|
@ -67,12 +67,12 @@ class AnnouncementAdapter(
|
|||
}
|
||||
|
||||
item.reactions.forEachIndexed { i, reaction ->
|
||||
(chips.getChildAt(i)?.takeUnless { it.id == R.id.addReactionChip } as Chip?
|
||||
?: Chip(ContextThemeWrapper(chips.context, R.style.Widget_MaterialComponents_Chip_Choice)).apply {
|
||||
isCheckable = true
|
||||
checkedIcon = null
|
||||
chips.addView(this, i)
|
||||
})
|
||||
chips.getChildAt(i)?.takeUnless { it.id == R.id.addReactionChip } as Chip?
|
||||
?: Chip(ContextThemeWrapper(chips.context, R.style.Widget_MaterialComponents_Chip_Choice)).apply {
|
||||
isCheckable = true
|
||||
checkedIcon = null
|
||||
chips.addView(this, i)
|
||||
}
|
||||
.apply {
|
||||
val emojiText = if (reaction.url == null) {
|
||||
reaction.name
|
||||
|
@ -80,16 +80,18 @@ class AnnouncementAdapter(
|
|||
context.getString(R.string.emoji_shortcode_format, reaction.name)
|
||||
}
|
||||
this.text = ("$emojiText ${reaction.count}")
|
||||
.emojify(
|
||||
listOf(Emoji(
|
||||
reaction.name,
|
||||
reaction.url ?: "",
|
||||
reaction.staticUrl ?: "",
|
||||
null
|
||||
)),
|
||||
this,
|
||||
animateEmojis
|
||||
)
|
||||
.emojify(
|
||||
listOf(
|
||||
Emoji(
|
||||
reaction.name,
|
||||
reaction.url ?: "",
|
||||
reaction.staticUrl ?: "",
|
||||
null
|
||||
)
|
||||
),
|
||||
this,
|
||||
animateEmojis
|
||||
)
|
||||
|
||||
isChecked = reaction.me
|
||||
|
||||
|
|
|
@ -34,7 +34,12 @@ import com.keylesspalace.tusky.databinding.ActivityAnnouncementsBinding
|
|||
import com.keylesspalace.tusky.di.Injectable
|
||||
import com.keylesspalace.tusky.di.ViewModelFactory
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.util.*
|
||||
import com.keylesspalace.tusky.util.Error
|
||||
import com.keylesspalace.tusky.util.Loading
|
||||
import com.keylesspalace.tusky.util.Success
|
||||
import com.keylesspalace.tusky.util.hide
|
||||
import com.keylesspalace.tusky.util.show
|
||||
import com.keylesspalace.tusky.util.viewBinding
|
||||
import com.keylesspalace.tusky.view.EmojiPicker
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -52,13 +57,13 @@ class AnnouncementsActivity : BottomSheetActivity(), AnnouncementActionListener,
|
|||
private val picker by lazy { EmojiPicker(this) }
|
||||
private val pickerDialog by lazy {
|
||||
PopupWindow(this)
|
||||
.apply {
|
||||
contentView = picker
|
||||
isFocusable = true
|
||||
setOnDismissListener {
|
||||
currentAnnouncementId = null
|
||||
}
|
||||
.apply {
|
||||
contentView = picker
|
||||
isFocusable = true
|
||||
setOnDismissListener {
|
||||
currentAnnouncementId = null
|
||||
}
|
||||
}
|
||||
}
|
||||
private var currentAnnouncementId: String? = null
|
||||
|
||||
|
|
|
@ -27,15 +27,20 @@ import com.keylesspalace.tusky.entity.Announcement
|
|||
import com.keylesspalace.tusky.entity.Emoji
|
||||
import com.keylesspalace.tusky.entity.Instance
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.util.*
|
||||
import com.keylesspalace.tusky.util.Either
|
||||
import com.keylesspalace.tusky.util.Error
|
||||
import com.keylesspalace.tusky.util.Loading
|
||||
import com.keylesspalace.tusky.util.Resource
|
||||
import com.keylesspalace.tusky.util.RxAwareViewModel
|
||||
import com.keylesspalace.tusky.util.Success
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import javax.inject.Inject
|
||||
|
||||
class AnnouncementsViewModel @Inject constructor(
|
||||
accountManager: AccountManager,
|
||||
private val appDatabase: AppDatabase,
|
||||
private val mastodonApi: MastodonApi,
|
||||
private val eventHub: EventHub
|
||||
accountManager: AccountManager,
|
||||
private val appDatabase: AppDatabase,
|
||||
private val mastodonApi: MastodonApi,
|
||||
private val eventHub: EventHub
|
||||
) : RxAwareViewModel() {
|
||||
|
||||
private val announcementsMutable = MutableLiveData<Resource<List<Announcement>>>()
|
||||
|
@ -45,139 +50,153 @@ class AnnouncementsViewModel @Inject constructor(
|
|||
val emojis: LiveData<List<Emoji>> = emojisMutable
|
||||
|
||||
init {
|
||||
Single.zip(mastodonApi.getCustomEmojis(),
|
||||
appDatabase.instanceDao().loadMetadataForInstance(accountManager.activeAccount?.domain!!)
|
||||
.map<Either<InstanceEntity, Instance>> { Either.Left(it) }
|
||||
.onErrorResumeNext {
|
||||
mastodonApi.getInstance()
|
||||
.map { Either.Right(it) }
|
||||
},
|
||||
{ emojis, either ->
|
||||
either.asLeftOrNull()?.copy(emojiList = emojis)
|
||||
?: InstanceEntity(
|
||||
accountManager.activeAccount?.domain!!,
|
||||
emojis,
|
||||
either.asRight().maxTootChars,
|
||||
either.asRight().pollLimits?.maxOptions,
|
||||
either.asRight().pollLimits?.maxOptionChars,
|
||||
either.asRight().version
|
||||
)
|
||||
})
|
||||
.doOnSuccess {
|
||||
appDatabase.instanceDao().insertOrReplace(it)
|
||||
}
|
||||
.subscribe({
|
||||
Single.zip(
|
||||
mastodonApi.getCustomEmojis(),
|
||||
appDatabase.instanceDao().loadMetadataForInstance(accountManager.activeAccount?.domain!!)
|
||||
.map<Either<InstanceEntity, Instance>> { Either.Left(it) }
|
||||
.onErrorResumeNext {
|
||||
mastodonApi.getInstance()
|
||||
.map { Either.Right(it) }
|
||||
},
|
||||
{ emojis, either ->
|
||||
either.asLeftOrNull()?.copy(emojiList = emojis)
|
||||
?: InstanceEntity(
|
||||
accountManager.activeAccount?.domain!!,
|
||||
emojis,
|
||||
either.asRight().maxTootChars,
|
||||
either.asRight().pollLimits?.maxOptions,
|
||||
either.asRight().pollLimits?.maxOptionChars,
|
||||
either.asRight().version
|
||||
)
|
||||
}
|
||||
)
|
||||
.doOnSuccess {
|
||||
appDatabase.instanceDao().insertOrReplace(it)
|
||||
}
|
||||
.subscribe(
|
||||
{
|
||||
emojisMutable.postValue(it.emojiList.orEmpty())
|
||||
}, {
|
||||
},
|
||||
{
|
||||
Log.w(TAG, "Failed to get custom emojis.", it)
|
||||
})
|
||||
.autoDispose()
|
||||
}
|
||||
)
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
fun load() {
|
||||
announcementsMutable.postValue(Loading())
|
||||
mastodonApi.listAnnouncements()
|
||||
.subscribe({
|
||||
.subscribe(
|
||||
{
|
||||
announcementsMutable.postValue(Success(it))
|
||||
it.filter { announcement -> !announcement.read }
|
||||
.forEach { announcement ->
|
||||
mastodonApi.dismissAnnouncement(announcement.id)
|
||||
.subscribe(
|
||||
{
|
||||
eventHub.dispatch(AnnouncementReadEvent(announcement.id))
|
||||
},
|
||||
{ throwable ->
|
||||
Log.d(TAG, "Failed to mark announcement as read.", throwable)
|
||||
}
|
||||
)
|
||||
.autoDispose()
|
||||
}
|
||||
}, {
|
||||
.forEach { announcement ->
|
||||
mastodonApi.dismissAnnouncement(announcement.id)
|
||||
.subscribe(
|
||||
{
|
||||
eventHub.dispatch(AnnouncementReadEvent(announcement.id))
|
||||
},
|
||||
{ throwable ->
|
||||
Log.d(TAG, "Failed to mark announcement as read.", throwable)
|
||||
}
|
||||
)
|
||||
.autoDispose()
|
||||
}
|
||||
},
|
||||
{
|
||||
announcementsMutable.postValue(Error(cause = it))
|
||||
})
|
||||
.autoDispose()
|
||||
}
|
||||
)
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
fun addReaction(announcementId: String, name: String) {
|
||||
mastodonApi.addAnnouncementReaction(announcementId, name)
|
||||
.subscribe({
|
||||
.subscribe(
|
||||
{
|
||||
announcementsMutable.postValue(
|
||||
Success(
|
||||
announcements.value!!.data!!.map { announcement ->
|
||||
if (announcement.id == announcementId) {
|
||||
announcement.copy(
|
||||
reactions = if (announcement.reactions.find { reaction -> reaction.name == name } != null) {
|
||||
announcement.reactions.map { reaction ->
|
||||
if (reaction.name == name) {
|
||||
reaction.copy(
|
||||
count = reaction.count + 1,
|
||||
me = true
|
||||
)
|
||||
} else {
|
||||
reaction
|
||||
}
|
||||
}
|
||||
} else {
|
||||
listOf(
|
||||
*announcement.reactions.toTypedArray(),
|
||||
emojis.value!!.find { emoji -> emoji.shortcode == name }
|
||||
!!.run {
|
||||
Announcement.Reaction(
|
||||
name,
|
||||
1,
|
||||
true,
|
||||
url,
|
||||
staticUrl
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
Success(
|
||||
announcements.value!!.data!!.map { announcement ->
|
||||
if (announcement.id == announcementId) {
|
||||
announcement.copy(
|
||||
reactions = if (announcement.reactions.find { reaction -> reaction.name == name } != null) {
|
||||
announcement.reactions.map { reaction ->
|
||||
if (reaction.name == name) {
|
||||
reaction.copy(
|
||||
count = reaction.count + 1,
|
||||
me = true
|
||||
)
|
||||
} else {
|
||||
reaction
|
||||
}
|
||||
}
|
||||
} else {
|
||||
announcement
|
||||
listOf(
|
||||
*announcement.reactions.toTypedArray(),
|
||||
emojis.value!!.find { emoji -> emoji.shortcode == name }
|
||||
!!.run {
|
||||
Announcement.Reaction(
|
||||
name,
|
||||
1,
|
||||
true,
|
||||
url,
|
||||
staticUrl
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
} else {
|
||||
announcement
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
}, {
|
||||
},
|
||||
{
|
||||
Log.w(TAG, "Failed to add reaction to the announcement.", it)
|
||||
})
|
||||
.autoDispose()
|
||||
}
|
||||
)
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
fun removeReaction(announcementId: String, name: String) {
|
||||
mastodonApi.removeAnnouncementReaction(announcementId, name)
|
||||
.subscribe({
|
||||
.subscribe(
|
||||
{
|
||||
announcementsMutable.postValue(
|
||||
Success(
|
||||
announcements.value!!.data!!.map { announcement ->
|
||||
if (announcement.id == announcementId) {
|
||||
announcement.copy(
|
||||
reactions = announcement.reactions.mapNotNull { reaction ->
|
||||
if (reaction.name == name) {
|
||||
if (reaction.count > 1) {
|
||||
reaction.copy(
|
||||
count = reaction.count - 1,
|
||||
me = false
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} else {
|
||||
reaction
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
announcement
|
||||
Success(
|
||||
announcements.value!!.data!!.map { announcement ->
|
||||
if (announcement.id == announcementId) {
|
||||
announcement.copy(
|
||||
reactions = announcement.reactions.mapNotNull { reaction ->
|
||||
if (reaction.name == name) {
|
||||
if (reaction.count > 1) {
|
||||
reaction.copy(
|
||||
count = reaction.count - 1,
|
||||
me = false
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} else {
|
||||
reaction
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
} else {
|
||||
announcement
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
}, {
|
||||
},
|
||||
{
|
||||
Log.w(TAG, "Failed to remove reaction from the announcement.", it)
|
||||
})
|
||||
.autoDispose()
|
||||
}
|
||||
)
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue