マニフェストの微調整。ボタン無効状態で色を薄くする。選択してコピー画面のデザイン変更。強調表示する単語の編集画面のデザイン変更。

This commit is contained in:
tateisu 2021-05-22 18:07:23 +09:00
parent 3c3f7dff66
commit a5d16a6934
26 changed files with 751 additions and 698 deletions

View File

@ -6,7 +6,8 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
@ -18,18 +19,15 @@
<!-- (自アプリ以外で)指定URLを開けるアプリの存在確認 -->
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
</intent>
@ -52,7 +50,6 @@
<!-- Simejiマッシュルームプラグインの存在確認 -->
<intent>
<action android:name="com.adamrocker.android.simeji.ACTION_INTERCEPT" />
<category android:name="com.adamrocker.android.simeji.REPLACE"/>
</intent>
<!-- <intent>-->

View File

@ -82,6 +82,9 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
@kotlinx.serialization.Serializable
data class State(
var propName: String = "",
@kotlinx.serialization.Serializable(with = UriOrNullSerializer::class)
var uriCameraImage: Uri? = null,
)
var state = State()
@ -181,8 +184,6 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
internal var visibility = TootVisibility.Public
private var uriCameraImage: Uri? = null
///////////////////////////////////////////////////////////////////
@ -212,33 +213,33 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
private val arAddAttachment = activityResultHandler { ar ->
val data = ar?.data
if (data != null && ar.resultCode == Activity.RESULT_OK) {
data.handleGetContentResult(contentResolver).firstOrNull()?.let {
addAttachment(
state.propName,
it.uri,
it.mimeType?.notEmpty() ?: contentResolver.getType(it.uri)
)
}
}
if (ar?.resultCode == Activity.RESULT_OK)
ar.data
?.handleGetContentResult(contentResolver)
?.firstOrNull()
?.let {
addAttachment(
state.propName,
it.uri,
it.mimeType?.notEmpty() ?: contentResolver.getType(it.uri)
)
}
}
private val arCameraImage = activityResultHandler { ar ->
if (ar?.resultCode == Activity.RESULT_OK) {
// 画像のURL
val uri = ar.data?.data ?: uriCameraImage
val uri = ar.data?.data ?: state.uriCameraImage
if (uri != null) {
val type = contentResolver.getType(uri)
addAttachment(state.propName, uri, type)
}
} else {
// 失敗したら DBからデータを削除
val uriCameraImage = this.uriCameraImage
if (uriCameraImage != null) {
contentResolver.delete(uriCameraImage, null, null)
this.uriCameraImage = null
state.uriCameraImage?.let{
contentResolver.delete(it, null, null)
}
state.uriCameraImage = null
}
}
@ -279,7 +280,12 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString(ACTIVITY_STATE, Json.encodeToString(state))
val encodedState = Json.encodeToString(state)
log.d("encodedState=$encodedState")
val decodedState :State = Json.decodeFromString(encodedState)
log.d("encodedState.uriCameraImage=${decodedState.uriCameraImage}")
outState.putString(ACTIVITY_STATE,encodedState )
}
override fun onStop() {
@ -591,34 +597,34 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
loading = false
val enabled = !a.isPseudo
btnAccessToken.isEnabled = enabled
btnInputAccessToken.isEnabled = enabled
btnVisibility.isEnabled = enabled
btnPushSubscription.isEnabled = enabled
btnPushSubscriptionNotForce.isEnabled = enabled
btnResetNotificationTracking.isEnabled = enabled
btnNotificationSoundEdit.isEnabled = Build.VERSION.SDK_INT < 26 && enabled
btnNotificationSoundReset.isEnabled = Build.VERSION.SDK_INT < 26 && enabled
btnNotificationStyleEdit.isEnabled = Build.VERSION.SDK_INT >= 26 && enabled
btnNotificationStyleEditReply.isEnabled = Build.VERSION.SDK_INT >= 26 && enabled
btnAccessToken.isEnabledAlpha = enabled
btnInputAccessToken.isEnabledAlpha = enabled
btnVisibility.isEnabledAlpha = enabled
btnPushSubscription.isEnabledAlpha = enabled
btnPushSubscriptionNotForce.isEnabledAlpha = enabled
btnResetNotificationTracking.isEnabledAlpha = enabled
btnNotificationSoundEdit.isEnabledAlpha = Build.VERSION.SDK_INT < 26 && enabled
btnNotificationSoundReset.isEnabledAlpha = Build.VERSION.SDK_INT < 26 && enabled
btnNotificationStyleEdit.isEnabledAlpha = Build.VERSION.SDK_INT >= 26 && enabled
btnNotificationStyleEditReply.isEnabledAlpha = Build.VERSION.SDK_INT >= 26 && enabled
cbNotificationMention.isEnabled = enabled
cbNotificationBoost.isEnabled = enabled
cbNotificationFavourite.isEnabled = enabled
cbNotificationFollow.isEnabled = enabled
cbNotificationFollowRequest.isEnabled = enabled
cbNotificationReaction.isEnabled = enabled
cbNotificationVote.isEnabled = enabled
cbNotificationPost.isEnabled = enabled
cbNotificationMention.isEnabledAlpha = enabled
cbNotificationBoost.isEnabledAlpha = enabled
cbNotificationFavourite.isEnabledAlpha = enabled
cbNotificationFollow.isEnabledAlpha = enabled
cbNotificationFollowRequest.isEnabledAlpha = enabled
cbNotificationReaction.isEnabledAlpha = enabled
cbNotificationVote.isEnabledAlpha = enabled
cbNotificationPost.isEnabledAlpha = enabled
cbConfirmFollow.isEnabled = enabled
cbConfirmFollowLockedUser.isEnabled = enabled
cbConfirmUnfollow.isEnabled = enabled
cbConfirmBoost.isEnabled = enabled
cbConfirmFavourite.isEnabled = enabled
cbConfirmUnboost.isEnabled = enabled
cbConfirmUnfavourite.isEnabled = enabled
cbConfirmToot.isEnabled = enabled
cbConfirmFollow.isEnabledAlpha = enabled
cbConfirmFollowLockedUser.isEnabledAlpha = enabled
cbConfirmUnfollow.isEnabledAlpha = enabled
cbConfirmBoost.isEnabledAlpha = enabled
cbConfirmFavourite.isEnabledAlpha = enabled
cbConfirmUnboost.isEnabledAlpha = enabled
cbConfirmUnfavourite.isEnabledAlpha = enabled
cbConfirmToot.isEnabledAlpha = enabled
val ti = TootInstance.getCached(a.apiHost)
if (ti == null) {
@ -1004,21 +1010,21 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
etNote.setText(loadingText)
// 初期状態では編集不可能
btnProfileAvatar.isEnabled = false
btnProfileHeader.isEnabled = false
etDisplayName.isEnabled = false
btnDisplayName.isEnabled = false
etNote.isEnabled = false
btnNote.isEnabled = false
cbLocked.isEnabled = false
btnProfileAvatar.isEnabledAlpha = false
btnProfileHeader.isEnabledAlpha = false
etDisplayName.isEnabledAlpha = false
btnDisplayName.isEnabledAlpha = false
etNote.isEnabledAlpha = false
btnNote.isEnabledAlpha = false
cbLocked.isEnabledAlpha = false
for (et in listEtFieldName) {
et.setText(loadingText)
et.isEnabled = false
et.isEnabledAlpha = false
}
for (et in listEtFieldValue) {
et.setText(loadingText)
et.isEnabled = false
et.isEnabledAlpha = false
}
// 疑似アカウントなら編集不可のまま
@ -1126,13 +1132,13 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
cbLocked.isChecked = src.locked
// 編集可能にする
btnProfileAvatar.isEnabled = true
btnProfileHeader.isEnabled = true
etDisplayName.isEnabled = true
btnDisplayName.isEnabled = true
etNote.isEnabled = true
btnNote.isEnabled = true
cbLocked.isEnabled = true
btnProfileAvatar.isEnabledAlpha = true
btnProfileHeader.isEnabledAlpha = true
etDisplayName.isEnabledAlpha = true
btnDisplayName.isEnabledAlpha = true
etNote.isEnabledAlpha = true
btnNote.isEnabledAlpha = true
cbLocked.isEnabledAlpha = true
if (src.source?.fields != null) {
val fields = src.source.fields
@ -1149,7 +1155,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
}
)
et.setText(text)
et.isEnabled = true
et.isEnabledAlpha = true
val invalidator = NetworkEmojiInvalidator(handler, et)
invalidator.register(text)
}
@ -1165,7 +1171,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
}
)
et.setText(text)
et.isEnabled = true
et.isEnabledAlpha = true
val invalidator = NetworkEmojiInvalidator(handler, et)
invalidator.register(text)
}
@ -1186,7 +1192,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
}
)
et.setText(text)
et.isEnabled = true
et.isEnabledAlpha = true
val invalidator = NetworkEmojiInvalidator(handler, et)
invalidator.register(text)
}
@ -1203,7 +1209,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
}
)
et.text = text
et.isEnabled = true
et.isEnabledAlpha = true
val invalidator = NetworkEmojiInvalidator(handler, et)
invalidator.register(text)
}
@ -1580,11 +1586,11 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
val values = ContentValues()
values.put(MediaStore.Images.Media.TITLE, filename)
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
uriCameraImage =
contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
state.uriCameraImage = uri
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
intent.putExtra(MediaStore.EXTRA_OUTPUT, uriCameraImage)
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
state.propName = propName
arCameraImage.launch(intent)

