migrating to ViewBinding part 2: Activities (#2093)

This commit is contained in:
Konrad Pozniak 2021-03-07 19:05:51 +01:00 committed by GitHub
commit ff69a2ad0d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 741 additions and 729 deletions

View file

@ -30,13 +30,12 @@ import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.ViewTagActivity
import com.keylesspalace.tusky.adapter.EmojiAdapter
import com.keylesspalace.tusky.adapter.OnEmojiSelectedListener
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.view.EmojiPicker
import kotlinx.android.synthetic.main.activity_announcements.*
import kotlinx.android.synthetic.main.toolbar_basic.*
import javax.inject.Inject
class AnnouncementsActivity : BottomSheetActivity(), AnnouncementActionListener, OnEmojiSelectedListener, Injectable {
@ -46,6 +45,8 @@ class AnnouncementsActivity : BottomSheetActivity(), AnnouncementActionListener,
private val viewModel: AnnouncementsViewModel by viewModels { viewModelFactory }
private val binding by viewBinding(ActivityAnnouncementsBinding::inflate)
private lateinit var adapter: AnnouncementAdapter
private val picker by lazy { EmojiPicker(this) }
@ -63,22 +64,22 @@ class AnnouncementsActivity : BottomSheetActivity(), AnnouncementActionListener,
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_announcements)
setContentView(binding.root)
setSupportActionBar(toolbar)
setSupportActionBar(binding.includedToolbar.toolbar)
supportActionBar?.apply {
title = getString(R.string.title_announcements)
setDisplayHomeAsUpEnabled(true)
setDisplayShowHomeEnabled(true)
}
swipeRefreshLayout.setOnRefreshListener(this::refreshAnnouncements)
swipeRefreshLayout.setColorSchemeResources(R.color.tusky_blue)
binding.swipeRefreshLayout.setOnRefreshListener(this::refreshAnnouncements)
binding.swipeRefreshLayout.setColorSchemeResources(R.color.tusky_blue)
announcementsList.setHasFixedSize(true)
announcementsList.layoutManager = LinearLayoutManager(this)
binding.announcementsList.setHasFixedSize(true)
binding.announcementsList.layoutManager = LinearLayoutManager(this)
val divider = DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
announcementsList.addItemDecoration(divider)
binding.announcementsList.addItemDecoration(divider)
val preferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
val wellbeingEnabled = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false)
@ -86,31 +87,31 @@ class AnnouncementsActivity : BottomSheetActivity(), AnnouncementActionListener,
adapter = AnnouncementAdapter(emptyList(), this, wellbeingEnabled, animateEmojis)
announcementsList.adapter = adapter
binding.announcementsList.adapter = adapter
viewModel.announcements.observe(this) {
when (it) {
is Success -> {
progressBar.hide()
swipeRefreshLayout.isRefreshing = false
binding.progressBar.hide()
binding.swipeRefreshLayout.isRefreshing = false
if (it.data.isNullOrEmpty()) {
errorMessageView.setup(R.drawable.elephant_friend_empty, R.string.no_announcements)
errorMessageView.show()
binding.errorMessageView.setup(R.drawable.elephant_friend_empty, R.string.no_announcements)
binding.errorMessageView.show()
} else {
errorMessageView.hide()
binding.errorMessageView.hide()
}
adapter.updateList(it.data ?: listOf())
}
is Loading -> {
errorMessageView.hide()
binding.errorMessageView.hide()
}
is Error -> {
progressBar.hide()
swipeRefreshLayout.isRefreshing = false
errorMessageView.setup(R.drawable.elephant_error, R.string.error_generic) {
binding.progressBar.hide()
binding.swipeRefreshLayout.isRefreshing = false
binding.errorMessageView.setup(R.drawable.elephant_error, R.string.error_generic) {
refreshAnnouncements()
}
errorMessageView.show()
binding.errorMessageView.show()
}
}
}
@ -120,12 +121,12 @@ class AnnouncementsActivity : BottomSheetActivity(), AnnouncementActionListener,
}
viewModel.load()
progressBar.show()
binding.progressBar.show()
}
private fun refreshAnnouncements() {
viewModel.load()
swipeRefreshLayout.isRefreshing = true
binding.swipeRefreshLayout.isRefreshing = true
}
override fun openReactionPicker(announcementId: String, target: View) {

View file

@ -61,6 +61,7 @@ import com.keylesspalace.tusky.components.compose.dialog.makeCaptionDialog
import com.keylesspalace.tusky.components.compose.dialog.showAddPollDialog
import com.keylesspalace.tusky.components.compose.view.ComposeOptionsListener
import com.keylesspalace.tusky.components.compose.view.ComposeScheduleView
import com.keylesspalace.tusky.databinding.ActivityComposeBinding
import com.keylesspalace.tusky.db.AccountEntity
import com.keylesspalace.tusky.db.DraftAttachment
import com.keylesspalace.tusky.di.Injectable
@ -76,7 +77,6 @@ import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp
import kotlinx.android.parcel.Parcelize
import kotlinx.android.synthetic.main.activity_compose.*
import java.io.File
import java.io.IOException
import java.util.*
@ -109,17 +109,20 @@ class ComposeActivity : BaseActivity(),
private val viewModel: ComposeViewModel by viewModels { viewModelFactory }
private val binding by viewBinding(ActivityComposeBinding::inflate)
private val maxUploadMediaNumber = 4
private var mediaCount = 0
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val preferences = PreferenceManager.getDefaultSharedPreferences(this)
val theme = preferences.getString("appTheme", ThemeUtils.APP_THEME_DEFAULT)
if (theme == "black") {
setTheme(R.style.TuskyDialogActivityBlackTheme)
}
setContentView(R.layout.activity_compose)
setContentView(binding.root)
setupActionBar()
// do not do anything when not logged in, activity will be finished in super.onCreate() anyway
@ -135,10 +138,10 @@ class ComposeActivity : BaseActivity(),
},
onRemove = this::removeMediaFromQueue
)
composeMediaPreviewBar.layoutManager =
binding.composeMediaPreviewBar.layoutManager =
LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
composeMediaPreviewBar.adapter = mediaAdapter
composeMediaPreviewBar.itemAnimator = null
binding.composeMediaPreviewBar.adapter = mediaAdapter
binding.composeMediaPreviewBar.itemAnimator = null
subscribeToUpdates(mediaAdapter)
setupButtons()
@ -154,11 +157,11 @@ class ComposeActivity : BaseActivity(),
setupReplyViews(composeOptions?.replyingStatusAuthor, composeOptions?.replyingStatusContent)
val tootText = composeOptions?.tootText
if (!tootText.isNullOrEmpty()) {
composeEditField.setText(tootText)
binding.composeEditField.setText(tootText)
}
if (!composeOptions?.scheduledAt.isNullOrEmpty()) {
composeScheduleView.setDateTime(composeOptions?.scheduledAt)
binding.composeScheduleView.setDateTime(composeOptions?.scheduledAt)
}
setupComposeField(preferences, viewModel.startingText)
@ -198,14 +201,14 @@ class ComposeActivity : BaseActivity(),
}
if (shareBody.isNotBlank()) {
val start = composeEditField.selectionStart.coerceAtLeast(0)
val end = composeEditField.selectionEnd.coerceAtLeast(0)
val start = binding.composeEditField.selectionStart.coerceAtLeast(0)
val end = binding.composeEditField.selectionEnd.coerceAtLeast(0)
val left = min(start, end)
val right = max(start, end)
composeEditField.text.replace(left, right, shareBody, 0, shareBody.length)
binding.composeEditField.text.replace(left, right, shareBody, 0, shareBody.length)
// move edittext cursor to first when shareBody parsed
composeEditField.text.insert(0, "\n")
composeEditField.setSelection(0)
binding.composeEditField.text.insert(0, "\n")
binding.composeEditField.setSelection(0)
}
}
}
@ -214,58 +217,58 @@ class ComposeActivity : BaseActivity(),
private fun setupReplyViews(replyingStatusAuthor: String?, replyingStatusContent: String?) {
if (replyingStatusAuthor != null) {
composeReplyView.show()
composeReplyView.text = getString(R.string.replying_to, replyingStatusAuthor)
binding.composeReplyView.show()
binding.composeReplyView.text = getString(R.string.replying_to, replyingStatusAuthor)
val arrowDownIcon = IconicsDrawable(this, GoogleMaterial.Icon.gmd_arrow_drop_down).apply { sizeDp = 12 }
ThemeUtils.setDrawableTint(this, arrowDownIcon, android.R.attr.textColorTertiary)
composeReplyView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, arrowDownIcon, null)
binding.composeReplyView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, arrowDownIcon, null)
composeReplyView.setOnClickListener {
TransitionManager.beginDelayedTransition(composeReplyContentView.parent as ViewGroup)
binding.composeReplyView.setOnClickListener {
TransitionManager.beginDelayedTransition(binding.composeReplyContentView.parent as ViewGroup)
if (composeReplyContentView.isVisible) {
composeReplyContentView.hide()
composeReplyView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, arrowDownIcon, null)
if (binding.composeReplyContentView.isVisible) {
binding.composeReplyContentView.hide()
binding.composeReplyView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, arrowDownIcon, null)
} else {
composeReplyContentView.show()
binding.composeReplyContentView.show()
val arrowUpIcon = IconicsDrawable(this, GoogleMaterial.Icon.gmd_arrow_drop_up).apply { sizeDp = 12 }
ThemeUtils.setDrawableTint(this, arrowUpIcon, android.R.attr.textColorTertiary)
composeReplyView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, arrowUpIcon, null)
binding.composeReplyView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, arrowUpIcon, null)
}
}
}
replyingStatusContent?.let { composeReplyContentView.text = it }
replyingStatusContent?.let { binding.composeReplyContentView.text = it }
}
private fun setupContentWarningField(startingContentWarning: String?) {
if (startingContentWarning != null) {
composeContentWarningField.setText(startingContentWarning)
binding.composeContentWarningField.setText(startingContentWarning)
}
composeContentWarningField.onTextChanged { _, _, _, _ -> updateVisibleCharactersLeft() }
binding.composeContentWarningField.onTextChanged { _, _, _, _ -> updateVisibleCharactersLeft() }
}
private fun setupComposeField(preferences: SharedPreferences, startingText: String?) {
composeEditField.setOnCommitContentListener(this)
binding.composeEditField.setOnCommitContentListener(this)
composeEditField.setOnKeyListener { _, keyCode, event -> this.onKeyDown(keyCode, event) }
binding.composeEditField.setOnKeyListener { _, keyCode, event -> this.onKeyDown(keyCode, event) }
composeEditField.setAdapter(
binding.composeEditField.setAdapter(
ComposeAutoCompleteAdapter(
this,
preferences.getBoolean(PrefKeys.ANIMATE_GIF_AVATARS, false),
preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
)
)
composeEditField.setTokenizer(ComposeTokenizer())
binding.composeEditField.setTokenizer(ComposeTokenizer())
composeEditField.setText(startingText)
composeEditField.setSelection(composeEditField.length())
binding.composeEditField.setText(startingText)
binding.composeEditField.setSelection(binding.composeEditField.length())
val mentionColour = composeEditField.linkTextColors.defaultColor
highlightSpans(composeEditField.text, mentionColour)
composeEditField.afterTextChanged { editable ->
val mentionColour = binding.composeEditField.linkTextColors.defaultColor
highlightSpans(binding.composeEditField.text, mentionColour)
binding.composeEditField.afterTextChanged { editable ->
highlightSpans(editable, mentionColour)
updateVisibleCharactersLeft()
}
@ -273,7 +276,7 @@ class ComposeActivity : BaseActivity(),
// work around Android platform bug -> https://issuetracker.google.com/issues/67102093
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O
|| Build.VERSION.SDK_INT == Build.VERSION_CODES.O_MR1) {
composeEditField.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
binding.composeEditField.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
}
}
@ -282,7 +285,7 @@ class ComposeActivity : BaseActivity(),
viewModel.instanceParams.observe { instanceData ->
maximumTootCharacters = instanceData.maxChars
updateVisibleCharactersLeft()
composeScheduleButton.visible(instanceData.supportsScheduled)
binding.composeScheduleButton.visible(instanceData.supportsScheduled)
}
viewModel.emoji.observe { emoji -> setEmojiList(emoji) }
combineLiveData(viewModel.markMediaAsSensitive, viewModel.showContentWarning) { markSensitive, showContentWarning ->
@ -296,19 +299,19 @@ class ComposeActivity : BaseActivity(),
mediaAdapter.submitList(media)
if (media.size != mediaCount) {
mediaCount = media.size
composeMediaPreviewBar.visible(media.isNotEmpty())
binding.composeMediaPreviewBar.visible(media.isNotEmpty())
updateSensitiveMediaToggle(viewModel.markMediaAsSensitive.value != false, viewModel.showContentWarning.value != false)
}
}
viewModel.poll.observe { poll ->
pollPreview.visible(poll != null)
poll?.let(pollPreview::setPoll)
binding.pollPreview.visible(poll != null)
poll?.let(binding.pollPreview::setPoll)
}
viewModel.scheduledAt.observe { scheduledAt ->
if (scheduledAt == null) {
composeScheduleView.resetSchedule()
binding.composeScheduleView.resetSchedule()
} else {
composeScheduleView.setDateTime(scheduledAt)
binding.composeScheduleView.setDateTime(scheduledAt)
}
updateScheduleButton()
}
@ -316,7 +319,7 @@ class ComposeActivity : BaseActivity(),
val active = poll == null
&& media!!.size != 4
&& (media.isEmpty() || media.first().type == QueuedMedia.Type.IMAGE)
enableButton(composeAddMediaButton, active, active)
enableButton(binding.composeAddMediaButton, active, active)
enablePollButton(media.isNullOrEmpty())
}.subscribe()
viewModel.uploadError.observe {
@ -324,52 +327,52 @@ class ComposeActivity : BaseActivity(),
}
viewModel.setupComplete.observe {
// Focus may have changed during view model setup, ensure initial focus is on the edit field
composeEditField.requestFocus()
binding.composeEditField.requestFocus()
}
}
}
private fun setupButtons() {
composeOptionsBottomSheet.listener = this
binding.composeOptionsBottomSheet.listener = this
composeOptionsBehavior = BottomSheetBehavior.from(composeOptionsBottomSheet)
addMediaBehavior = BottomSheetBehavior.from(addMediaBottomSheet)
scheduleBehavior = BottomSheetBehavior.from(composeScheduleView)
emojiBehavior = BottomSheetBehavior.from(emojiView)
composeOptionsBehavior = BottomSheetBehavior.from(binding.composeOptionsBottomSheet)
addMediaBehavior = BottomSheetBehavior.from(binding.addMediaBottomSheet)
scheduleBehavior = BottomSheetBehavior.from(binding.composeScheduleView)
emojiBehavior = BottomSheetBehavior.from(binding.emojiView)
enableButton(composeEmojiButton, clickable = false, colorActive = false)
enableButton(binding.composeEmojiButton, clickable = false, colorActive = false)
// Setup the interface buttons.
composeTootButton.setOnClickListener { onSendClicked() }
composeAddMediaButton.setOnClickListener { openPickDialog() }
composeToggleVisibilityButton.setOnClickListener { showComposeOptions() }
composeContentWarningButton.setOnClickListener { onContentWarningChanged() }
composeEmojiButton.setOnClickListener { showEmojis() }
composeHideMediaButton.setOnClickListener { toggleHideMedia() }
composeScheduleButton.setOnClickListener { onScheduleClick() }
composeScheduleView.setResetOnClickListener { resetSchedule() }
composeScheduleView.setListener(this)
atButton.setOnClickListener { atButtonClicked() }
hashButton.setOnClickListener { hashButtonClicked() }
binding.composeTootButton.setOnClickListener { onSendClicked() }
binding.composeAddMediaButton.setOnClickListener { openPickDialog() }
binding.composeToggleVisibilityButton.setOnClickListener { showComposeOptions() }
binding.composeContentWarningButton.setOnClickListener { onContentWarningChanged() }
binding.composeEmojiButton.setOnClickListener { showEmojis() }
binding.composeHideMediaButton.setOnClickListener { toggleHideMedia() }
binding.composeScheduleButton.setOnClickListener { onScheduleClick() }
binding.composeScheduleView.setResetOnClickListener { resetSchedule() }
binding.composeScheduleView.setListener(this)
binding.atButton.setOnClickListener { atButtonClicked() }
binding.hashButton.setOnClickListener { hashButtonClicked() }
val textColor = ThemeUtils.getColor(this, android.R.attr.textColorTertiary)
val cameraIcon = IconicsDrawable(this, GoogleMaterial.Icon.gmd_camera_alt).apply { colorInt = textColor; sizeDp = 18 }
actionPhotoTake.setCompoundDrawablesRelativeWithIntrinsicBounds(cameraIcon, null, null, null)
binding.actionPhotoTake.setCompoundDrawablesRelativeWithIntrinsicBounds(cameraIcon, null, null, null)
val imageIcon = IconicsDrawable(this, GoogleMaterial.Icon.gmd_image).apply { colorInt = textColor; sizeDp = 18 }
actionPhotoPick.setCompoundDrawablesRelativeWithIntrinsicBounds(imageIcon, null, null, null)
binding.actionPhotoPick.setCompoundDrawablesRelativeWithIntrinsicBounds(imageIcon, null, null, null)
val pollIcon = IconicsDrawable(this, GoogleMaterial.Icon.gmd_poll).apply { colorInt = textColor; sizeDp = 18 }
addPollTextActionTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(pollIcon, null, null, null)
binding.addPollTextActionTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(pollIcon, null, null, null)
actionPhotoTake.setOnClickListener { initiateCameraApp() }
actionPhotoPick.setOnClickListener { onMediaPick() }
addPollTextActionTextView.setOnClickListener { openPollDialog() }
binding.actionPhotoTake.setOnClickListener { initiateCameraApp() }
binding.actionPhotoPick.setOnClickListener { onMediaPick() }
binding.addPollTextActionTextView.setOnClickListener { openPollDialog() }
}
private fun setupActionBar() {
setSupportActionBar(toolbar)
setSupportActionBar(binding.toolbar)
supportActionBar?.run {
title = null
setDisplayHomeAsUpEnabled(true)
@ -388,40 +391,40 @@ class ComposeActivity : BaseActivity(),
val animateAvatars = preferences.getBoolean("animateGifAvatars", false)
loadAvatar(
activeAccount.profilePictureUrl,
composeAvatar,
binding.composeAvatar,
avatarSize / 8,
animateAvatars
)
composeAvatar.contentDescription = getString(R.string.compose_active_account_description,
binding.composeAvatar.contentDescription = getString(R.string.compose_active_account_description,
activeAccount.fullName)
}
private fun replaceTextAtCaret(text: CharSequence) {
// If you select "backward" in an editable, you get SelectionStart > SelectionEnd
val start = composeEditField.selectionStart.coerceAtMost(composeEditField.selectionEnd)
val end = composeEditField.selectionStart.coerceAtLeast(composeEditField.selectionEnd)
val textToInsert = if (start > 0 && !composeEditField.text[start - 1].isWhitespace()) {
val start = binding.composeEditField.selectionStart.coerceAtMost(binding.composeEditField.selectionEnd)
val end = binding.composeEditField.selectionStart.coerceAtLeast(binding.composeEditField.selectionEnd)
val textToInsert = if (start > 0 && !binding.composeEditField.text[start - 1].isWhitespace()) {
" $text"
} else {
text
}
composeEditField.text.replace(start, end, textToInsert)
binding.composeEditField.text.replace(start, end, textToInsert)
// Set the cursor after the inserted text
composeEditField.setSelection(start + text.length)
binding.composeEditField.setSelection(start + text.length)
}
fun prependSelectedWordsWith(text: CharSequence) {
// If you select "backward" in an editable, you get SelectionStart > SelectionEnd
val start = composeEditField.selectionStart.coerceAtMost(composeEditField.selectionEnd)
val end = composeEditField.selectionStart.coerceAtLeast(composeEditField.selectionEnd)
val editorText = composeEditField.text
val start = binding.composeEditField.selectionStart.coerceAtMost(binding.composeEditField.selectionEnd)
val end = binding.composeEditField.selectionStart.coerceAtLeast(binding.composeEditField.selectionEnd)
val editorText = binding.composeEditField.text
if (start == end) {
// No selection, just insert text at caret
editorText.insert(start, text)
// Set the cursor after the inserted text
composeEditField.setSelection(start + text.length)
binding.composeEditField.setSelection(start + text.length)
} else {
var wasWord: Boolean
var isWord = end < editorText.length && !Character.isWhitespace(editorText[end])
@ -447,7 +450,7 @@ class ComposeActivity : BaseActivity(),
}
// Keep the same text (including insertions) selected
composeEditField.setSelection(start, newEnd)
binding.composeEditField.setSelection(start, newEnd)
}
}
@ -466,7 +469,7 @@ class ComposeActivity : BaseActivity(),
}
private fun displayTransientError(@StringRes stringId: Int) {
val bar = Snackbar.make(activityCompose, stringId, Snackbar.LENGTH_LONG)
val bar = Snackbar.make(binding.activityCompose, stringId, Snackbar.LENGTH_LONG)
//necessary so snackbar is shown over everything
bar.view.elevation = resources.getDimension(R.dimen.compose_activity_snackbar_elevation)
bar.show()
@ -478,49 +481,49 @@ class ComposeActivity : BaseActivity(),
private fun updateSensitiveMediaToggle(markMediaSensitive: Boolean, contentWarningShown: Boolean) {
if (viewModel.media.value.isNullOrEmpty()) {
composeHideMediaButton.hide()
binding.composeHideMediaButton.hide()
} else {
composeHideMediaButton.show()
binding.composeHideMediaButton.show()
@ColorInt val color = if (contentWarningShown) {
composeHideMediaButton.setImageResource(R.drawable.ic_hide_media_24dp)
composeHideMediaButton.isClickable = false
binding.composeHideMediaButton.setImageResource(R.drawable.ic_hide_media_24dp)
binding.composeHideMediaButton.isClickable = false
ContextCompat.getColor(this, R.color.transparent_tusky_blue)
} else {
composeHideMediaButton.isClickable = true
binding.composeHideMediaButton.isClickable = true
if (markMediaSensitive) {
composeHideMediaButton.setImageResource(R.drawable.ic_hide_media_24dp)
binding.composeHideMediaButton.setImageResource(R.drawable.ic_hide_media_24dp)
ContextCompat.getColor(this, R.color.tusky_blue)
} else {
composeHideMediaButton.setImageResource(R.drawable.ic_eye_24dp)
binding.composeHideMediaButton.setImageResource(R.drawable.ic_eye_24dp)
ThemeUtils.getColor(this, android.R.attr.textColorTertiary)
}
}
composeHideMediaButton.drawable.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
binding.composeHideMediaButton.drawable.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
}
}
private fun updateScheduleButton() {
@ColorInt val color = if (composeScheduleView.time == null) {
@ColorInt val color = if (binding.composeScheduleView.time == null) {
ThemeUtils.getColor(this, android.R.attr.textColorTertiary)
} else {
ContextCompat.getColor(this, R.color.tusky_blue)
}
composeScheduleButton.drawable.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
binding.composeScheduleButton.drawable.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
}
private fun enableButtons(enable: Boolean) {
composeAddMediaButton.isClickable = enable
composeToggleVisibilityButton.isClickable = enable
composeEmojiButton.isClickable = enable
composeHideMediaButton.isClickable = enable
composeScheduleButton.isClickable = enable
composeTootButton.isEnabled = enable
binding.composeAddMediaButton.isClickable = enable
binding.composeToggleVisibilityButton.isClickable = enable
binding.composeEmojiButton.isClickable = enable
binding.composeHideMediaButton.isClickable = enable
binding.composeScheduleButton.isClickable = enable
binding.composeTootButton.isEnabled = enable
}
private fun setStatusVisibility(visibility: Status.Visibility) {
composeOptionsBottomSheet.setStatusVisibility(visibility)
composeTootButton.setStatusVisibility(visibility)
binding.composeOptionsBottomSheet.setStatusVisibility(visibility)
binding.composeTootButton.setStatusVisibility(visibility)
val iconRes = when (visibility) {
Status.Visibility.PUBLIC -> R.drawable.ic_public_24dp
@ -529,7 +532,7 @@ class ComposeActivity : BaseActivity(),
Status.Visibility.UNLISTED -> R.drawable.ic_lock_open_24dp
else -> R.drawable.ic_lock_open_24dp
}
composeToggleVisibilityButton.setImageResource(iconRes)
binding.composeToggleVisibilityButton.setImageResource(iconRes)
}
private fun showComposeOptions() {
@ -545,7 +548,7 @@ class ComposeActivity : BaseActivity(),
private fun onScheduleClick() {
if (viewModel.scheduledAt.value == null) {
composeScheduleView.openPickDateDialog()
binding.composeScheduleView.openPickDateDialog()
} else {
showScheduleView()
}
@ -563,7 +566,7 @@ class ComposeActivity : BaseActivity(),
}
private fun showEmojis() {
emojiView.adapter?.let {
binding.emojiView.adapter?.let {
if (it.itemCount == 0) {
val errorMessage = getString(R.string.error_no_custom_emojis, accountManager.activeAccount!!.domain)
Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT).show()
@ -626,10 +629,10 @@ class ComposeActivity : BaseActivity(),
val layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
layoutParams.setMargins(margin, margin, margin, marginBottom)
pollPreview.layoutParams = layoutParams
binding.pollPreview.layoutParams = layoutParams
pollPreview.setOnClickListener {
val popup = PopupMenu(this, pollPreview)
binding.pollPreview.setOnClickListener {
val popup = PopupMenu(this, binding.pollPreview)
val editId = 1
val removeId = 2
popup.menu.add(0, editId, 0, R.string.edit_poll)
@ -647,7 +650,7 @@ class ComposeActivity : BaseActivity(),
private fun removePoll() {
viewModel.poll.value = null
pollPreview.hide()
binding.pollPreview.hide()
}
override fun onVisibilityChanged(visibility: Status.Visibility) {
@ -658,39 +661,39 @@ class ComposeActivity : BaseActivity(),
@VisibleForTesting
fun calculateTextLength(): Int {
var offset = 0
val urlSpans = composeEditField.urls
val urlSpans = binding.composeEditField.urls
if (urlSpans != null) {
for (span in urlSpans) {
offset += max(0, span.url.length - MAXIMUM_URL_LENGTH)
}
}
var length = composeEditField.length() - offset
var length = binding.composeEditField.length() - offset
if (viewModel.showContentWarning.value!!) {
length += composeContentWarningField.length()
length += binding.composeContentWarningField.length()
}
return length
}
private fun updateVisibleCharactersLeft() {
val remainingLength = maximumTootCharacters - calculateTextLength()
composeCharactersLeftView.text = String.format(Locale.getDefault(), "%d", remainingLength)
binding.composeCharactersLeftView.text = String.format(Locale.getDefault(), "%d", remainingLength)
val textColor = if (remainingLength < 0) {
ContextCompat.getColor(this, R.color.tusky_red)
} else {
ThemeUtils.getColor(this, android.R.attr.textColorTertiary)
}
composeCharactersLeftView.setTextColor(textColor)
binding.composeCharactersLeftView.setTextColor(textColor)
}
private fun onContentWarningChanged() {
val showWarning = composeContentWarningBar.isGone
val showWarning = binding.composeContentWarningBar.isGone
viewModel.contentWarningChanged(showWarning)
updateVisibleCharactersLeft()
}
private fun verifyScheduledTime(): Boolean {
return composeScheduleView.verifyScheduledTime(composeScheduleView.getDateTime(viewModel.scheduledAt.value))
return binding.composeScheduleView.verifyScheduledTime(binding.composeScheduleView.getDateTime(viewModel.scheduledAt.value))
}
private fun onSendClicked() {
@ -725,14 +728,14 @@ class ComposeActivity : BaseActivity(),
private fun sendStatus() {
enableButtons(false)
val contentText = composeEditField.text.toString()
val contentText = binding.composeEditField.text.toString()
var spoilerText = ""
if (viewModel.showContentWarning.value!!) {
spoilerText = composeContentWarningField.text.toString()
spoilerText = binding.composeContentWarningField.text.toString()
}
val characterCount = calculateTextLength()
if ((characterCount <= 0 || contentText.isBlank()) && viewModel.media.value!!.isEmpty()) {
composeEditField.error = getString(R.string.error_empty)
binding.composeEditField.error = getString(R.string.error_empty)
enableButtons(true)
} else if (characterCount <= maximumTootCharacters) {
if (viewModel.media.value!!.isNotEmpty()) {
@ -747,7 +750,7 @@ class ComposeActivity : BaseActivity(),
})
} else {
composeEditField.error = getString(R.string.error_compose_character_limit)
binding.composeEditField.error = getString(R.string.error_compose_character_limit)
enableButtons(true)
}
}
@ -758,7 +761,7 @@ class ComposeActivity : BaseActivity(),
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
initiateMediaPicking()
} else {
val bar = Snackbar.make(activityCompose, R.string.error_media_upload_permission,
val bar = Snackbar.make(binding.activityCompose, R.string.error_media_upload_permission,
Snackbar.LENGTH_SHORT).apply {
}
@ -813,12 +816,12 @@ class ComposeActivity : BaseActivity(),
}
private fun enablePollButton(enable: Boolean) {
addPollTextActionTextView.isEnabled = enable
binding.addPollTextActionTextView.isEnabled = enable
val textColor = ThemeUtils.getColor(this,
if (enable) android.R.attr.textColorTertiary
else R.attr.textColorDisabled)
addPollTextActionTextView.setTextColor(textColor)
addPollTextActionTextView.compoundDrawablesRelative[0].colorFilter = PorterDuffColorFilter(textColor, PorterDuff.Mode.SRC_IN)
binding.addPollTextActionTextView.setTextColor(textColor)
binding.addPollTextActionTextView.compoundDrawablesRelative[0].colorFilter = PorterDuffColorFilter(textColor, PorterDuff.Mode.SRC_IN)
}
private fun removeMediaFromQueue(item: QueuedMedia) {
@ -879,19 +882,18 @@ class ComposeActivity : BaseActivity(),
}
private fun showContentWarning(show: Boolean) {
TransitionManager.beginDelayedTransition(composeContentWarningBar.parent as ViewGroup)
TransitionManager.beginDelayedTransition(binding.composeContentWarningBar.parent as ViewGroup)
@ColorInt val color = if (show) {
composeContentWarningBar.show()
composeContentWarningField.setSelection(composeContentWarningField.text.length)
composeContentWarningField.requestFocus()
binding.composeContentWarningBar.show()
binding.composeContentWarningField.setSelection(binding.composeContentWarningField.text.length)
binding.composeContentWarningField.requestFocus()
ContextCompat.getColor(this, R.color.tusky_blue)
} else {
composeContentWarningBar.hide()
composeEditField.requestFocus()
binding.composeContentWarningBar.hide()
binding.composeEditField.requestFocus()
ThemeUtils.getColor(this, android.R.attr.textColorTertiary)
}
composeContentWarningButton.drawable.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
binding.composeContentWarningButton.drawable.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -939,8 +941,8 @@ class ComposeActivity : BaseActivity(),
}
private fun handleCloseButton() {
val contentText = composeEditField.text.toString()
val contentWarning = composeContentWarningField.text.toString()
val contentText = binding.composeEditField.text.toString()
val contentWarning = binding.composeContentWarningField.text.toString()
if (viewModel.didChange(contentText, contentWarning)) {
AlertDialog.Builder(this)
.setMessage(R.string.compose_save_draft)
@ -974,8 +976,8 @@ class ComposeActivity : BaseActivity(),
private fun setEmojiList(emojiList: List<Emoji>?) {
if (emojiList != null) {
emojiView.adapter = EmojiAdapter(emojiList, this@ComposeActivity)
enableButton(composeEmojiButton, true, emojiList.isNotEmpty())
binding.emojiView.adapter = EmojiAdapter(emojiList, this@ComposeActivity)
enableButton(binding.composeEmojiButton, true, emojiList.isNotEmpty())
}
}

View file

@ -4,10 +4,10 @@ import android.os.Bundle
import com.keylesspalace.tusky.BaseActivity
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.components.instancemute.fragment.InstanceListFragment
import com.keylesspalace.tusky.databinding.ActivityAccountListBinding
import dagger.android.DispatchingAndroidInjector
import dagger.android.HasAndroidInjector
import javax.inject.Inject
import kotlinx.android.synthetic.main.toolbar_basic.*
class InstanceListActivity: BaseActivity(), HasAndroidInjector {
@ -16,9 +16,10 @@ class InstanceListActivity: BaseActivity(), HasAndroidInjector {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityAccountListBinding.inflate(layoutInflater)
setContentView(R.layout.activity_account_list)
setSupportActionBar(toolbar)
setSupportActionBar(binding.includedToolbar.toolbar)
supportActionBar?.apply {
setTitle(R.string.title_domain_mutes)
setDisplayHomeAsUpEnabled(true)

View file

@ -28,12 +28,12 @@ import com.keylesspalace.tusky.MainActivity
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.appstore.EventHub
import com.keylesspalace.tusky.appstore.PreferenceChangedEvent
import com.keylesspalace.tusky.databinding.ActivityPreferencesBinding
import com.keylesspalace.tusky.settings.PrefKeys
import com.keylesspalace.tusky.util.ThemeUtils
import com.keylesspalace.tusky.util.getNonNullString
import dagger.android.DispatchingAndroidInjector
import dagger.android.HasAndroidInjector
import kotlinx.android.synthetic.main.toolbar_basic.*
import javax.inject.Inject
class PreferencesActivity : BaseActivity(), SharedPreferences.OnSharedPreferenceChangeListener,
@ -48,12 +48,12 @@ class PreferencesActivity : BaseActivity(), SharedPreferences.OnSharedPreference
private var restartActivitiesOnExit: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_preferences)
val binding = ActivityPreferencesBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(toolbar)
setSupportActionBar(binding.includedToolbar.toolbar)
supportActionBar?.run {
setDisplayHomeAsUpEnabled(true)
setDisplayShowHomeEnabled(true)

View file

@ -22,11 +22,11 @@ import androidx.activity.viewModels
import com.keylesspalace.tusky.BottomSheetActivity
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.components.report.adapter.ReportPagerAdapter
import com.keylesspalace.tusky.databinding.ActivityReportBinding
import com.keylesspalace.tusky.di.ViewModelFactory
import com.keylesspalace.tusky.util.viewBinding
import dagger.android.DispatchingAndroidInjector
import dagger.android.HasAndroidInjector
import kotlinx.android.synthetic.main.activity_report.*
import kotlinx.android.synthetic.main.toolbar_basic.*
import javax.inject.Inject
class ReportActivity : BottomSheetActivity(), HasAndroidInjector {
@ -39,6 +39,8 @@ class ReportActivity : BottomSheetActivity(), HasAndroidInjector {
private val viewModel: ReportViewModel by viewModels { viewModelFactory }
private val binding by viewBinding(ActivityReportBinding::inflate)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val accountId = intent?.getStringExtra(ACCOUNT_ID)
@ -50,9 +52,9 @@ class ReportActivity : BottomSheetActivity(), HasAndroidInjector {
viewModel.init(accountId, accountUserName, intent?.getStringExtra(STATUS_ID))
setContentView(R.layout.activity_report)
setContentView(binding.root)
setSupportActionBar(toolbar)
setSupportActionBar(binding.includedToolbar.toolbar)
supportActionBar?.apply {
title = getString(R.string.report_username_format, viewModel.accountUserName)
@ -69,8 +71,8 @@ class ReportActivity : BottomSheetActivity(), HasAndroidInjector {
}
private fun initViewPager() {
wizard.isUserInputEnabled = false
wizard.adapter = ReportPagerAdapter(this)
binding.wizard.isUserInputEnabled = false
binding.wizard.adapter = ReportPagerAdapter(this)
}
private fun subscribeObservables() {
@ -96,18 +98,18 @@ class ReportActivity : BottomSheetActivity(), HasAndroidInjector {
}
private fun showPreviousScreen() {
when (wizard.currentItem) {
when (binding.wizard.currentItem) {
0 -> closeScreen()
1 -> showStatusesPage()
}
}
private fun showDonePage() {
wizard.currentItem = 2
binding.wizard.currentItem = 2
}
private fun showNotesPage() {
wizard.currentItem = 1
binding.wizard.currentItem = 1
}
private fun closeScreen() {
@ -115,7 +117,7 @@ class ReportActivity : BottomSheetActivity(), HasAndroidInjector {
}
private fun showStatusesPage() {
wizard.currentItem = 0
binding.wizard.currentItem = 0
}
companion object {

View file

@ -18,20 +18,19 @@ package com.keylesspalace.tusky.components.scheduled
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import androidx.activity.viewModels
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.keylesspalace.tusky.BaseActivity
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.components.compose.ComposeActivity
import com.keylesspalace.tusky.databinding.ActivityScheduledTootBinding
import com.keylesspalace.tusky.di.Injectable
import com.keylesspalace.tusky.di.ViewModelFactory
import com.keylesspalace.tusky.entity.ScheduledStatus
import com.keylesspalace.tusky.util.Status
import com.keylesspalace.tusky.util.hide
import com.keylesspalace.tusky.util.show
import kotlinx.android.synthetic.main.activity_scheduled_toot.*
import kotlinx.android.synthetic.main.toolbar_basic.*
import javax.inject.Inject
class ScheduledTootActivity : BaseActivity(), ScheduledTootActionListener, Injectable {
@ -39,31 +38,31 @@ class ScheduledTootActivity : BaseActivity(), ScheduledTootActionListener, Injec
@Inject
lateinit var viewModelFactory: ViewModelFactory
lateinit var viewModel: ScheduledTootViewModel
private val viewModel: ScheduledTootViewModel by viewModels { viewModelFactory }
private val adapter = ScheduledTootAdapter(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_scheduled_toot)
setSupportActionBar(toolbar)
val binding = ActivityScheduledTootBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.includedToolbar.toolbar)
supportActionBar?.run {
title = getString(R.string.title_scheduled_toot)
setDisplayHomeAsUpEnabled(true)
setDisplayShowHomeEnabled(true)
}
swipeRefreshLayout.setOnRefreshListener(this::refreshStatuses)
swipeRefreshLayout.setColorSchemeResources(R.color.tusky_blue)
binding.swipeRefreshLayout.setOnRefreshListener(this::refreshStatuses)
binding.swipeRefreshLayout.setColorSchemeResources(R.color.tusky_blue)
scheduledTootList.setHasFixedSize(true)
scheduledTootList.layoutManager = LinearLayoutManager(this)
binding.scheduledTootList.setHasFixedSize(true)
binding.scheduledTootList.layoutManager = LinearLayoutManager(this)
val divider = DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
scheduledTootList.addItemDecoration(divider)
scheduledTootList.adapter = adapter
viewModel = ViewModelProvider(this, viewModelFactory)[ScheduledTootViewModel::class.java]
binding.scheduledTootList.addItemDecoration(divider)
binding.scheduledTootList.adapter = adapter
viewModel.data.observe(this) {
adapter.submitList(it)
@ -72,31 +71,31 @@ class ScheduledTootActivity : BaseActivity(), ScheduledTootActionListener, Injec
viewModel.networkState.observe(this) { (status) ->
when(status) {
Status.SUCCESS -> {
progressBar.hide()
swipeRefreshLayout.isRefreshing = false
binding.progressBar.hide()
binding.swipeRefreshLayout.isRefreshing = false
if(viewModel.data.value?.loadedCount == 0) {
errorMessageView.setup(R.drawable.elephant_friend_empty, R.string.no_scheduled_status)
errorMessageView.show()
binding.errorMessageView.setup(R.drawable.elephant_friend_empty, R.string.no_scheduled_status)
binding.errorMessageView.show()
} else {
errorMessageView.hide()
binding.errorMessageView.hide()
}
}
Status.RUNNING -> {
errorMessageView.hide()
binding.errorMessageView.hide()
if(viewModel.data.value?.loadedCount ?: 0 > 0) {
swipeRefreshLayout.isRefreshing = true
binding.swipeRefreshLayout.isRefreshing = true
} else {
progressBar.show()
binding.progressBar.show()
}
}
Status.FAILED -> {
if(viewModel.data.value?.loadedCount ?: 0 >= 0) {
progressBar.hide()
swipeRefreshLayout.isRefreshing = false
errorMessageView.setup(R.drawable.elephant_error, R.string.error_generic) {
binding.progressBar.hide()
binding.swipeRefreshLayout.isRefreshing = false
binding.errorMessageView.setup(R.drawable.elephant_error, R.string.error_generic) {
refreshStatuses()
}
errorMessageView.show()
binding.errorMessageView.show()
}
}
}

View file

@ -26,10 +26,11 @@ import com.google.android.material.tabs.TabLayoutMediator
import com.keylesspalace.tusky.BottomSheetActivity
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.components.search.adapter.SearchPagerAdapter
import com.keylesspalace.tusky.databinding.ActivitySearchBinding
import com.keylesspalace.tusky.di.ViewModelFactory
import com.keylesspalace.tusky.util.viewBinding
import dagger.android.DispatchingAndroidInjector
import dagger.android.HasAndroidInjector
import kotlinx.android.synthetic.main.activity_search.*
import javax.inject.Inject
class SearchActivity : BottomSheetActivity(), HasAndroidInjector {
@ -41,10 +42,12 @@ class SearchActivity : BottomSheetActivity(), HasAndroidInjector {
private val viewModel: SearchViewModel by viewModels { viewModelFactory }
private val binding by viewBinding(ActivitySearchBinding::inflate)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search)
setSupportActionBar(toolbar)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
supportActionBar?.apply {
setDisplayHomeAsUpEnabled(true)
setDisplayShowHomeEnabled(true)
@ -55,9 +58,9 @@ class SearchActivity : BottomSheetActivity(), HasAndroidInjector {
}
private fun setupPages() {
pages.adapter = SearchPagerAdapter(this)
binding.pages.adapter = SearchPagerAdapter(this)
TabLayoutMediator(tabs, pages) {
TabLayoutMediator(binding.tabs, binding.pages) {
tab, position ->
tab.text = getPageTitle(position)
}.attach()