mirror of
https://github.com/tateisu/SubwayTooter
synced 2024-12-22 23:28:15 +01:00
投稿画面に言語選択を追加。言語選択の候補に「Web設定を使う」を追加。
This commit is contained in:
parent
f57ac32c78
commit
d800557796
2
.gitignore
vendored
2
.gitignore
vendored
@ -128,3 +128,5 @@ _Emoji/*.log
|
||||
_Emoji/*.txt
|
||||
|
||||
detektReport/
|
||||
|
||||
.idea/deploymentTargetDropDown.xml
|
||||
|
@ -37,10 +37,7 @@ import jp.juggler.subwaytooter.pref.PrefB
|
||||
import jp.juggler.subwaytooter.pref.PrefS
|
||||
import jp.juggler.subwaytooter.table.AcctColor
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.util.DecodeOptions
|
||||
import jp.juggler.subwaytooter.util.EmojiDecoder
|
||||
import jp.juggler.subwaytooter.util.NetworkEmojiInvalidator
|
||||
import jp.juggler.subwaytooter.util.openBrowser
|
||||
import jp.juggler.subwaytooter.util.*
|
||||
import jp.juggler.util.*
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.encodeToString
|
||||
@ -152,20 +149,7 @@ class ActAccountSetting : AppCompatActivity(), View.OnClickListener,
|
||||
internal var visibility = TootVisibility.Public
|
||||
|
||||
private val languages by lazy {
|
||||
ArrayList<Pair<String, String>>().apply {
|
||||
add(Pair("", getString(R.string.device_language)))
|
||||
val nameMap = HashMap<String, String>()
|
||||
addAll(
|
||||
Locale.getAvailableLocales().mapNotNull { locale ->
|
||||
locale.language.takeIf { it.length == 2 || it.contains('-') }
|
||||
?.also { code -> nameMap[code] = "$code ${locale.displayLanguage}" }
|
||||
}
|
||||
.toSet()
|
||||
.toList()
|
||||
.sorted()
|
||||
.map { Pair(it, nameMap[it]!!) }
|
||||
)
|
||||
}
|
||||
loadLanguageList()
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
@ -610,8 +594,8 @@ class ActAccountSetting : AppCompatActivity(), View.OnClickListener,
|
||||
account.movieTranscodeBitrate = etMovieBitrate.text.toString()
|
||||
account.movieTranscodeFramerate = etMovieFrameRate.text.toString()
|
||||
account.movieTranscodeSquarePixels = etMovieSquarePixels.text.toString()
|
||||
account.lang =
|
||||
languages.elementAtOrNull(spLanguageCode.selectedItemPosition)?.first ?: ""
|
||||
account.lang = languages.elementAtOrNull(spLanguageCode.selectedItemPosition)?.first
|
||||
?: SavedAccount.LANG_WEB
|
||||
}
|
||||
|
||||
account.saveSetting()
|
||||
|
@ -110,6 +110,10 @@ class ActPost : AppCompatActivity(),
|
||||
|
||||
var density: Float = 0f
|
||||
|
||||
val languages by lazy{
|
||||
loadLanguageList()
|
||||
}
|
||||
|
||||
private lateinit var progressChannel: Channel<Unit>
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
@ -434,5 +438,13 @@ class ActPost : AppCompatActivity(),
|
||||
|
||||
views.etContent.contentMineTypeArray = AttachmentUploader.acceptableMimeTypes.toTypedArray()
|
||||
views.etContent.contentCallback = { addAttachment(it) }
|
||||
|
||||
views.spLanguage.adapter =ArrayAdapter(
|
||||
this,
|
||||
android.R.layout.simple_spinner_item,
|
||||
languages.map { it.second }.toTypedArray()
|
||||
).apply {
|
||||
setDropDownViewResource(R.layout.lv_spinner_dropdown)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,6 +131,7 @@ fun ActMain.performQuickPost(account: SavedAccount?) {
|
||||
editStatusId = null,
|
||||
emojiMapCustom = App1.custom_emoji_lister.getMapNonBlocking(account),
|
||||
useQuoteToot = false,
|
||||
lang = account.lang,
|
||||
).runSuspend()
|
||||
|
||||
if (postResult is PostResult.Normal) {
|
||||
|
@ -9,12 +9,14 @@ import jp.juggler.subwaytooter.table.AcctColor
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.util.*
|
||||
import org.jetbrains.anko.textColor
|
||||
import kotlin.math.max
|
||||
|
||||
private val log = LogCategory("ActPostAccount")
|
||||
|
||||
fun ActPost.selectAccount(a: SavedAccount?) {
|
||||
this.account = a
|
||||
|
||||
|
||||
completionHelper.setInstance(a)
|
||||
|
||||
if (a == null) {
|
||||
@ -28,6 +30,8 @@ fun ActPost.selectAccount(a: SavedAccount?) {
|
||||
App1.custom_emoji_lister.getList(a)
|
||||
}
|
||||
|
||||
views.spLanguage.setSelection(max(0,languages.indexOfFirst { it.first == a.lang}))
|
||||
|
||||
val ac = AcctColor.load(a)
|
||||
views.btnAccount.text = ac.nickname
|
||||
|
||||
|
@ -4,14 +4,22 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import jp.juggler.subwaytooter.*
|
||||
import jp.juggler.subwaytooter.ActMain
|
||||
import jp.juggler.subwaytooter.ActPost
|
||||
import jp.juggler.subwaytooter.App1
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.actmain.onCompleteActPost
|
||||
import jp.juggler.subwaytooter.api.entity.*
|
||||
import jp.juggler.subwaytooter.api.entity.TootPollsType
|
||||
import jp.juggler.subwaytooter.api.entity.TootVisibility
|
||||
import jp.juggler.subwaytooter.api.entity.unknownHostAndDomain
|
||||
import jp.juggler.subwaytooter.dialog.ActionsDialog
|
||||
import jp.juggler.subwaytooter.pref.PrefB
|
||||
import jp.juggler.subwaytooter.table.PostDraft
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.util.*
|
||||
import jp.juggler.subwaytooter.util.DecodeOptions
|
||||
import jp.juggler.subwaytooter.util.PostAttachment
|
||||
import jp.juggler.subwaytooter.util.PostImpl
|
||||
import jp.juggler.subwaytooter.util.PostResult
|
||||
import jp.juggler.util.*
|
||||
|
||||
private val log = LogCategory("ActPostExtra")
|
||||
@ -316,7 +324,7 @@ fun ActPost.performPost() {
|
||||
}
|
||||
}
|
||||
|
||||
val postResult = PostImpl(
|
||||
val postResult = PostImpl(
|
||||
activity = activity,
|
||||
account = account,
|
||||
content = views.etContent.text.toString().trim { it <= ' ' },
|
||||
@ -339,9 +347,11 @@ fun ActPost.performPost() {
|
||||
editStatusId = states.editStatusId,
|
||||
emojiMapCustom = App1.custom_emoji_lister.getMapNonBlocking(account),
|
||||
useQuoteToot = views.cbQuote.isChecked,
|
||||
lang = languages.elementAtOrNull(views.spLanguage.selectedItemPosition)?.first
|
||||
?: SavedAccount.LANG_WEB
|
||||
).runSuspend()
|
||||
when(postResult){
|
||||
is PostResult.Normal ->{
|
||||
when (postResult) {
|
||||
is PostResult.Normal -> {
|
||||
val data = Intent()
|
||||
data.putExtra(ActPost.EXTRA_POSTED_ACCT, postResult.targetAccount.acct.ascii)
|
||||
postResult.status.id.putTo(data, ActPost.EXTRA_POSTED_STATUS_ID)
|
||||
@ -363,10 +373,10 @@ fun ActPost.performPost() {
|
||||
this@performPost.finish()
|
||||
}
|
||||
}
|
||||
is PostResult.Scheduled ->{
|
||||
is PostResult.Scheduled -> {
|
||||
showToast(false, getString(R.string.scheduled_status_sent))
|
||||
val data = Intent()
|
||||
data.putExtra(ActPost.EXTRA_POSTED_ACCT,postResult. targetAccount.acct.ascii)
|
||||
data.putExtra(ActPost.EXTRA_POSTED_ACCT, postResult.targetAccount.acct.ascii)
|
||||
|
||||
if (isMultiWindowPost) {
|
||||
resetText()
|
||||
|
@ -15,7 +15,6 @@ import jp.juggler.subwaytooter.notification.PollingWorker
|
||||
import jp.juggler.subwaytooter.util.LinkHelper
|
||||
import jp.juggler.util.*
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.math.max
|
||||
|
||||
class SavedAccount(
|
||||
@ -88,33 +87,25 @@ class SavedAccount(
|
||||
|
||||
private val extraJson = JsonObject()
|
||||
|
||||
var movieTranscodeMode: Int by JsonProperty(
|
||||
extraJson,
|
||||
"movieTranscodeMode",
|
||||
0)
|
||||
private val jsonDelegates = JsonDelegates(extraJson)
|
||||
|
||||
var movieTranscodeBitrate: String by JsonProperty(
|
||||
extraJson,
|
||||
"movieTranscodeBitrate",
|
||||
"2000000")
|
||||
var movieTranscodeFramerate: String by JsonProperty(
|
||||
extraJson,
|
||||
"movieTranscodeFramerate",
|
||||
"30")
|
||||
var movieTranscodeSquarePixels: String by JsonProperty(
|
||||
extraJson,
|
||||
"movieTranscodeSquarePixels",
|
||||
"2304000")
|
||||
@JsonPropInt("movieTranscodeMode", 0)
|
||||
var movieTranscodeMode by jsonDelegates.int
|
||||
|
||||
var lang: String by JsonProperty(
|
||||
extraJson,
|
||||
"lang",
|
||||
"")
|
||||
@JsonPropString("movieTranscodeBitrate", "2000000")
|
||||
var movieTranscodeBitrate by jsonDelegates.string
|
||||
|
||||
var notification_status_reference: Boolean by JsonProperty(
|
||||
extraJson,
|
||||
"notification_status_reference",
|
||||
true)
|
||||
@JsonPropString("movieTranscodeFramerate", "30")
|
||||
var movieTranscodeFramerate by jsonDelegates.string
|
||||
|
||||
@JsonPropString("movieTranscodeSquarePixels", "2304000")
|
||||
var movieTranscodeSquarePixels by jsonDelegates.string
|
||||
|
||||
@JsonPropString("lang2", LANG_WEB)
|
||||
var lang by jsonDelegates.string
|
||||
|
||||
@JsonPropBoolean("notification_status_reference", true)
|
||||
var notification_status_reference by jsonDelegates.boolean
|
||||
|
||||
init {
|
||||
val tmpAcct = Acct.parse(acctArg)
|
||||
@ -601,6 +592,9 @@ class SavedAccount(
|
||||
}
|
||||
}
|
||||
|
||||
const val LANG_WEB = "(web)"
|
||||
const val LANG_DEVICE = "(device)"
|
||||
|
||||
private const val REGISTER_KEY_UNREGISTERED = "unregistered"
|
||||
|
||||
fun clearRegistrationCache() {
|
||||
|
@ -55,6 +55,7 @@ class PostImpl(
|
||||
val editStatusId: EntityId?,
|
||||
val emojiMapCustom: HashMap<String, CustomEmoji>?,
|
||||
var useQuoteToot: Boolean,
|
||||
var lang : String,
|
||||
) {
|
||||
companion object {
|
||||
private val log = LogCategory("PostImpl")
|
||||
@ -283,7 +284,16 @@ class PostImpl(
|
||||
|
||||
private fun encodeParamsMastodon(json: JsonObject, instance: TootInstance) {
|
||||
|
||||
json["language"] = account.lang.notBlank() ?: Locale.getDefault().language
|
||||
when(val lang = lang.trim()){
|
||||
// Web設定に従うなら指定しない
|
||||
SavedAccount.LANG_WEB,"" -> Unit
|
||||
// 端末の言語コード
|
||||
SavedAccount.LANG_DEVICE->
|
||||
json["language"] = Locale.getDefault().language
|
||||
// その他
|
||||
else->
|
||||
json["language"] = lang
|
||||
}
|
||||
|
||||
visibilityChecked?.let { json["visibility"] = it.strMastodon }
|
||||
|
||||
|
@ -0,0 +1,24 @@
|
||||
package jp.juggler.subwaytooter.util
|
||||
|
||||
import android.content.Context
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import java.util.*
|
||||
|
||||
// 言語コードと表示文字列のペアのリストを返す
|
||||
fun Context.loadLanguageList() =
|
||||
ArrayList<Pair<String, String>>().apply {
|
||||
add(Pair(SavedAccount.LANG_WEB, getString(R.string.use_web_settings)))
|
||||
add(Pair(SavedAccount.LANG_DEVICE, getString(R.string.device_language)))
|
||||
val nameMap = HashMap<String, String>()
|
||||
addAll(
|
||||
Locale.getAvailableLocales().mapNotNull { locale ->
|
||||
locale.language.takeIf { it.length == 2 || it.contains('-') }
|
||||
?.also { code -> nameMap[code] = "$code ${locale.displayLanguage}" }
|
||||
}
|
||||
.toSet()
|
||||
.toList()
|
||||
.sorted()
|
||||
.map { Pair(it, nameMap[it]!!) }
|
||||
)
|
||||
}
|
@ -12,6 +12,7 @@ class JsonException : RuntimeException {
|
||||
|
||||
private const val CHAR0 = '\u0000'
|
||||
|
||||
@Suppress("RegExpUnnecessaryNonCapturingGroup")
|
||||
private val reDecimal = """(?:\A-0\z)|[.eE]""".toRegex()
|
||||
|
||||
// Tests if the value should be tried as a decimal.
|
||||
|
50
app/src/main/java/jp/juggler/util/JsonDelegate.kt
Normal file
50
app/src/main/java/jp/juggler/util/JsonDelegate.kt
Normal file
@ -0,0 +1,50 @@
|
||||
package jp.juggler.util
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
|
||||
private interface JsonAnnotationBase :Annotation
|
||||
annotation class JsonPropInt(val key:String,val defVal:Int)
|
||||
annotation class JsonPropString(val key:String,val defVal:String)
|
||||
annotation class JsonPropBoolean(val key:String,val defVal:Boolean)
|
||||
|
||||
class JsonDelegate<T>(val parent: JsonDelegates)
|
||||
|
||||
class JsonDelegates(val src: JsonObject){
|
||||
val int = JsonDelegate<Int>(this)
|
||||
val string = JsonDelegate<String>(this)
|
||||
val boolean = JsonDelegate<Boolean>(this)
|
||||
}
|
||||
|
||||
private fun getMetaString(property: KProperty<*>) =
|
||||
property.findAnnotation<JsonPropString>()
|
||||
?: error("${property.name}, required=String, defined=(missing)")
|
||||
|
||||
operator fun JsonDelegate<String>.getValue(thisRef: Any?, property: KProperty<*>): String =
|
||||
getMetaString(property).let { parent.src.string(it.key) ?: it.defVal }
|
||||
|
||||
operator fun JsonDelegate<String>.setValue(thisRef: Any?, property: KProperty<*>, value: String) {
|
||||
getMetaString(property).let { parent.src[it.key] = value }
|
||||
}
|
||||
|
||||
private fun getMetaInt(property: KProperty<*>) =
|
||||
property.findAnnotation<JsonPropInt>()
|
||||
?: error("${property.name}, required=Int, defined=(missing)")
|
||||
|
||||
operator fun JsonDelegate<Int>.getValue(thisRef: Any?, property: KProperty<*>): Int =
|
||||
getMetaInt(property).let { parent.src.int(it.key) ?: it.defVal }
|
||||
|
||||
operator fun JsonDelegate<Int>.setValue(thisRef: Any?, property: KProperty<*>, value: Int) {
|
||||
getMetaInt(property).let { parent.src[it.key] = value }
|
||||
}
|
||||
|
||||
private fun getMetaBoolean(property: KProperty<*>) =
|
||||
property.findAnnotation<JsonPropBoolean>()
|
||||
?: error("${property.name}, required=Boolean, defined=(missing)")
|
||||
|
||||
operator fun JsonDelegate<Boolean>.getValue(thisRef: Any?, property: KProperty<*>): Boolean =
|
||||
getMetaBoolean(property).let { parent.src.boolean(it.key) ?: it.defVal }
|
||||
|
||||
operator fun JsonDelegate<Boolean>.setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) {
|
||||
getMetaBoolean(property).let { parent.src[it.key] = value }
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package jp.juggler.util
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class JsonProperty<ValueType>(
|
||||
val src: JsonObject,
|
||||
val key: String,
|
||||
val defVal: ValueType,
|
||||
)
|
||||
|
||||
operator fun JsonProperty<String>.getValue(thisRef: Any?, property: KProperty<*>): String {
|
||||
return src.string(key) ?: defVal
|
||||
}
|
||||
|
||||
operator fun JsonProperty<String>.setValue(thisRef: Any?, property: KProperty<*>, value: String) {
|
||||
src[key] = value
|
||||
}
|
||||
|
||||
operator fun JsonProperty<Int>.getValue(thisRef: Any?, property: KProperty<*>): Int {
|
||||
return src.int(key) ?: defVal
|
||||
}
|
||||
|
||||
operator fun JsonProperty<Int>.setValue(thisRef: Any?, property: KProperty<*>, value: Int) {
|
||||
src[key] = value
|
||||
}
|
||||
operator fun JsonProperty<Boolean>.getValue(thisRef: Any?, property: KProperty<*>): Boolean {
|
||||
return src.boolean(key) ?: defVal
|
||||
}
|
||||
|
||||
operator fun JsonProperty<Boolean>.setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) {
|
||||
src[key] = value
|
||||
}
|
@ -209,7 +209,7 @@
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/status" />
|
||||
android:text="@string/content" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btnFeaturedTag"
|
||||
@ -254,6 +254,27 @@
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:baselineAligned="false"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:text="@string/language" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spLanguage"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_weight="1" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -1147,4 +1147,6 @@
|
||||
<string name="emoji_picker_custom_of">カスタム: %1$s</string>
|
||||
<string name="others" >その他</string>
|
||||
<string name="post_error_attachments_duplicated">Misskeyは添付データの重複を許可していません。</string>
|
||||
<string name="use_web_settings">Web設定を使う</string>
|
||||
<string name="content">本文</string>
|
||||
</resources>
|
||||
|
@ -1156,4 +1156,6 @@
|
||||
<string name="emoji_picker_custom_of">Custom: %1$s</string>
|
||||
<string name="others">Others</string>
|
||||
<string name="post_error_attachments_duplicated">Misskey does not allow duplicate in attachments.</string>
|
||||
<string name="use_web_settings">(Use web setting)</string>
|
||||
<string name="content">Content</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user