View File

@ -17,7 +17,6 @@ import android.view.Window
import android.widget.*
import androidx.annotation.ColorInt
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SwitchCompat
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
@ -78,26 +77,20 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
private val arNoop = activityResultHandler { }
private val arImportAppData = activityResultHandler { ar ->
val data = ar?.data
if (data != null && ar.resultCode == RESULT_OK) {
data.handleGetContentResult(contentResolver).firstOrNull()?.uri?.let {
importAppData2(false, it)
}
}
if (ar?.resultCode == RESULT_OK)
ar.data?.handleGetContentResult(contentResolver)
?.firstOrNull()
?.uri?.let { importAppData2(false, it) }
}
val arTimelineFont = activityResultHandler { ar ->
val data = ar?.data
if (data != null && ar.resultCode == RESULT_OK) {
handleFontResult(AppSettingItem.TIMELINE_FONT, data, "TimelineFont")
}
if (ar?.resultCode == RESULT_OK)
ar.data?.let { handleFontResult(AppSettingItem.TIMELINE_FONT, it, "TimelineFont") }
}
val arTimelineFontBold = activityResultHandler { ar ->
val data = ar?.data
if (data != null && ar.resultCode == RESULT_OK) {
handleFontResult(AppSettingItem.TIMELINE_FONT_BOLD, data, "TimelineFontBold")
}
if (ar?.resultCode == RESULT_OK)
ar.data?.let { handleFontResult(AppSettingItem.TIMELINE_FONT_BOLD, it, "TimelineFontBold") }
}
override fun onCreate(savedInstanceState: Bundle?) {
@ -513,7 +506,7 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
SettingType.Section -> {
btnAction.vg(true)
btnAction.text = name
btnAction.isEnabled = item.enabled
btnAction.isEnabledAlpha = item.enabled
btnAction.setOnClickListener {
load(item.cast()!!, null)
}
@ -522,7 +515,7 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
SettingType.Action -> {
btnAction.vg(true)
btnAction.text = name
btnAction.isEnabled = item.enabled
btnAction.isEnabledAlpha = item.enabled
btnAction.setOnClickListener {
item.action(activity)
}
@ -533,7 +526,7 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
item.pref.cast() ?: error("$name has no boolean pref")
checkBox.vg(false) // skip animation
checkBox.text = name
checkBox.isEnabled = item.enabled
checkBox.isEnabledAlpha = item.enabled
checkBox.isChecked = bp(pref)
checkBox.vg(true)
}
@ -544,7 +537,7 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
showCaption(name)
swSwitch.vg(false) // skip animation
setSwitchColor(pref, swSwitch)
swSwitch.isEnabled = item.enabled
swSwitch.isEnabledAlpha = item.enabled
swSwitch.isChecked = bp(pref)
swSwitch.vg(true)
}
@ -566,8 +559,8 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
llButtonBar.vg(true)
vColor.vg(true)
vColor.setBackgroundColor(ip(pref))
btnEdit.isEnabled = item.enabled
btnReset.isEnabled = item.enabled
btnEdit.isEnabledAlpha = item.enabled
btnReset.isEnabledAlpha = item.enabled
btnEdit.setOnClickListener {
colorTarget = item
val color = ip(pref)
@ -591,7 +584,7 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
showCaption(name)
spSpinner.vg(true)
spSpinner.isEnabled = item.enabled
spSpinner.isEnabledAlpha = item.enabled
val pi = item.pref
if (pi is IntPref) {
@ -842,8 +835,6 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
fun importAppData1() {
try {
val intent = intentOpenDocument("*/*")
arImportAppData.launch(intent)
} catch (ex: Throwable) {
showToast(ex, "importAppData(1) failed.")

View File

@ -1,6 +1,7 @@
package jp.juggler.subwaytooter
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
import android.graphics.Color
import android.media.RingtoneManager
@ -8,7 +9,7 @@ import android.net.Uri
import android.os.Bundle
import android.view.View
import android.widget.CompoundButton
import android.widget.TextView
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SwitchCompat
import com.jrummyapps.android.colorpicker.ColorPickerDialog
@ -27,20 +28,27 @@ class ActHighlightWordEdit
internal val log = LogCategory("ActHighlightWordEdit")
const val EXTRA_ITEM = "item"
private const val COLOR_DIALOG_ID_TEXT = 1
private const val COLOR_DIALOG_ID_BACKGROUND = 2
fun createIntent(activity: Activity, item: HighlightWord) =
private const val STATE_ITEM = "item"
private const val EXTRA_ITEM_ID = "itemId"
private const val EXTRA_INITIAL_TEXT = "initialText"
fun createIntent(activity: Activity, itemId:Long) =
Intent(activity, ActHighlightWordEdit::class.java).apply {
putExtra(EXTRA_ITEM, item.encodeJson().toString())
putExtra(EXTRA_ITEM_ID,itemId)
}
fun createIntent(activity: Activity, initialText:String) =
Intent(activity, ActHighlightWordEdit::class.java).apply {
putExtra(EXTRA_INITIAL_TEXT, initialText)
}
}
internal lateinit var item: HighlightWord
private lateinit var tvName: TextView
private lateinit var etName: EditText
private lateinit var swSound: SwitchCompat
private lateinit var swSpeech: SwitchCompat
@ -54,24 +62,19 @@ class ActHighlightWordEdit
if (uri is Uri) {
item.sound_uri = uri.toString()
item.sound_type = HighlightWord.SOUND_TYPE_CUSTOM
swSound.isChecked = true
showSound()
}
}
}
private fun makeResult() {
try {
val data = Intent()
data.putExtra(EXTRA_ITEM, item.encodeJson().toString())
setResult(Activity.RESULT_OK, data)
} catch (ex: JsonException) {
throw RuntimeException(ex)
}
}
override fun onBackPressed() {
makeResult()
super.onBackPressed()
AlertDialog.Builder(this)
.setCancelable(true)
.setMessage(R.string.discard_changes)
.setPositiveButton(R.string.no, null)
.setNegativeButton(R.string.yes) { _,_ -> finish() }
.show()
}
override fun onCreate(savedInstanceState: Bundle?) {
@ -80,17 +83,49 @@ class ActHighlightWordEdit
App1.setActivityTheme(this)
initUI()
val src = (savedInstanceState?.getString(EXTRA_ITEM) ?: intent.getStringExtra(EXTRA_ITEM))
?.decodeJsonObject()
setResult(RESULT_CANCELED)
if (src == null) {
fun loadData():HighlightWord? {
savedInstanceState
?.getString(STATE_ITEM)
?.decodeJsonObject()
?.let { return HighlightWord(it) }
intent
?.getStringExtra(EXTRA_INITIAL_TEXT)
?.let { return HighlightWord(it) }
intent
?.getLongExtra(EXTRA_ITEM_ID, -1L)
?.takeIf { it > 0L }
?.let { return HighlightWord.load(it) }
return null
}
val item = loadData()
if(item==null) {
log.d("missing source data")
finish()
return
}
item = HighlightWord(src)
showSampleText()
this.item = item
etName.setText( item.name )
showSound()
showColor()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
try {
// ui may not initialized yet.
uiToData()
}catch(ex:Throwable) {
log.e(ex,"uiToData failed.")
}
item.encodeJson().toString().let{ outState.putString(STATE_ITEM,it) }
}
@ -98,7 +133,7 @@ class ActHighlightWordEdit
setContentView(R.layout.act_highlight_edit)
App1.initEdgeToEdge(this)
tvName = findViewById(R.id.tvName)
etName = findViewById(R.id.etName)
swSound = findViewById(R.id.swSound)
swSound.setOnCheckedChangeListener(this)
@ -114,57 +149,48 @@ class ActHighlightWordEdit
R.id.btnBackgroundColorEdit,
R.id.btnBackgroundColorReset,
R.id.btnNotificationSoundEdit,
R.id.btnNotificationSoundReset
R.id.btnNotificationSoundReset,
R.id.btnDiscard,
R.id.btnSave,
).forEach {
findViewById<View>(it)?.setOnClickListener(this)
}
}
private fun showSampleText() {
bBusy = true
try {
swSound.isChecked = item.sound_type != HighlightWord.SOUND_TYPE_NONE
swSpeech.isChecked = item.speech != 0
tvName.text = item.name
tvName.setBackgroundColor(item.color_bg) // may 0
tvName.textColor = item.color_fg.notZero()
?: attrColor(android.R.attr.textColorPrimary)
} finally {
bBusy = false
}
}
override fun onClick(v: View) {
when (v.id) {
R.id.btnDiscard ->
finish()
R.id.btnTextColorEdit -> openColorPicker(COLOR_DIALOG_ID_TEXT, item.color_fg)
R.id.btnSave ->
save()
R.id.btnTextColorEdit ->
openColorPicker(COLOR_DIALOG_ID_TEXT, item.color_fg)
R.id.btnTextColorReset -> {
item.color_fg = 0
showSampleText()
showColor()
}
R.id.btnBackgroundColorEdit -> openColorPicker(
COLOR_DIALOG_ID_BACKGROUND,
item.color_bg
)
R.id.btnBackgroundColorEdit ->
openColorPicker(COLOR_DIALOG_ID_BACKGROUND,item.color_bg)
R.id.btnBackgroundColorReset -> {
item.color_bg = 0
showSampleText()
showColor()
}
R.id.btnNotificationSoundEdit -> openNotificationSoundPicker()
R.id.btnNotificationSoundEdit ->
openNotificationSoundPicker()
R.id.btnNotificationSoundReset -> {
item.sound_uri = null
item.sound_type =
if (swSound.isChecked) HighlightWord.SOUND_TYPE_DEFAULT else HighlightWord.SOUND_TYPE_NONE
item.sound_type = if (swSound.isChecked)
HighlightWord.SOUND_TYPE_DEFAULT
else
HighlightWord.SOUND_TYPE_NONE
showSound()
}
}
@ -172,24 +198,7 @@ class ActHighlightWordEdit
override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) {
if (bBusy) return
when (buttonView.id) {
R.id.swSound -> {
if (!isChecked) {
item.sound_type = HighlightWord.SOUND_TYPE_NONE
} else {
item.sound_type =
if (item.sound_uri?.isEmpty() != false) HighlightWord.SOUND_TYPE_DEFAULT else HighlightWord.SOUND_TYPE_CUSTOM
}
}
R.id.swSpeech -> {
item.speech = when (isChecked) {
false -> 0
else -> 1
}
}
}
uiToData()
}
private fun openColorPicker(id: Int, initial_color: Int) {
@ -212,11 +221,31 @@ class ActHighlightWordEdit
COLOR_DIALOG_ID_TEXT -> item.color_fg = color or Color.BLACK
COLOR_DIALOG_ID_BACKGROUND -> item.color_bg = color.notZero() ?: 0x01000000
}
showSampleText()
showColor()
}
//////////////////////////////////////////////////////////////////
private fun showSound(){
bBusy = true
try {
swSound.isChecked = item.sound_type != HighlightWord.SOUND_TYPE_NONE
swSpeech.isChecked = item.speech != 0
} finally {
bBusy = false
}
}
private fun showColor(){
bBusy = true
try {
etName.setBackgroundColor(item.color_bg) // may 0
etName.textColor = item.color_fg.notZero() ?: attrColor(android.R.attr.textColorPrimary)
} finally {
bBusy = false
}
}
private fun openNotificationSoundPicker() {
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER)
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION)
@ -229,9 +258,41 @@ class ActHighlightWordEdit
}
val chooser = Intent.createChooser(intent, getString(R.string.notification_sound))
arNotificationSound.launch(chooser)
}
private fun uiToData(){
item.name = etName.text.toString().trim{ it <= ' ' || it == ' '}
item.sound_type = when {
!swSound.isChecked -> HighlightWord.SOUND_TYPE_NONE
item.sound_uri?.notEmpty() == null -> HighlightWord.SOUND_TYPE_DEFAULT
else -> HighlightWord.SOUND_TYPE_CUSTOM
}
item.speech = when (swSpeech.isChecked) {
false -> 0
else -> 1
}
}
private fun save(){
uiToData()
if( item.name.isEmpty() ) {
showToast(true, R.string.cant_leave_empty_keyword)
return
}
val other = HighlightWord.load(item.name)
if( other != null && other.id != item.id) {
showToast(true, R.string.cant_save_duplicated_keyword)
return
}
item.save(this)
showToast(false,R.string.saved)
setResult(RESULT_OK)
finish()
}
}

View File

@ -1,6 +1,5 @@
package jp.juggler.subwaytooter
import android.app.Dialog
import android.content.Context
import android.media.Ringtone
import android.media.RingtoneManager
@ -17,7 +16,6 @@ import com.woxthebox.draglistview.DragItemAdapter
import com.woxthebox.draglistview.DragListView
import com.woxthebox.draglistview.swipe.ListSwipeHelper
import com.woxthebox.draglistview.swipe.ListSwipeItem
import jp.juggler.subwaytooter.dialog.DlgTextInput
import jp.juggler.subwaytooter.table.HighlightWord
import jp.juggler.util.*
import java.lang.ref.WeakReference
@ -36,19 +34,12 @@ class ActHighlightWordList : AppCompatActivity(), View.OnClickListener {
private var last_ringtone : WeakReference<Ringtone>? = null
private val arEdit = activityResultHandler {ar->
val data = ar?.data
if(data != null && ar.resultCode == RESULT_OK){
try {
data.getStringExtra(ActHighlightWordEdit.EXTRA_ITEM)
?.decodeJsonObject()
?.let{
HighlightWord(it).save(this)
loadData()
}
} catch(ex : Throwable) {
throw RuntimeException("can't load data", ex)
}
private val arEdit = activityResultHandler { ar->
try {
if( ar?.resultCode == RESULT_OK )
loadData()
} catch(ex : Throwable) {
throw RuntimeException("can't load data", ex)
}
}
@ -263,39 +254,15 @@ class ActHighlightWordList : AppCompatActivity(), View.OnClickListener {
}
private fun create() {
DlgTextInput.show(
this,
getString(R.string.new_item),
"",
callback = object : DlgTextInput.Callback {
override fun onEmptyError() {
showToast(true, R.string.word_empty)
}
override fun onOK(dialog : Dialog, text : String) {
var item = HighlightWord.load(text)
if(item == null) {
item = HighlightWord(text)
item.save(this@ActHighlightWordList)
loadData()
}
edit(item)
dialog.dismissSafe()
}
})
arEdit.launch(
ActHighlightWordEdit.createIntent(this, "")
)
}
private fun edit(oldItem : HighlightWord) {
try {
arEdit.launch(
ActHighlightWordEdit.createIntent(this, oldItem)
)
} catch(ex : JsonException) {
throw RuntimeException(ex)
}
arEdit.launch(
ActHighlightWordEdit.createIntent(this, oldItem.id)
)
}
private fun stopLastRingtone() {

View File

@ -378,8 +378,7 @@ class ActLanguageFilter : AsyncActivity(), View.OnClickListener {
})
if (item != null) {
etLanguage.isEnabled = false
btnPresets.isEnabled = false
etLanguage.isEnabledAlpha = false
btnPresets.setEnabledColor(
activity,
R.drawable.ic_edit,

View File

@ -223,10 +223,8 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
cbMute = findViewById(R.id.cbMute)
val enablePaging = media_list.size > 1
btnPrevious.isEnabled = enablePaging
btnNext.isEnabled = enablePaging
btnPrevious.alpha = if (enablePaging) 1f else 0.3f
btnNext.alpha = if (enablePaging) 1f else 0.3f
btnPrevious.isEnabledAlpha = enablePaging
btnNext.isEnabledAlpha = enablePaging
btnPrevious.setOnClickListener(this)
btnNext.setOnClickListener(this)

View File

@ -132,8 +132,8 @@ class ActNickname : AppCompatActivity(), View.OnClickListener, ColorPickerDialog
btnNotificationSoundReset.setOnClickListener(this)
val bBefore8 = Build.VERSION.SDK_INT < 26
btnNotificationSoundEdit.isEnabled = bBefore8
btnNotificationSoundReset.isEnabled = bBefore8
btnNotificationSoundEdit.isEnabledAlpha = bBefore8
btnNotificationSoundReset.isEnabledAlpha = bBefore8
etNickname.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(

View File

@ -4,8 +4,8 @@ import android.app.SearchManager
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.view.Menu
import android.view.MenuItem
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import jp.juggler.subwaytooter.api.entity.TootAccount
@ -17,201 +17,210 @@ import jp.juggler.subwaytooter.util.CustomShareTarget
import jp.juggler.subwaytooter.util.TootTextEncoder
import jp.juggler.util.*
class ActText : AppCompatActivity(), View.OnClickListener {
companion object {
internal val log = LogCategory("ActText")
internal const val RESULT_SEARCH_MSP = RESULT_FIRST_USER + 1
internal const val RESULT_SEARCH_TS = RESULT_FIRST_USER + 2
internal const val RESULT_SEARCH_NOTESTOCK = RESULT_FIRST_USER + 3
internal const val EXTRA_TEXT = "text"
internal const val EXTRA_CONTENT_START = "content_start"
internal const val EXTRA_CONTENT_END = "content_end"
internal const val EXTRA_ACCOUNT_DB_ID = "account_db_id"
fun createIntent(
activity : ActMain,
access_info : SavedAccount,
status : TootStatus
) = Intent(activity, ActText::class.java).apply {
putExtra(EXTRA_ACCOUNT_DB_ID, access_info.db_id)
TootTextEncoder.encodeStatus(this, activity, access_info, status)
}
class ActText : AppCompatActivity() {
fun createIntent(
activity : ActMain,
access_info : SavedAccount,
who : TootAccount
) = Intent(activity, ActText::class.java).apply {
putExtra(EXTRA_ACCOUNT_DB_ID, access_info.db_id)
TootTextEncoder.encodeAccount(this, activity, access_info, who)
}
companion object {
}
private lateinit var etText : EditText
private lateinit var btnTranslate : Button
private val selection : String
get() {
val s = etText.selectionStart
val e = etText.selectionEnd
val text = etText.text.toString()
return if(s == e) {
text
} else {
text.substring(s, e)
}
}
private var account : SavedAccount? = null
override fun onCreate(savedInstanceState : Bundle?) {
super.onCreate(savedInstanceState)
App1.setActivityTheme(this)
val intent = intent
account = SavedAccount.loadAccount(this, intent.getLongExtra(EXTRA_ACCOUNT_DB_ID, - 1L))
initUI()
if(savedInstanceState == null) {
val sv = intent.getStringExtra(EXTRA_TEXT) ?: ""
val content_start = intent.getIntExtra(EXTRA_CONTENT_START, 0)
val content_end = intent.getIntExtra(EXTRA_CONTENT_END, sv.length)
etText.setText(sv)
// Android 9 以降ではフォーカスがないとsetSelectionできない
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
etText.requestFocus()
etText.hideKeyboard()
}
etText.setSelection(content_start, content_end)
}
}
internal fun initUI() {
setContentView(R.layout.act_text)
App1.initEdgeToEdge(this)
Styler.fixHorizontalMargin(findViewById(R.id.svFooterBar))
Styler.fixHorizontalMargin(findViewById(R.id.svContent))
etText = findViewById(R.id.etText)
btnTranslate = findViewById(R.id.btnTranslate)
btnTranslate.setOnClickListener(this)
findViewById<View>(R.id.btnCopy).setOnClickListener(this)
findViewById<View>(R.id.btnSearch).setOnClickListener(this)
findViewById<View>(R.id.btnSend).setOnClickListener(this)
findViewById<View>(R.id.btnMuteWord).setOnClickListener(this)
findViewById<View>(R.id.btnSearchTS).setOnClickListener(this)
val btnKeywordFilter : View = findViewById(R.id.btnKeywordFilter)
btnKeywordFilter.setOnClickListener(this)
btnKeywordFilter.isEnabled = account?.isPseudo == false
}
override fun onClick(v : View) {
when(v.id) {
R.id.btnCopy -> selection.copyToClipboard(this)
R.id.btnSearch -> search()
R.id.btnSend -> send()
R.id.btnMuteWord -> muteWord()
R.id.btnTranslate -> CustomShare.invoke(
this,
selection,
CustomShareTarget.Translate
)
R.id.btnSearchTS -> searchToot(RESULT_SEARCH_TS)
internal val log = LogCategory("ActText")
R.id.btnSearchNotestock -> searchToot(RESULT_SEARCH_NOTESTOCK)
internal const val RESULT_SEARCH_MSP = RESULT_FIRST_USER + 1
internal const val RESULT_SEARCH_TS = RESULT_FIRST_USER + 2
internal const val RESULT_SEARCH_NOTESTOCK = RESULT_FIRST_USER + 3
R.id.btnKeywordFilter -> keywordFilter()
}
}
private fun send() {
try {
val intent = Intent()
intent.action = Intent.ACTION_SEND
intent.type = "text/plain"
intent.putExtra(Intent.EXTRA_TEXT, selection)
startActivity(intent)
} catch(ex : Throwable) {
log.trace(ex)
showToast(ex, "send failed.")
}
}
private fun search() {
val sv = selection
if(sv.isEmpty()) {
showToast(false, "please select search keyword")
return
}
try {
val intent = Intent(Intent.ACTION_WEB_SEARCH)
intent.putExtra(SearchManager.QUERY, sv)
if(intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
} catch(ex : Throwable) {
log.trace(ex)
showToast(ex, "search failed.")
}
}
private fun searchToot(@Suppress("SameParameterValue") resultCode : Int) {
val sv = selection
if(sv.isEmpty()) {
showToast(false, "please select search keyword")
return
}
try {
val data = Intent()
data.putExtra(Intent.EXTRA_TEXT, sv)
setResult(resultCode, data)
finish()
} catch(ex : Throwable) {
log.trace(ex)
}
}
private fun muteWord() {
try {
MutedWord.save(selection)
App1.getAppState(this).onMuteUpdated()
showToast(false, R.string.word_was_muted)
} catch(ex : Throwable) {
log.trace(ex)
showToast(ex, "muteWord failed.")
}
}
private fun keywordFilter() {
val account = this.account
if(account?.isPseudo != false) return
ActKeywordFilter.open(this, account, initial_phrase = selection)
}
internal const val EXTRA_TEXT = "text"
internal const val EXTRA_CONTENT_START = "content_start"
internal const val EXTRA_CONTENT_END = "content_end"
internal const val EXTRA_ACCOUNT_DB_ID = "account_db_id"
fun createIntent(
activity: ActMain,
access_info: SavedAccount,
status: TootStatus
) = Intent(activity, ActText::class.java).apply {
putExtra(EXTRA_ACCOUNT_DB_ID, access_info.db_id)
TootTextEncoder.encodeStatus(this, activity, access_info, status)
}
fun createIntent(
activity: ActMain,
access_info: SavedAccount,
who: TootAccount
) = Intent(activity, ActText::class.java).apply {
putExtra(EXTRA_ACCOUNT_DB_ID, access_info.db_id)
TootTextEncoder.encodeAccount(this, activity, access_info, who)
}
}
private var account: SavedAccount? = null
private lateinit var etText: EditText
private val selection: String
get() {
val s = etText.selectionStart
val e = etText.selectionEnd
val text = etText.text.toString()
return if (s == e) {
text
} else {
text.substring(s, e)
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.btnCopy -> selection.copyToClipboard(this)
R.id.btnSearch -> search()
R.id.btnSend -> send()
R.id.btnMuteWord -> muteWord()
R.id.btnTranslate -> CustomShare.invoke(
this,
selection,
CustomShareTarget.Translate
)
R.id.btnSearchTS -> searchToot(RESULT_SEARCH_TS)
R.id.btnSearchNotestock -> searchToot(RESULT_SEARCH_NOTESTOCK)
R.id.btnKeywordFilter -> keywordFilter()
R.id.btnHighlight -> highlight()
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
else -> return super.onOptionsItemSelected(item)
}
return true
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.act_text, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
menu.findItem(R.id.btnKeywordFilter)?.apply {
isEnabled = account?.isPseudo == false
}
return super.onPrepareOptionsMenu(menu)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
App1.setActivityTheme(this, noActionBar = true)
val intent = intent
account = SavedAccount.loadAccount(this, intent.getLongExtra(EXTRA_ACCOUNT_DB_ID, -1L))
initUI()
if (savedInstanceState == null) {
val sv = intent.getStringExtra(EXTRA_TEXT) ?: ""
val content_start = intent.getIntExtra(EXTRA_CONTENT_START, 0)
val content_end = intent.getIntExtra(EXTRA_CONTENT_END, sv.length)
etText.setText(sv)
// Android 9 以降ではフォーカスがないとsetSelectionできない
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
etText.requestFocus()
etText.hideKeyboard()
}
etText.setSelection(content_start, content_end)
}
}
internal fun initUI() {
setContentView(R.layout.act_text)
etText = findViewById(R.id.etText)
App1.initEdgeToEdge(this)
Styler.fixHorizontalMargin(etText)
setSupportActionBar(findViewById(R.id.toolbar))
supportActionBar?.apply{
setDisplayHomeAsUpEnabled(false)
setHomeButtonEnabled(false)
}
}
private fun send() {
selection.trim().notEmpty()?.let {
try {
val intent = Intent()
intent.action = Intent.ACTION_SEND
intent.type = "text/plain"
intent.putExtra(Intent.EXTRA_TEXT, it)
startActivity(intent)
} catch (ex: Throwable) {
log.trace(ex)
showToast(ex, "send failed.")
}
}
}
private fun search() {
selection.trim().notEmpty()?.let {
try {
val intent = Intent(Intent.ACTION_WEB_SEARCH)
intent.putExtra(SearchManager.QUERY, it)
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
} catch (ex: Throwable) {
log.trace(ex)
showToast(ex, "search failed.")
}
}
}
private fun searchToot(@Suppress("SameParameterValue") resultCode: Int) {
selection.trim().notEmpty()?.let {
try {
val data = Intent()
data.putExtra(Intent.EXTRA_TEXT, it)
setResult(resultCode, data)
finish()
} catch (ex: Throwable) {
log.trace(ex)
}
}
}
private fun muteWord() {
selection.trim().notEmpty()?.let {
try {
MutedWord.save(it)
App1.getAppState(this).onMuteUpdated()
showToast(false, R.string.word_was_muted)
} catch (ex: Throwable) {
log.trace(ex)
showToast(ex, "muteWord failed.")
}
}
}
private fun keywordFilter() {
selection.trim().notEmpty()?.let {
val account = this.account
if (account?.isPseudo != false) return
ActKeywordFilter.open(this, account, initial_phrase = it)
}
}
private fun highlight() {
selection.trim().notEmpty()?.let {
startActivity(ActHighlightWordEdit.createIntent(this, it))
}
}
}

View File

@ -125,11 +125,11 @@ fun ColumnViewHolder.showAnnouncements(force: Boolean = true) {
)
btnAnnouncementsPrev.vg(expand)?.run {
isEnabled = enablePaging
btnAnnouncementsPrev.vg(expand)?.apply {
isEnabledAlpha = enablePaging
}
btnAnnouncementsNext.vg(expand)?.run {
isEnabled = enablePaging
btnAnnouncementsNext.vg(expand)?.apply {
isEnabledAlpha = enablePaging
}
tvAnnouncementsCaption.textColor = content_color

View File

@ -5,6 +5,7 @@ import android.text.TextUtils
import android.view.View
import android.view.animation.AlphaAnimation
import android.view.animation.Animation
import jp.juggler.util.isEnabledAlpha
import jp.juggler.util.notZero
import jp.juggler.util.vg
import org.jetbrains.anko.textColor
@ -76,9 +77,7 @@ fun ColumnViewHolder.showError(message: String) {
}
fun ColumnViewHolder.showColumnCloseButton() {
val dont_close = column?.dont_close ?: return
btnColumnClose.isEnabled = !dont_close
btnColumnClose.alpha = if (dont_close) 0.3f else 1f
column?.dont_close?.let{ btnColumnClose.isEnabledAlpha = !it }
}
internal fun ColumnViewHolder.showContent(

View File

@ -16,6 +16,7 @@ import jp.juggler.subwaytooter.drawable.PollPlotDrawable
import jp.juggler.subwaytooter.table.SavedAccount
import jp.juggler.subwaytooter.util.NetworkEmojiInvalidator
import jp.juggler.subwaytooter.view.EnqueteTimerView
import jp.juggler.util.isEnabledAlpha
import jp.juggler.util.jsonObject
import jp.juggler.util.showToast
import jp.juggler.util.toPostRequestBuilder
@ -173,7 +174,7 @@ fun ItemViewHolder.makeEnqueteChoiceView(
extra_invalidator_list.add(invalidator)
invalidator.register(text)
if (!canVote) {
b.isEnabled = false
b.isEnabledAlpha = false
} else {
b.isChecked = item.checked
b.setOnCheckedChangeListener { _, checked ->

View File

@ -14,10 +14,7 @@ import jp.juggler.subwaytooter.util.openBrowser
import jp.juggler.subwaytooter.util.openCustomTab
import jp.juggler.subwaytooter.view.MyLinkMovementMethod
import jp.juggler.subwaytooter.view.MyNetworkImageView
import jp.juggler.util.LogCategory
import jp.juggler.util.neatSpaces
import jp.juggler.util.notEmpty
import jp.juggler.util.showToast
import jp.juggler.util.*
import org.conscrypt.OpenSSLX509Certificate
internal class ViewHolderHeaderInstance(
@ -90,17 +87,17 @@ internal class ViewHolderHeaderInstance(
tvVersion.text = "?"
tvTitle.text = "?"
btnEmail.text = "?"
btnEmail.isEnabled = false
btnEmail.isEnabledAlpha = false
tvDescription.text = "?"
tvShortDescription.text = "?"
ivThumbnail.setImageUrl(App1.pref, 0f, null)
tvLanguages.text = "?"
tvInvitesEnabled.text = "?"
btnContact.text = "?"
btnContact.isEnabled = false
btnAbout.isEnabled = false
btnAboutMore.isEnabled = false
btnExplore.isEnabled = false
btnContact.isEnabledAlpha = false
btnAbout.isEnabledAlpha = false
btnAboutMore.isEnabledAlpha = false
btnExplore.isEnabledAlpha = false
} else {
val uri = instance.uri ?: ""
val hasUri = uri.isNotEmpty()
@ -112,23 +109,23 @@ internal class ViewHolderHeaderInstance(
"${host.pretty}\n${host.ascii}"
}
btnInstance.isEnabled = hasUri
btnAbout.isEnabled = hasUri
btnAboutMore.isEnabled = hasUri
btnExplore.isEnabled = hasUri
btnInstance.isEnabledAlpha = hasUri
btnAbout.isEnabledAlpha = hasUri
btnAboutMore.isEnabledAlpha = hasUri
btnExplore.isEnabledAlpha = hasUri
tvVersion.text = instance.version ?: ""
tvTitle.text = instance.title ?: ""
val email = instance.email ?: ""
btnEmail.text = email
btnEmail.isEnabled = email.isNotEmpty()
btnEmail.isEnabledAlpha = email.isNotEmpty()
val contact_acct =
instance.contact_account?.let { who -> "@${who.username}@${who.apDomain.pretty}" }
?: ""
btnContact.text = contact_acct
btnContact.isEnabled = contact_acct.isNotEmpty()
btnContact.isEnabledAlpha = contact_acct.isNotEmpty()
tvLanguages.text = instance.languages?.joinToString(", ") ?: ""
tvInvitesEnabled.text = when(instance.invites_enabled) {

View File

@ -11,6 +11,7 @@ import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import jp.juggler.subwaytooter.R
import jp.juggler.subwaytooter.table.SavedAccount
import jp.juggler.util.isEnabledAlpha
class DlgConfirmMail(
val activity: AppCompatActivity,
@ -38,7 +39,7 @@ class DlgConfirmMail(
}
cbUpdateMailAddress.setOnCheckedChangeListener { _, isChecked ->
etEmail.isEnabled = isChecked
etEmail.isEnabledAlpha = isChecked
}
arrayOf(

View File

@ -250,7 +250,7 @@ class DlgListMember(
}
private fun showList(_list : ArrayList<TootList>?) {
btnCreateList.isEnabled = _list != null
btnCreateList.isEnabledAlpha = _list != null
adapter.item_list.clear()
when {
_list == null -> adapter.item_list.add(ErrorItem(activity.getString(R.string.cant_access_list)))

View File

@ -12,6 +12,7 @@ import android.widget.*
import jp.juggler.subwaytooter.R
import jp.juggler.subwaytooter.api.entity.Host
import jp.juggler.util.LogCategory
import jp.juggler.util.isEnabledAlpha
import jp.juggler.util.showToast
import java.io.BufferedReader
import java.io.InputStreamReader

View File

@ -81,7 +81,22 @@ class HighlightWord {
return null
}
fun load(id:Long) : HighlightWord? {
try {
App1.database.query(table, null, selection_id, arrayOf(id.toString()), null, null, null)
.use { cursor ->
if(cursor.moveToNext()) {
return HighlightWord(cursor)
}
}
} catch(ex : Throwable) {
log.trace(ex)
}
return null
}
fun createCursor() : Cursor {
return App1.database.query(table, null, null, null, null, null, "$COL_NAME asc")
}
@ -154,7 +169,7 @@ class HighlightWord {
dst[COL_COLOR_FG] = color_fg
dst[COL_SOUND_TYPE] = sound_type
dst[COL_SPEECH] = speech
if(sound_uri != null) dst[COL_SOUND_URI] = sound_uri
sound_uri?.let{ dst[COL_SOUND_URI] = it}
return dst
}

View File

@ -0,0 +1,21 @@
package jp.juggler.util
import android.net.Uri
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
object UriOrNullSerializer : KSerializer<Uri?> {
override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("UriOrNull", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: Uri?) =
encoder.encodeString(value?.toString() ?:"" )
override fun deserialize(decoder: Decoder): Uri? =
decoder.decodeString().mayUri()
}

View File

@ -16,6 +16,7 @@ import android.os.SystemClock
import android.text.Editable
import android.text.TextWatcher
import android.util.SparseArray
import android.view.View
import android.widget.ImageButton
import android.widget.ImageView
import androidx.activity.ComponentActivity
@ -25,9 +26,6 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import jp.juggler.subwaytooter.R
import java.util.*
import kotlin.reflect.full.isSubtypeOf
import kotlin.reflect.full.memberProperties
import kotlin.reflect.typeOf
object UiUtils {
@ -345,6 +343,16 @@ fun ImageButton.setEnabledColor(context: Context, iconId: Int, color: Int, enabl
)
}
var View.isEnabledAlpha :Boolean
get() = isEnabled
set(enabled){
this.isEnabled = enabled
this.alpha = when (enabled) {
true -> 1f
else -> 0.3f
}
}
/////////////////////////////////////////////////
@ -369,9 +377,7 @@ class ActivityResultHandler<A : ComponentActivity>(
this.context = a.applicationContext
this.launcher = a.registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
callback(a, it)
}
) { callback(a, it) }
}
}

View File

@ -1,145 +1,161 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:fadeScrollbars="false"
android:fillViewport="true"
android:padding="12dp"
>
android:orientation="vertical">
<LinearLayout
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
android:layout_height="0dp"
android:layout_weight="1"
android:clipToPadding="false"
android:fadeScrollbars="false"
android:fillViewport="true"
android:padding="12dp">
<View style="@style/setting_divider"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
style="@style/setting_row_label"
android:text="@string/keyword"
/>
<LinearLayout style="@style/setting_row_form">
<View style="@style/setting_divider" />
<TextView
android:id="@+id/tvName"
style="@style/setting_horizontal_stretch"
android:padding="6dp"
android:gravity="center"
/>
</LinearLayout>
style="@style/setting_row_label"
android:text="@string/keyword" />
<View style="@style/setting_divider"/>
<LinearLayout style="@style/setting_row_form">
<TextView
style="@style/setting_row_label"
android:text="@string/text_color"
/>
<EditText
android:id="@+id/etName"
style="@style/setting_horizontal_stretch"
android:gravity="center"
android:padding="6dp" />
</LinearLayout>
<LinearLayout style="@style/setting_row_form">
<View style="@style/setting_divider" />
<Button
android:id="@+id/btnTextColorEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/edit"
android:textAllCaps="false"
/>
<TextView
style="@style/setting_row_label"
android:text="@string/text_color" />
<Button
android:id="@+id/btnTextColorReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reset"
android:textAllCaps="false"
/>
<LinearLayout style="@style/setting_row_form">
<Button
android:id="@+id/btnTextColorEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/edit"
android:textAllCaps="false" />
<Button
android:id="@+id/btnTextColorReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reset"
android:textAllCaps="false" />
</LinearLayout>
<View style="@style/setting_divider" />
<TextView
style="@style/setting_row_label"
android:text="@string/background_color" />
<LinearLayout style="@style/setting_row_form">
<Button
android:id="@+id/btnBackgroundColorEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/edit"
android:textAllCaps="false" />
<Button
android:id="@+id/btnBackgroundColorReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reset"
android:textAllCaps="false" />
</LinearLayout>
<View style="@style/setting_divider" />
<TextView
style="@style/setting_row_label"
android:text="@string/notification_sound" />
<LinearLayout style="@style/setting_row_form">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swSound"
style="@style/setting_horizontal_stretch"
android:gravity="center" />
</LinearLayout>
<LinearLayout style="@style/setting_row_form">
<Button
android:id="@+id/btnNotificationSoundEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/edit"
android:textAllCaps="false" />
<Button
android:id="@+id/btnNotificationSoundReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reset"
android:textAllCaps="false" />
</LinearLayout>
<View style="@style/setting_divider" />
<TextView
style="@style/setting_row_label"
android:text="@string/enable_speech" />
<LinearLayout style="@style/setting_row_form">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swSpeech"
style="@style/setting_horizontal_stretch"
android:gravity="center" />
</LinearLayout>
</LinearLayout>
</ScrollView>
<View style="@style/setting_divider"/>
<LinearLayout
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:measureWithLargestChild="true">
<TextView
style="@style/setting_row_label"
android:text="@string/background_color"
/>
<LinearLayout style="@style/setting_row_form">
<Button
android:id="@+id/btnBackgroundColorEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/edit"
android:textAllCaps="false"
/>
<Button
android:id="@+id/btnBackgroundColorReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reset"
android:textAllCaps="false"
/>
</LinearLayout>
<View style="@style/setting_divider"/>
<TextView
style="@style/setting_row_label"
android:text="@string/notification_sound"
/>
<LinearLayout style="@style/setting_row_form">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swSound"
style="@style/setting_horizontal_stretch"
android:gravity="center"
/>
</LinearLayout>
<LinearLayout style="@style/setting_row_form">
<Button
android:id="@+id/btnNotificationSoundEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/edit"
android:textAllCaps="false"
/>
<Button
android:id="@+id/btnNotificationSoundReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reset"
android:textAllCaps="false"
/>
</LinearLayout>
<View style="@style/setting_divider"/>
<TextView
style="@style/setting_row_label"
android:text="@string/enable_speech"
/>
<LinearLayout style="@style/setting_row_form">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swSpeech"
style="@style/setting_horizontal_stretch"
android:gravity="center"
/>
</LinearLayout>
<Button
android:id="@+id/btnDiscard"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/discard"
android:textAllCaps="false" />
<Button
android:id="@+id/btnSave"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/save"
android:textAllCaps="false" />
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@ -170,14 +170,7 @@
android:layout_height="wrap_content"
android:measureWithLargestChild="true">
<Button
android:id="@+id/btnSave"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/save"
android:textAllCaps="false" />
<Button
android:id="@+id/btnDiscard"
@ -187,5 +180,14 @@
android:layout_weight="1"
android:text="@string/discard"
android:textAllCaps="false" />
<Button
android:id="@+id/btnSave"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/save"
android:textAllCaps="false" />
</LinearLayout>
</LinearLayout>

View File

@ -73,7 +73,7 @@
android:contentDescription="@string/delete"
android:gravity="center_vertical"
android:src="@drawable/ic_close"
android:tint="?attr/colorVectorDrawable" />
app:tint="?attr/colorVectorDrawable" />
</LinearLayout>
<CheckBox
@ -206,7 +206,7 @@
android:background="@drawable/btn_bg_transparent_round6dp"
android:contentDescription="@string/open_picker_emoji"
android:src="@drawable/ic_hashtag"
android:tint="?attr/colorVectorDrawable"
app:tint="?attr/colorVectorDrawable"
/>
@ -218,7 +218,7 @@
android:background="@drawable/btn_bg_transparent_round6dp"
android:contentDescription="@string/open_picker_emoji"
android:src="@drawable/ic_face"
android:tint="?attr/colorVectorDrawable"
app:tint="?attr/colorVectorDrawable"
/>
</LinearLayout>
@ -267,7 +267,7 @@
android:background="@drawable/btn_bg_transparent_round6dp"
android:contentDescription="@string/edit"
android:src="@drawable/ic_edit"
android:tint="?attr/colorVectorDrawable"
app:tint="?attr/colorVectorDrawable"
/>
@ -278,7 +278,7 @@
android:background="@drawable/btn_bg_transparent_round6dp"
android:contentDescription="@string/reset"
android:src="@drawable/ic_close"
android:tint="?attr/colorVectorDrawable"
app:tint="?attr/colorVectorDrawable"
/>
@ -485,7 +485,7 @@
android:background="@drawable/btn_bg_transparent_round6dp"
android:contentDescription="@string/media_attachment"
android:src="@drawable/ic_clip"
android:tint="?attr/colorVectorDrawable" />
app:tint="?attr/colorVectorDrawable" />
<ImageButton
android:id="@+id/btnVisibility"
@ -496,7 +496,7 @@
android:contentDescription="@string/visibility"
android:minWidth="48dp"
android:minHeight="48dp"
android:tint="?attr/colorVectorDrawable"
app:tint="?attr/colorVectorDrawable"
tools:src="@drawable/ic_public" />
<ImageButton
@ -507,7 +507,7 @@
android:background="@drawable/btn_bg_transparent_round6dp"
android:contentDescription="@string/plugin"
android:src="@drawable/ic_extension"
android:tint="?attr/colorVectorDrawable" />
app:tint="?attr/colorVectorDrawable" />
<ImageButton
android:id="@+id/btnMore"
@ -517,7 +517,7 @@
android:background="@drawable/btn_bg_transparent_round6dp"
android:contentDescription="@string/more"
android:src="@drawable/ic_more"
android:tint="?attr/colorVectorDrawable"
app:tint="?attr/colorVectorDrawable"
/>
@ -544,7 +544,7 @@
android:background="@drawable/btn_bg_transparent_round6dp"
android:contentDescription="@string/toot"
android:src="@drawable/ic_send"
android:tint="?attr/colorVectorDrawable"
app:tint="?attr/colorVectorDrawable"
/>
</LinearLayout>

View File

@ -1,114 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
android:orientation="vertical">
<ScrollView
android:id="@+id/svContent"
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorStatusButtonsPopupBg"
app:title="@string/select_and_copy"
/>
<jp.juggler.subwaytooter.view.MyEditText
android:id="@+id/etText"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:fillViewport="true"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<jp.juggler.subwaytooter.view.MyEditText
android:id="@+id/etText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"
/>
</LinearLayout>
</ScrollView>
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/svFooterBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flexWrap="wrap"
>
<Button
android:id="@+id/btnCopy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/copy_st"
android:textAllCaps="false"
/>
<Button
android:id="@+id/btnSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/send"
android:textAllCaps="false"
/>
<Button
android:id="@+id/btnSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/search_web"
android:textAllCaps="false"
/>
<Button
android:id="@+id/btnSearchTS"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/toot_search_ts"
android:textAllCaps="false"
/>
<Button
android:id="@+id/btnSearchNotestock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/toot_search_notestock"
android:textAllCaps="false"
/>
<Button
android:id="@+id/btnTranslate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/translate"
android:textAllCaps="false"
/>
<Button
android:id="@+id/btnMuteWord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/mute_word"
android:textAllCaps="false"
/>
<Button
android:id="@+id/btnKeywordFilter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/keyword_filter"
android:textAllCaps="false"
/>
</com.google.android.flexbox.FlexboxLayout>
android:inputType="none" />
</LinearLayout>

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/btnCopy"
android:title="@string/copy_st"
app:showAsAction="ifRoom" />
<item
android:id="@+id/btnSend"
android:title="@string/send"
app:showAsAction="never" />
<item
android:id="@+id/btnSearch"
android:title="@string/search_web"
app:showAsAction="never" />
<item
android:id="@+id/btnSearchTS"
android:title="@string/toot_search_ts"
app:showAsAction="never" />
<item
android:id="@+id/btnSearchNotestock"
android:title="@string/toot_search_notestock"
app:showAsAction="never" />
<item
android:id="@+id/btnTranslate"
android:title="@string/translate"
app:showAsAction="never" />
<item
android:id="@+id/btnMuteWord"
android:title="@string/mute_word"
app:showAsAction="never" />
<item
android:id="@+id/btnKeywordFilter"
android:title="@string/keyword_filter"
app:showAsAction="never" />
<item
android:id="@+id/btnHighlight"
android:title="@string/highlight_word"
app:showAsAction="never" />
</menu>

View File

@ -630,7 +630,7 @@
<string name="search_is_not_available_on_pseudo_account">疑似アカウントでは検索APIを利用できなくなりました</string>
<string name="search_of">検索:%1$s</string>
<string name="search_web">Web検索</string>
<string name="select_and_copy">選択してコピー</string>
<string name="select_and_copy">選択してコピー</string>
<string name="select_draft">どの下書きから復元しますか?</string>
<string name="select_plugin">プラグインの選択</string>
<string name="send">共有</string>
@ -1086,4 +1086,9 @@
<string name="long_tap_to_delete">長押しで削除</string>
<string name="suggestion_source">推奨する理由</string>
<string name="cant_leave_empty_keyword">キーワードを指定してください</string>
<string name="cant_save_duplicated_keyword">既に存在するキーワードを重複保存できません</string>
<string name="discard_changes">変更を破棄しますか?</string>
<string name="saved">保存しました</string>
</resources>

View File

@ -1099,4 +1099,8 @@
<string name="keep_reaction_space">Keep Spacing for Reactions</string>
<string name="long_tap_to_delete">long tap to delete</string>
<string name="suggestion_source">Suggestion source</string>
<string name="cant_leave_empty_keyword">Can\'t leave empty keyword.</string>
<string name="cant_save_duplicated_keyword">Can\'t save duplicated keyword.</string>
<string name="discard_changes">Discard changes?</string>
<string name="saved">saved.</string>
</resources>