Add language dropdown to compose view (#2651)
* Add UI for selecting post language * Apply selected language when sending status * Save/restore post language with drafts * Fall back to english if the configured language isn't found in the locale list (no-NB) * Remove comment about no_NB * Move language dropdown to top of compose view * Preserve language when redrafting * Set default language to target post's language when replying * Add Tusky license header to new source file * Tweak language dropdown button width
This commit is contained in:
parent
c638ad7e6b
commit
0041acf2d4
28 changed files with 1140 additions and 28 deletions
|
|
@ -35,6 +35,7 @@ import android.view.KeyEvent
|
|||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ImageButton
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.PopupMenu
|
||||
|
|
@ -65,6 +66,7 @@ import com.keylesspalace.tusky.BaseActivity
|
|||
import com.keylesspalace.tusky.BuildConfig
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.adapter.EmojiAdapter
|
||||
import com.keylesspalace.tusky.adapter.LocaleAdapter
|
||||
import com.keylesspalace.tusky.adapter.OnEmojiSelectedListener
|
||||
import com.keylesspalace.tusky.components.compose.dialog.makeCaptionDialog
|
||||
import com.keylesspalace.tusky.components.compose.dialog.showAddPollDialog
|
||||
|
|
@ -244,6 +246,7 @@ class ComposeActivity :
|
|||
binding.composeScheduleView.setDateTime(composeOptions?.scheduledAt)
|
||||
}
|
||||
|
||||
setupLanguageSpinner(getInitialLanguage(composeOptions?.language))
|
||||
setupComposeField(preferences, viewModel.startingText)
|
||||
setupContentWarningField(composeOptions?.contentWarning)
|
||||
setupPollView()
|
||||
|
|
@ -476,6 +479,40 @@ class ComposeActivity :
|
|||
binding.addPollTextActionTextView.setOnClickListener { openPollDialog() }
|
||||
}
|
||||
|
||||
private fun setupLanguageSpinner(initialLanguage: String?) {
|
||||
val locales = Locale.getAvailableLocales()
|
||||
.filter { it.country.isNullOrEmpty() && it.script.isNullOrEmpty() && it.variant.isNullOrEmpty() } // Only "base" languages, "en" but not "en_DK"
|
||||
var currentLocaleIndex = locales.indexOfFirst { it.language == initialLanguage }
|
||||
if (currentLocaleIndex < 0) {
|
||||
Log.e(TAG, "Error looking up language tag '$initialLanguage', falling back to english")
|
||||
currentLocaleIndex = locales.indexOfFirst { it.language == "en" }
|
||||
}
|
||||
|
||||
val context = this
|
||||
binding.composePostLanguageButton.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>, view: View?, position: Int, id: Long) {
|
||||
viewModel.postLanguage = (parent.adapter.getItem(position) as Locale).language
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>) {
|
||||
parent.setSelection(locales.indexOfFirst { it.language == getInitialLanguage() })
|
||||
}
|
||||
}
|
||||
binding.composePostLanguageButton.apply {
|
||||
adapter = LocaleAdapter(context, android.R.layout.simple_spinner_dropdown_item, locales)
|
||||
setSelection(currentLocaleIndex)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInitialLanguage(language: String? = null): String {
|
||||
return if (language.isNullOrEmpty()) {
|
||||
// Setting the application ui preference sets the default locale
|
||||
Locale.getDefault().language
|
||||
} else {
|
||||
language
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupActionBar() {
|
||||
setSupportActionBar(binding.toolbar)
|
||||
supportActionBar?.run {
|
||||
|
|
@ -793,6 +830,10 @@ class ComposeActivity :
|
|||
return length
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
val selectedLanguage: String?
|
||||
get() = viewModel.postLanguage
|
||||
|
||||
private fun updateVisibleCharactersLeft() {
|
||||
val remainingLength = maximumTootCharacters - calculateTextLength()
|
||||
binding.composeCharactersLeftView.text = String.format(Locale.getDefault(), "%d", remainingLength)
|
||||
|
|
@ -1128,7 +1169,8 @@ class ComposeActivity :
|
|||
var scheduledAt: String? = null,
|
||||
var sensitive: Boolean? = null,
|
||||
var poll: NewPoll? = null,
|
||||
var modifiedInitialState: Boolean? = null
|
||||
var modifiedInitialState: Boolean? = null,
|
||||
var language: String? = null,
|
||||
) : Parcelable
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ class ComposeViewModel @Inject constructor(
|
|||
private var replyingStatusAuthor: String? = null
|
||||
private var replyingStatusContent: String? = null
|
||||
internal var startingText: String? = null
|
||||
internal var postLanguage: String? = null
|
||||
private var draftId: Int = 0
|
||||
private var scheduledTootId: String? = null
|
||||
private var startingContentWarning: String = ""
|
||||
|
|
@ -261,7 +262,8 @@ class ComposeViewModel @Inject constructor(
|
|||
mediaDescriptions = mediaDescriptions,
|
||||
poll = poll.value,
|
||||
failedToSend = false,
|
||||
scheduledAt = scheduledAt.value
|
||||
scheduledAt = scheduledAt.value,
|
||||
language = postLanguage,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -308,7 +310,8 @@ class ComposeViewModel @Inject constructor(
|
|||
draftId = draftId,
|
||||
idempotencyKey = randomAlphanumericString(16),
|
||||
retries = 0,
|
||||
mediaProcessed = mediaProcessed
|
||||
mediaProcessed = mediaProcessed,
|
||||
language = postLanguage,
|
||||
)
|
||||
|
||||
serviceClient.sendToot(tootToSend)
|
||||
|
|
@ -426,6 +429,7 @@ class ComposeViewModel @Inject constructor(
|
|||
draftId = composeOptions?.draftId ?: 0
|
||||
scheduledTootId = composeOptions?.scheduledTootId
|
||||
startingText = composeOptions?.content
|
||||
postLanguage = composeOptions?.language
|
||||
|
||||
val tootVisibility = composeOptions?.visibility ?: Status.Visibility.UNKNOWN
|
||||
if (tootVisibility.num != Status.Visibility.UNKNOWN.num) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue