improve #241, increase custom share button

This commit is contained in:
tateisu 2023-05-04 02:21:36 +09:00
parent f33026baf3
commit 75e6001fcd
8 changed files with 161 additions and 184 deletions

View File

@ -1260,7 +1260,7 @@ class ActAppSetting : AppCompatActivity(), ColorPickerDialogListener, View.OnCli
fun showCustomShareIcon(tv: TextView?, target: CustomShareTarget) {
tv ?: return
val cn = CustomShare.getCustomShareComponentName(target)
val cn = target.customShareComponentName
val (label, icon) = CustomShare.getInfo(this, cn)
tv.text = label ?: getString(R.string.not_selected)
tv.setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null)

View File

@ -360,49 +360,6 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
sw(PrefB.bpDontRemoveDeletedToot, R.string.dont_remove_deleted_toot_from_timeline)
sw(PrefB.bpShowTranslateButton, R.string.show_translate_button)
item(
SettingType.TextWithSelector,
PrefS.spTranslateAppComponent,
R.string.translation_app
) {
val target = CustomShareTarget.Translate
onClickEdit = { openCustomShareChooser(this@item, target) }
onClickReset = { setCustomShare(this@item, target, "") }
showTextView = { showCustomShareIcon(it, target) }
}
item(
SettingType.TextWithSelector,
PrefS.spCustomShare1,
R.string.custom_share_button_1
) {
val target = CustomShareTarget.CustomShare1
onClickEdit = { openCustomShareChooser(this@item, target) }
onClickReset = { setCustomShare(this@item, target, "") }
showTextView = { showCustomShareIcon(it, target) }
}
item(
SettingType.TextWithSelector,
PrefS.spCustomShare2,
R.string.custom_share_button_2
) {
val target = CustomShareTarget.CustomShare2
onClickEdit = { openCustomShareChooser(this@item, target) }
onClickReset = { setCustomShare(this@item, target, "") }
showTextView = { showCustomShareIcon(it, target) }
}
item(
SettingType.TextWithSelector,
PrefS.spCustomShare3,
R.string.custom_share_button_3
) {
val target = CustomShareTarget.CustomShare3
onClickEdit = { openCustomShareChooser(this@item, target) }
onClickReset = { setCustomShare(this@item, target, "") }
showTextView = { showCustomShareIcon(it, target) }
}
spinnerSimple(
PrefI.ipAdditionalButtonsPosition,
R.string.additional_buttons_position,
@ -418,6 +375,20 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
sw(PrefB.bpEnableDomainTimeline, R.string.enable_domain_timeline)
}
section(R.string.translate_or_custom_share){
CustomShareTarget.values().forEach{ target->
item(
SettingType.TextWithSelector,
target.pref,
target.captionId,
) {
onClickEdit = { openCustomShareChooser(this@item, target) }
onClickReset = { setCustomShare(this@item, target, "") }
showTextView = { showCustomShareIcon(it, target) }
}
}
}
section(R.string.post) {
item(

View File

@ -112,10 +112,7 @@ class StatusButtons(
private val llFollow2 = holder.llFollow2
private val btnFollow2 = holder.btnFollow2
private val ivFollowedBy2 = holder.ivFollowedBy2
private val btnTranslate = holder.btnTranslate
private val btnCustomShare1 = holder.btnCustomShare1
private val btnCustomShare2 = holder.btnCustomShare2
private val btnCustomShare3 = holder.btnCustomShare3
private val btnCustomShares = holder.btnCustomShares
private val btnMore = holder.btnMore
private val colorTextContent = column.getContentColor()
@ -136,14 +133,14 @@ class StatusButtons(
btnFollow2,
btnConversation,
btnReply,
btnTranslate,
btnCustomShare1,
btnCustomShare2,
btnCustomShare3,
).forEach {
it.setOnClickListener(this)
it.setOnLongClickListener(this)
}
btnCustomShares.forEach {
it.setOnClickListener(this)
it.setOnLongClickListener(this)
}
// moreボタンだけ長押しがない
btnMore.setOnClickListener(this)
@ -414,41 +411,38 @@ class StatusButtons(
private fun bindAdditionalButtons() {
optionalButtonFirst = null
optionalButtonCount = 0
btnCustomShares.forEach { btn ->
val target = btn.getTag(R.id.custom_share_target) as CustomShareTarget
val (label, icon) = CustomShare.getCache(target)
?: error("showCustomShare: invalid target")
btnTranslate.vg(PrefB.bpShowTranslateButton.value)
?.showCustomShare(CustomShareTarget.Translate)
btnCustomShare1.showCustomShare(CustomShareTarget.CustomShare1)
btnCustomShare2.showCustomShare(CustomShareTarget.CustomShare2)
btnCustomShare3.showCustomShare(CustomShareTarget.CustomShare3)
val isShown = when {
target == CustomShareTarget.Translate && !PrefB.bpShowTranslateButton.value -> false
else -> label != null || icon != null
}
btn.vg(isShown)?.apply {
isEnabled = true
contentDescription = label ?: "?"
setImageDrawable(
icon ?: createColoredDrawable(
this@StatusButtons.activity,
R.drawable.ic_question,
colorTextContent,
stylerBoostAlpha
)
)
++optionalButtonCount
if (optionalButtonFirst == null) {
optionalButtonFirst = this
}
}
}
val updateAdditionalButton: (btn: ImageButton) -> Unit =
getUpdateAdditionalButton(optionalButtonCount, optionalButtonFirst)
updateAdditionalButton(btnTranslate)
updateAdditionalButton(btnCustomShare1)
updateAdditionalButton(btnCustomShare2)
updateAdditionalButton(btnCustomShare3)
}
private fun ImageButton.showCustomShare(target: CustomShareTarget) {
val (label, icon) = CustomShare.getCache(target)
?: error("showCustomShare: invalid target")
vg(label != null || icon != null)?.apply {
isEnabled = true
contentDescription = label ?: "?"
setImageDrawable(
icon ?: createColoredDrawable(
this@StatusButtons.activity,
R.drawable.ic_question,
colorTextContent,
stylerBoostAlpha
)
)
++optionalButtonCount
if (optionalButtonFirst == null) {
optionalButtonFirst = this
}
btnCustomShares.forEach { btn ->
updateAdditionalButton(btn)
}
}
@ -591,10 +585,14 @@ class StatusButtons(
btnBookmark -> clickBookmark(accessInfo, status, willToast = bSimpleList)
btnReaction -> clickReaction(accessInfo, column, status)
btnFollow2 -> clickFollow(pos, accessInfo, status.accountRef, relation)
btnTranslate -> shareStatusText(status, CustomShareTarget.Translate)
btnCustomShare1 -> shareStatusText(status, CustomShareTarget.CustomShare1)
btnCustomShare2 -> shareStatusText(status, CustomShareTarget.CustomShare2)
btnCustomShare3 -> shareStatusText(status, CustomShareTarget.CustomShare3)
else -> {
btnCustomShares.find { it == v }?.let {
val target = it.getTag(R.id.custom_share_target) as CustomShareTarget
shareStatusText(status, target)
return
}
}
}
}
}
@ -620,11 +618,13 @@ class StatusButtons(
status.account
)
// 以下、長押し
btnTranslate -> shareStatusUrl(status, CustomShareTarget.Translate)
btnCustomShare1 -> shareStatusUrl(status, CustomShareTarget.CustomShare1)
btnCustomShare2 -> shareStatusUrl(status, CustomShareTarget.CustomShare2)
btnCustomShare3 -> shareStatusUrl(status, CustomShareTarget.CustomShare3)
else -> {
btnCustomShares.find { it == v }?.let {
val target = it.getTag(R.id.custom_share_target) as CustomShareTarget
shareStatusUrl(status, target)
return true
}
}
}
}
return true
@ -691,10 +691,8 @@ class StatusButtonsViewHolder(
lateinit var llFollow2: View
lateinit var btnFollow2: ImageButton
lateinit var ivFollowedBy2: ImageView
lateinit var btnTranslate: ImageButton
lateinit var btnCustomShares: List<ImageButton>
lateinit var btnCustomShare1: ImageButton
lateinit var btnCustomShare2: ImageButton
lateinit var btnCustomShare3: ImageButton
lateinit var btnMore: ImageButton
private fun AnkoFlexboxLayout.normalButtons() {
@ -823,48 +821,18 @@ class StatusButtonsViewHolder(
}
private fun AnkoFlexboxLayout.additionalButtons() {
btnTranslate = imageButton {
background = ContextCompat.getDrawable(
context,
R.drawable.btn_bg_transparent_round6dp
)
setPadding(paddingH, paddingV, paddingH, paddingV)
scaleType = ImageView.ScaleType.FIT_CENTER
}.lparams(buttonHeight, buttonHeight) {
startMargin = marginBetween
}
btnCustomShare1 = imageButton {
background = ContextCompat.getDrawable(
context,
R.drawable.btn_bg_transparent_round6dp
)
setPadding(paddingH, paddingV, paddingH, paddingV)
scaleType = ImageView.ScaleType.FIT_CENTER
}.lparams(buttonHeight, buttonHeight) {
startMargin = marginBetween
}
btnCustomShare2 = imageButton {
background = ContextCompat.getDrawable(
context,
R.drawable.btn_bg_transparent_round6dp
)
setPadding(paddingH, paddingV, paddingH, paddingV)
scaleType = ImageView.ScaleType.FIT_CENTER
}.lparams(buttonHeight, buttonHeight) {
startMargin = marginBetween
}
btnCustomShare3 = imageButton {
background = ContextCompat.getDrawable(
context,
R.drawable.btn_bg_transparent_round6dp
)
setPadding(paddingH, paddingV, paddingH, paddingV)
scaleType = ImageView.ScaleType.FIT_CENTER
}.lparams(buttonHeight, buttonHeight) {
startMargin = marginBetween
btnCustomShares = CustomShareTarget.values().map { target ->
imageButton {
background = ContextCompat.getDrawable(
context,
R.drawable.btn_bg_transparent_round6dp
)
setPadding(paddingH, paddingV, paddingH, paddingV)
scaleType = ImageView.ScaleType.FIT_CENTER
setTag(R.id.custom_share_target, target)
}.lparams(buttonHeight, buttonHeight) {
startMargin = marginBetween
}
}
}

View File

@ -48,6 +48,14 @@ object PrefS {
val spCustomShare1 = StringPref("CustomShare1", "")
val spCustomShare2 = StringPref("CustomShare2", "")
val spCustomShare3 = StringPref("CustomShare3", "")
val spCustomShare4 = StringPref("CustomShare4", "")
val spCustomShare5 = StringPref("CustomShare5", "")
val spCustomShare6 = StringPref("CustomShare6", "")
val spCustomShare7 = StringPref("CustomShare7", "")
val spCustomShare8 = StringPref("CustomShare8", "")
val spCustomShare9 = StringPref("CustomShare9", "")
val spCustomShare10 = StringPref("CustomShare10", "")
// val spWebBrowser = StringPref("WebBrowser", "")
val spTimelineSpacing = StringPref("TimelineSpacing", "")

View File

@ -1,23 +1,53 @@
package jp.juggler.subwaytooter.util
import android.content.*
import android.content.ActivityNotFoundException
import android.content.ClipData
import android.content.ClipboardManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.PorterDuff
import android.graphics.drawable.Drawable
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import jp.juggler.subwaytooter.R
import jp.juggler.subwaytooter.api.entity.TootStatus
import jp.juggler.subwaytooter.pref.PrefS
import jp.juggler.subwaytooter.pref.impl.StringPref
import jp.juggler.subwaytooter.table.SavedAccount
import jp.juggler.util.*
import jp.juggler.util.data.*
import jp.juggler.util.log.*
import jp.juggler.util.ui.*
import jp.juggler.util.log.LogCategory
import jp.juggler.util.log.showToast
import jp.juggler.util.queryIntentActivitiesCompat
import jp.juggler.util.resolveActivityCompat
import jp.juggler.util.systemService
import jp.juggler.util.ui.attrColor
enum class CustomShareTarget {
Translate,
CustomShare1,
CustomShare2,
CustomShare3,
enum class CustomShareTarget(val pref: StringPref, @StringRes val captionId: Int) {
Translate(PrefS.spTranslateAppComponent, R.string.translation_app),
CustomShare1(PrefS.spCustomShare1, R.string.custom_share_button_1),
CustomShare2(PrefS.spCustomShare2, R.string.custom_share_button_2),
CustomShare3(PrefS.spCustomShare3, R.string.custom_share_button_3),
CustomShare4(PrefS.spCustomShare4, R.string.custom_share_button_4),
CustomShare5(PrefS.spCustomShare5, R.string.custom_share_button_5),
CustomShare6(PrefS.spCustomShare6, R.string.custom_share_button_6),
CustomShare7(PrefS.spCustomShare7, R.string.custom_share_button_7),
CustomShare8(PrefS.spCustomShare8, R.string.custom_share_button_8),
CustomShare9(PrefS.spCustomShare9, R.string.custom_share_button_9),
CustomShare10(PrefS.spCustomShare10, R.string.custom_share_button_10),
;
val defaultComponentName
get() = when (this) {
Translate ->
"com.google.android.apps.translate/com.google.android.apps.translate.TranslateActivity"
else -> null
}
val customShareComponentName
get() = pref.value.cn() ?: defaultComponentName?.cn()
}
object CustomShare {
@ -26,38 +56,6 @@ object CustomShare {
const val CN_CLIPBOARD = "<InApp>/CopyToClipboard"
private const val translate_app_component_default =
"com.google.android.apps.translate/com.google.android.apps.translate.TranslateActivity"
fun getCustomShareComponentName(
target: CustomShareTarget,
): ComponentName? {
val src: String
val defaultComponentName: String?
when (target) {
CustomShareTarget.Translate -> {
src = PrefS.spTranslateAppComponent.value
defaultComponentName = translate_app_component_default
}
CustomShareTarget.CustomShare1 -> {
src = PrefS.spCustomShare1.value
defaultComponentName = null
}
CustomShareTarget.CustomShare2 -> {
src = PrefS.spCustomShare2.value
defaultComponentName = null
}
CustomShareTarget.CustomShare3 -> {
src = PrefS.spCustomShare3.value
defaultComponentName = null
}
}
return src.cn() ?: defaultComponentName?.cn()
}
fun getInfo(context: Context, cn: ComponentName?): Pair<CharSequence?, Drawable?> {
var label: CharSequence? = null
var icon: Drawable? = null
@ -74,7 +72,19 @@ object CustomShare {
}
} else {
val pm = context.packageManager
val ri = pm.resolveActivityCompat(Intent().apply { component = cn })
var queryIntent = Intent().apply { component = cn }
var ri = pm.resolveActivityCompat(queryIntent, PackageManager.MATCH_ALL)
if( ri ==null){
queryIntent = Intent().apply {
action = Intent.ACTION_SEND
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, context.getString(R.string.content_sample))
}
val listResolveInfo = pm.queryIntentActivitiesCompat(queryIntent, PackageManager.MATCH_ALL)
ri = listResolveInfo.find {
"${it.activityInfo.packageName}/${it.activityInfo.name}" == cnStr
}
}
if (ri != null) {
try {
label = ri.loadLabel(pm)
@ -101,7 +111,7 @@ object CustomShare {
text: String,
) {
// convert "pkgName/className" string to ComponentName object.
val cn = getCustomShareComponentName(target)
val cn = target.customShareComponentName
if (cn == null) {
context.showToast(true, R.string.custom_share_app_not_found)
return
@ -153,7 +163,7 @@ object CustomShare {
status ?: return
try {
// convert "pkgName/className" string to ComponentName object.
val cn = getCustomShareComponentName(target)
val cn = target.customShareComponentName
if (cn == null) {
context.showToast(true, R.string.custom_share_app_not_found)
return
@ -174,7 +184,7 @@ object CustomShare {
target: CustomShareTarget,
context: Context,
) = try {
getCustomShareComponentName(target)?.let { cn ->
target.customShareComponentName?.let { cn ->
val cnStr = "${cn.packageName}/${cn.className}"
if (cnStr == CN_CLIPBOARD) {
false
@ -198,7 +208,7 @@ object CustomShare {
fun reloadCache(context: Context) {
CustomShareTarget.values().forEach { target ->
val cn = getCustomShareComponentName(target)
val cn = target.customShareComponentName
val pair = getInfo(context, cn)
cache[target] = pair
}
@ -218,7 +228,6 @@ fun String.cn(): ComponentName? {
fun ComponentName.exists(context: Context): Boolean {
return try {
@Suppress("DEPRECATION")
context.packageManager.resolveActivityCompat(Intent().apply { component = this@exists })
?.activityInfo?.exported ?: false
} catch (_: Throwable) {

View File

@ -938,6 +938,13 @@
<string name="custom_share_button_1">カスタム共有ボタン1</string>
<string name="custom_share_button_2">カスタム共有ボタン2</string>
<string name="custom_share_button_3">カスタム共有ボタン3</string>
<string name="custom_share_button_4">カスタム共有ボタン4</string>
<string name="custom_share_button_5">カスタム共有ボタン5</string>
<string name="custom_share_button_6">カスタム共有ボタン6</string>
<string name="custom_share_button_7">カスタム共有ボタン7</string>
<string name="custom_share_button_8">カスタム共有ボタン8</string>
<string name="custom_share_button_9">カスタム共有ボタン9</string>
<string name="custom_share_button_10">カスタム共有ボタン10</string>
<string name="custom_share_app_not_found">共有先のアプリがインストールされていません。「アプリ設定/挙動」を確認してください</string>
<string name="additional_buttons_position">追加ボタンの位置(アプリ再起動が必要)</string>
<string name="top"></string>
@ -1278,5 +1285,6 @@
<string name="send_to_other_app">外部アプリに送信</string>
<string name="save_to_local_folder">ローカルフォルダに保存</string>
<string name="app_data_export_import">アプリデータのエクスポート/インポート</string>
<string name="translate_or_custom_share">翻訳ボタン / カスタム共有ボタン</string>
</resources>

View File

@ -943,6 +943,14 @@
<string name="custom_share_button_1">Custom share button 1</string>
<string name="custom_share_button_2">Custom share button 2</string>
<string name="custom_share_button_3">Custom share button 3</string>
<string name="custom_share_button_4">Custom share button 4</string>
<string name="custom_share_button_5">Custom share button 5</string>
<string name="custom_share_button_6">Custom share button 6</string>
<string name="custom_share_button_7">Custom share button 7</string>
<string name="custom_share_button_8">Custom share button 8</string>
<string name="custom_share_button_9">Custom share button 9</string>
<string name="custom_share_button_10">Custom share button 10</string>
<string name="custom_share_app_not_found">the share target app is not installed. please configure it in \"App setting/behavior\".</string>
<string name="additional_buttons_position">Additional buttons position (app restart required)</string>
<string name="top">Top</string>
@ -1286,4 +1294,5 @@
<string name="send_to_other_app">Send to other app</string>
<string name="save_to_local_folder">Save to local folder</string>
<string name="app_data_export_import">Export/Import app data</string>
<string name="translate_or_custom_share">Translate/Custom share buttons</string>
</resources>

View File

@ -2,4 +2,8 @@
<resources>
<!-- ビューのタグのキーに使うID -->
<item type="id" name="text" />
<!-- ビューのタグのキーに使うID -->
<item type="id" name="custom_share_target" />
</resources>