refactor
This commit is contained in:
parent
0de55da66b
commit
f4ac870c6a
|
@ -9,17 +9,19 @@ import android.widget.Button
|
|||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import jp.juggler.subwaytooter.util.openBrowser
|
||||
import jp.juggler.util.LogCategory
|
||||
|
||||
class ActAbout : AppCompatActivity() {
|
||||
|
||||
class Translators(
|
||||
val name:String,
|
||||
val acct:String?,
|
||||
val lang:String
|
||||
val name : String,
|
||||
val acct : String?,
|
||||
val lang : String
|
||||
)
|
||||
|
||||
companion object {
|
||||
|
||||
val log = LogCategory("ActAbout")
|
||||
|
||||
const val EXTRA_SEARCH = "search"
|
||||
|
@ -33,22 +35,22 @@ class ActAbout : AppCompatActivity() {
|
|||
|
||||
// git log --pretty=format:"%an %s" |grep "Translated using Weblate"|sort|uniq
|
||||
val translators = arrayOf(
|
||||
Translators("Allan Nordhøy",null,"English & Norwegian Bokmål"),
|
||||
Translators("ButterflyOfFire","@ButterflyOfFire@mstdn.fr", "Arabic & French"),
|
||||
Translators("Ch",null,"Korean"),
|
||||
Translators("Elizabeth Sherrock",null,"Chinese (Simplified)"),
|
||||
Translators("Gennady Archangorodsky",null,"Hebrew"),
|
||||
Translators("inqbs Siina",null,"Korean"),
|
||||
Translators("Jeong Arm","@jarm@qdon.space","Korean"),
|
||||
Translators("Joan Pujolar","@jpujolar@mastodont.cat","Catalan"),
|
||||
Translators("Kai Zhang","@bearzk@mastodon.social","Chinese (Simplified)"),
|
||||
Translators("lptprjh",null,"Korean"),
|
||||
Translators("mynameismonkey",null,"Welsh"),
|
||||
Translators("Nathan",null,"French"),
|
||||
Translators("Owain Rhys Lewis",null,"Welsh"),
|
||||
Translators("Swann Martinet",null,"French"),
|
||||
Translators("takubunn",null,"Chinese (Simplified)"),
|
||||
Translators("배태길",null,"Korea")
|
||||
Translators("Allan Nordhøy", null, "English & Norwegian Bokmål"),
|
||||
Translators("ButterflyOfFire", "@ButterflyOfFire@mstdn.fr", "Arabic & French"),
|
||||
Translators("Ch", null, "Korean"),
|
||||
Translators("Elizabeth Sherrock", null, "Chinese (Simplified)"),
|
||||
Translators("Gennady Archangorodsky", null, "Hebrew"),
|
||||
Translators("inqbs Siina", null, "Korean"),
|
||||
Translators("Jeong Arm", "@jarm@qdon.space", "Korean"),
|
||||
Translators("Joan Pujolar", "@jpujolar@mastodont.cat", "Catalan"),
|
||||
Translators("Kai Zhang", "@bearzk@mastodon.social", "Chinese (Simplified)"),
|
||||
Translators("lptprjh", null, "Korean"),
|
||||
Translators("mynameismonkey", null, "Welsh"),
|
||||
Translators("Nathan", null, "French"),
|
||||
Translators("Owain Rhys Lewis", null, "Welsh"),
|
||||
Translators("Swann Martinet", null, "French"),
|
||||
Translators("takubunn", null, "Chinese (Simplified)"),
|
||||
Translators("배태길", null, "Korea")
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -69,7 +71,7 @@ class ActAbout : AppCompatActivity() {
|
|||
log.trace(ex, "getPackageInfo failed.")
|
||||
}
|
||||
|
||||
fun setButton(btnId : Int, caption : String, onClick : () -> Unit ) {
|
||||
fun setButton(btnId : Int, caption : String, onClick : () -> Unit) {
|
||||
val b : Button = findViewById(btnId)
|
||||
b.text = caption
|
||||
b.setOnClickListener { onClick() }
|
||||
|
@ -80,9 +82,6 @@ class ActAbout : AppCompatActivity() {
|
|||
finish()
|
||||
}
|
||||
|
||||
fun openUrl(url : String) {
|
||||
App1.openBrowser(this@ActAbout, url)
|
||||
}
|
||||
|
||||
setButton(
|
||||
R.id.btnDeveloper,
|
||||
|
@ -94,10 +93,14 @@ class ActAbout : AppCompatActivity() {
|
|||
getString(R.string.search_for, official_acct)
|
||||
) { searchAcct(official_acct) }
|
||||
|
||||
setButton(R.id.btnReleaseNote, url_release)
|
||||
{ openBrowser(url_release) }
|
||||
|
||||
setButton(R.id.btnReleaseNote, url_release) { openUrl(url_release) }
|
||||
// setButton(R.id.btnIconDesign, url_futaba) { openUrl(url_futaba) }
|
||||
setButton(R.id.btnWeblate, getString(R.string.please_help_translation) ) { openUrl(url_weblate) }
|
||||
// setButton(R.id.btnIconDesign, url_futaba)
|
||||
// { openUrl(url_futaba) }
|
||||
|
||||
setButton(R.id.btnWeblate, getString(R.string.please_help_translation))
|
||||
{ openBrowser(url_weblate) }
|
||||
|
||||
val ll = findViewById<LinearLayout>(R.id.llContributors)
|
||||
val density = resources.displayMetrics.density
|
||||
|
@ -117,7 +120,7 @@ class ActAbout : AppCompatActivity() {
|
|||
setBackgroundResource(R.drawable.btn_bg_transparent_round6dp)
|
||||
setPadding(padding, padding, padding, padding)
|
||||
isAllCaps = false
|
||||
|
||||
|
||||
//
|
||||
val acct = who.acct ?: "@?@?"
|
||||
text = "${who.name}\n$acct\n${getString(R.string.thanks_for, who.lang)}"
|
||||
|
|
|
@ -262,7 +262,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
|
||||
Styler.fixHorizontalPadding(root)
|
||||
|
||||
setSwitchColor(this, pref, root)
|
||||
setSwitchColor(pref, root)
|
||||
|
||||
tvInstance = findViewById(R.id.tvInstance)
|
||||
tvUser = findViewById(R.id.tvUser)
|
||||
|
@ -529,7 +529,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
tvUserCustom.backgroundColor = ac.color_bg
|
||||
tvUserCustom.text = ac.nickname
|
||||
tvUserCustom.textColor = ac.color_fg.notZero()
|
||||
?: getAttributeColor(this, R.attr.colorTimeSmall)
|
||||
?: getAttributeColor(R.attr.colorTimeSmall)
|
||||
}
|
||||
|
||||
private fun saveUIToData() {
|
||||
|
@ -590,10 +590,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
R.id.btnAccountRemove -> performAccountRemove()
|
||||
R.id.btnLoadPreference -> performLoadPreference()
|
||||
R.id.btnVisibility -> performVisibility()
|
||||
R.id.btnOpenBrowser -> App1.openBrowser(
|
||||
this@ActAccountSetting,
|
||||
"https://${account.apiHost.ascii}/"
|
||||
)
|
||||
R.id.btnOpenBrowser -> openBrowser("https://${account.apiHost.ascii}/")
|
||||
R.id.btnPushSubscription -> startTest()
|
||||
|
||||
R.id.btnUserCustom -> ActNickname.open(
|
||||
|
@ -694,7 +691,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
|
||||
val json = result.jsonObject
|
||||
if(json == null) {
|
||||
showToast(this@ActAccountSetting, true, result.error)
|
||||
showToast(true, result.error)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -745,7 +742,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
account.delete()
|
||||
|
||||
val pref = Pref.pref(this@ActAccountSetting)
|
||||
val pref = pref()
|
||||
if(account.db_id == Pref.lpTabletTootDefaultAccount(pref)) {
|
||||
pref.edit().put(Pref.lpTabletTootDefaultAccount, - 1L).apply()
|
||||
}
|
||||
|
@ -810,7 +807,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
}
|
||||
|
||||
error != null -> {
|
||||
showToast(this@ActAccountSetting, true, error)
|
||||
showToast(true, error)
|
||||
log.e("can't get oauth browser URL. $error")
|
||||
}
|
||||
}
|
||||
|
@ -921,7 +918,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
if(data != null) {
|
||||
showProfile(data)
|
||||
} else {
|
||||
showToast(this@ActAccountSetting, true, result.error)
|
||||
showToast(true, result.error)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1248,7 +1245,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
if(data != null) {
|
||||
showProfile(data)
|
||||
} else {
|
||||
showToast(this@ActAccountSetting, true, result.error)
|
||||
showToast(true, result.error)
|
||||
for(arg in args) {
|
||||
val key = arg.first
|
||||
val value = arg.second
|
||||
|
@ -1401,7 +1398,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
)
|
||||
return
|
||||
}
|
||||
showToast(this, true, R.string.missing_permission_to_access_media)
|
||||
showToast(true, R.string.missing_permission_to_access_media)
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
|
@ -1413,7 +1410,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
if(grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
openPicker(requestCode)
|
||||
} else {
|
||||
showToast(this, true, R.string.missing_permission_to_access_media)
|
||||
showToast(true, R.string.missing_permission_to_access_media)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1424,7 +1421,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
startActivityForResult(intent, request_code)
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex, "performAttachment failed.")
|
||||
showToast(this, ex, "performAttachment failed.")
|
||||
showToast(ex, "performAttachment failed.")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1446,7 +1443,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
startActivityForResult(intent, request_code)
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex, "opening camera app failed.")
|
||||
showToast(this, ex, "opening camera app failed.")
|
||||
showToast(ex, "opening camera app failed.")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1483,7 +1480,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
try {
|
||||
val cache_dir = externalCacheDir
|
||||
if(cache_dir == null) {
|
||||
showToast(this, false, "getExternalCacheDir returns null.")
|
||||
showToast(false, "getExternalCacheDir returns null.")
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -1522,7 +1519,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex, "Resizing image failed.")
|
||||
showToast(this, ex, "Resizing image failed.")
|
||||
showToast(ex, "Resizing image failed.")
|
||||
}
|
||||
|
||||
break
|
||||
|
@ -1549,12 +1546,12 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
private fun addAttachment(request_code : Int, uri : Uri, mime_type : String?) {
|
||||
|
||||
if(mime_type == null) {
|
||||
showToast(this, false, "mime type is not provided.")
|
||||
showToast(false, "mime type is not provided.")
|
||||
return
|
||||
}
|
||||
|
||||
if(! mime_type.startsWith("image/")) {
|
||||
showToast(this, false, "mime type is not image.")
|
||||
showToast(false, "mime type is not image.")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1583,7 +1580,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
)
|
||||
|
||||
override fun background(client : TootApiClient) : TootApiResult? {
|
||||
return wps.updateSubscription(client,true)
|
||||
return wps.updateSubscription(client, true)
|
||||
}
|
||||
|
||||
override fun handleResult(result : TootApiResult?) {
|
||||
|
|
|
@ -81,7 +81,7 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
|
|||
App1.setActivityTheme(this, noActionBar = true)
|
||||
|
||||
this.handler = App1.getAppState(this).handler
|
||||
this.pref = Pref.pref(this)
|
||||
this.pref = pref()
|
||||
|
||||
// val intent = this.intent
|
||||
// val layoutId = intent.getIntExtra(EXTRA_LAYOUT_ID, 0)
|
||||
|
@ -373,7 +373,7 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
|
|||
val margin_tb = dip(6)
|
||||
setMargins(margin_lr, margin_tb, margin_lr, margin_tb)
|
||||
}
|
||||
setBackgroundColor(getAttributeColor(context, R.attr.colorSettingDivider))
|
||||
setBackgroundColor(context.getAttributeColor(R.attr.colorSettingDivider))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -538,7 +538,7 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
|
|||
item.pref.cast() ?: error("$name has no boolean pref")
|
||||
showCaption(name)
|
||||
swSwitch.vg(false) // skip animation
|
||||
setSwitchColor(activity, pref, swSwitch)
|
||||
setSwitchColor(pref, swSwitch)
|
||||
swSwitch.isEnabled = item.enabled
|
||||
swSwitch.isChecked = bp(pref)
|
||||
swSwitch.vg(true)
|
||||
|
@ -840,7 +840,7 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
|
|||
val intent = intentOpenDocument("*/*")
|
||||
startActivityForResult(intent, REQUEST_CODE_APP_DATA_IMPORT)
|
||||
} catch(ex : Throwable) {
|
||||
showToast(this, ex, "importAppData(1) failed.")
|
||||
showToast(ex, "importAppData(1) failed.")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -884,7 +884,7 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
|
|||
}
|
||||
|
||||
fun setSwitchColor() =
|
||||
setSwitchColor(this@ActAppSetting, pref, lvList)
|
||||
setSwitchColor(pref, lvList)
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
|
@ -955,7 +955,7 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
|
|||
private fun saveTimelineFont(uri : Uri?, file_name : String) : File? {
|
||||
try {
|
||||
if(uri == null) {
|
||||
showToast(this, false, "missing uri.")
|
||||
showToast(false, "missing uri.")
|
||||
return null
|
||||
}
|
||||
|
||||
|
@ -969,7 +969,7 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
|
|||
|
||||
val source : InputStream? = contentResolver.openInputStream(uri)
|
||||
if(source == null) {
|
||||
showToast(this, false, "openInputStream returns null. uri=%s", uri)
|
||||
showToast(false, "openInputStream returns null. uri=%s", uri)
|
||||
return null
|
||||
} else {
|
||||
source.use { inStream ->
|
||||
|
@ -981,20 +981,20 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
|
|||
|
||||
val face = Typeface.createFromFile(tmp_file)
|
||||
if(face == null) {
|
||||
showToast(this, false, "Typeface.createFromFile() failed.")
|
||||
showToast(false, "Typeface.createFromFile() failed.")
|
||||
return null
|
||||
}
|
||||
|
||||
val file = File(dir, file_name)
|
||||
if(! tmp_file.renameTo(file)) {
|
||||
showToast(this, false, "File operation failed.")
|
||||
showToast(false, "File operation failed.")
|
||||
return null
|
||||
}
|
||||
|
||||
return file
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(this, ex, "saveTimelineFont failed.")
|
||||
showToast(ex, "saveTimelineFont failed.")
|
||||
return null
|
||||
}
|
||||
|
||||
|
@ -1177,10 +1177,10 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
|
|||
}
|
||||
) { setCustomShare(target, it) }
|
||||
.show()
|
||||
if(! rv) showToast(this, true, "share target app is not installed.")
|
||||
if(! rv) showToast(true, "share target app is not installed.")
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(this, ex, "openCustomShareChooser failed.")
|
||||
showToast(ex, "openCustomShareChooser failed.")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import kotlin.math.max
|
|||
class ActColumnCustomize : AppCompatActivity(), View.OnClickListener, ColorPickerDialogListener {
|
||||
|
||||
companion object {
|
||||
|
||||
internal val log = LogCategory("ActColumnCustomize")
|
||||
|
||||
internal const val EXTRA_COLUMN_INDEX = "column_index"
|
||||
|
@ -298,7 +299,7 @@ class ActColumnCustomize : AppCompatActivity(), View.OnClickListener, ColorPicke
|
|||
show()
|
||||
}
|
||||
|
||||
else -> showToast(this@ActColumnCustomize, true, result.error ?: "?")
|
||||
else -> showToast(true, result.error ?: "?")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -395,18 +396,18 @@ class ActColumnCustomize : AppCompatActivity(), View.OnClickListener, ColorPicke
|
|||
}
|
||||
})
|
||||
|
||||
etAlpha.setOnEditorActionListener{ _, actionId, _->
|
||||
etAlpha.setOnEditorActionListener { _, actionId, _ ->
|
||||
when(actionId) {
|
||||
EditorInfo.IME_ACTION_DONE -> {
|
||||
etAlpha.hideKeyboard()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun show() {
|
||||
try {
|
||||
loading_busy = true
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.*
|
|||
class ActColumnList : AppCompatActivity() {
|
||||
|
||||
companion object {
|
||||
|
||||
private val log = LogCategory("ActColumnList")
|
||||
internal const val TMP_FILE_COLUMN_LIST = "tmp_column_list"
|
||||
|
||||
|
@ -119,11 +120,7 @@ class ActColumnList : AppCompatActivity() {
|
|||
if(swipedDirection == ListSwipeItem.SwipeDirection.LEFT) {
|
||||
val adapterItem = item.tag as MyItem
|
||||
if(adapterItem.json.optBoolean(Column.KEY_DONT_CLOSE, false)) {
|
||||
showToast(
|
||||
this@ActColumnList,
|
||||
false,
|
||||
R.string.column_has_dont_close_option
|
||||
)
|
||||
showToast(false, R.string.column_has_dont_close_option)
|
||||
listView.resetSwipedViews(null)
|
||||
return
|
||||
}
|
||||
|
@ -203,7 +200,7 @@ class ActColumnList : AppCompatActivity() {
|
|||
val type = ColumnType.parse(json.optInt(Column.KEY_TYPE))
|
||||
val acct_color_bg = json.optInt(Column.KEY_COLUMN_ACCESS_COLOR_BG, 0)
|
||||
val acct_color_fg = json.optInt(Column.KEY_COLUMN_ACCESS_COLOR, 0)
|
||||
.notZero() ?: getAttributeColor(context, R.attr.colorColumnListItemText)
|
||||
.notZero() ?: context.getAttributeColor(R.attr.colorColumnListItemText)
|
||||
var bOldSelection : Boolean = false
|
||||
|
||||
fun setOldSelection(b : Boolean) {
|
||||
|
@ -276,16 +273,14 @@ class ActColumnList : AppCompatActivity() {
|
|||
dragView.findViewById<View>(R.id.ivBookmark).visibility =
|
||||
clickedView.findViewById<View>(R.id.ivBookmark).visibility
|
||||
|
||||
dragView.findViewById<View>(R.id.item_layout).setBackgroundColor(
|
||||
getAttributeColor(this@ActColumnList, R.attr.list_item_bg_pressed_dragged)
|
||||
)
|
||||
dragView.findViewById<View>(R.id.item_layout)
|
||||
.setBackgroundColor(getAttributeColor(R.attr.list_item_bg_pressed_dragged))
|
||||
}
|
||||
}
|
||||
|
||||
private inner class MyListAdapter :
|
||||
DragItemAdapter<MyItem, MyViewHolder>() {
|
||||
|
||||
|
||||
init {
|
||||
setHasStableIds(true)
|
||||
itemList = ArrayList()
|
||||
|
|
|
@ -171,9 +171,8 @@ class ActFavMute : AppCompatActivity() {
|
|||
dragView.findViewById<TextView>(R.id.tvName).text =
|
||||
clickedView.findViewById<TextView>(R.id.tvName).text
|
||||
|
||||
dragView.findViewById<View>(R.id.item_layout).setBackgroundColor(
|
||||
getAttributeColor(this@ActFavMute, R.attr.list_item_bg_pressed_dragged)
|
||||
)
|
||||
dragView.findViewById<View>(R.id.item_layout)
|
||||
.setBackgroundColor(getAttributeColor(R.attr.list_item_bg_pressed_dragged))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -116,8 +116,8 @@ class ActHighlightWordEdit
|
|||
swSpeech = findViewById(R.id.swSpeech)
|
||||
swSpeech.setOnCheckedChangeListener(this)
|
||||
|
||||
setSwitchColor(this, App1.pref, swSound)
|
||||
setSwitchColor(this, App1.pref, swSpeech)
|
||||
setSwitchColor(App1.pref, swSound)
|
||||
setSwitchColor(App1.pref, swSpeech)
|
||||
|
||||
intArrayOf(
|
||||
R.id.btnTextColorEdit,
|
||||
|
@ -142,7 +142,7 @@ class ActHighlightWordEdit
|
|||
tvName.text = item.name
|
||||
tvName.setBackgroundColor(item.color_bg) // may 0
|
||||
tvName.textColor = item.color_fg.notZero()
|
||||
?: getAttributeColor(this, android.R.attr.textColorPrimary)
|
||||
?: getAttributeColor(android.R.attr.textColorPrimary)
|
||||
|
||||
} finally {
|
||||
bBusy = false
|
||||
|
|
|
@ -136,7 +136,7 @@ class ActHighlightWordList : AppCompatActivity(), View.OnClickListener {
|
|||
|
||||
val tvName : TextView
|
||||
private val btnSound : View
|
||||
private val ivSpeech: ImageButton
|
||||
private val ivSpeech : ImageButton
|
||||
|
||||
init {
|
||||
|
||||
|
@ -160,15 +160,15 @@ class ActHighlightWordList : AppCompatActivity(), View.OnClickListener {
|
|||
tvName.setBackgroundColor(item.color_bg)
|
||||
tvName.setTextColor(
|
||||
item.color_fg.notZero()
|
||||
?: getAttributeColor(this@ActHighlightWordList, android.R.attr.textColorPrimary)
|
||||
?: getAttributeColor(android.R.attr.textColorPrimary)
|
||||
)
|
||||
|
||||
btnSound.vg(item.sound_type != HighlightWord.SOUND_TYPE_NONE)?.apply{
|
||||
btnSound.vg(item.sound_type != HighlightWord.SOUND_TYPE_NONE)?.apply {
|
||||
setOnClickListener(this@MyViewHolder)
|
||||
tag = item
|
||||
}
|
||||
|
||||
ivSpeech.vg(item.speech != 0 )?.apply{
|
||||
ivSpeech.vg(item.speech != 0)?.apply {
|
||||
setOnClickListener(this@MyViewHolder)
|
||||
tag = item
|
||||
}
|
||||
|
@ -189,12 +189,14 @@ class ActHighlightWordList : AppCompatActivity(), View.OnClickListener {
|
|||
override fun onClick(v : View) {
|
||||
val o = v.tag
|
||||
if(o is HighlightWord) {
|
||||
when(v.id){
|
||||
R.id.btnSound->{
|
||||
when(v.id) {
|
||||
R.id.btnSound -> {
|
||||
sound(o)
|
||||
}
|
||||
R.id.ivSpeech->{
|
||||
App1.getAppState(this@ActHighlightWordList).addSpeech(o.name,dedupMode = DedupMode.None)
|
||||
|
||||
R.id.ivSpeech -> {
|
||||
App1.getAppState(this@ActHighlightWordList)
|
||||
.addSpeech(o.name, dedupMode = DedupMode.None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -206,22 +208,18 @@ class ActHighlightWordList : AppCompatActivity(), View.OnClickListener {
|
|||
DragItem(context, layoutId) {
|
||||
|
||||
override fun onBindDragView(clickedView : View, dragView : View) {
|
||||
|
||||
|
||||
dragView.findViewById<TextView>(R.id.tvName).text =
|
||||
clickedView.findViewById<TextView>(R.id.tvName).text
|
||||
|
||||
|
||||
dragView.findViewById<View>(R.id.btnSound).visibility =
|
||||
clickedView.findViewById<View>(R.id.btnSound).visibility
|
||||
|
||||
dragView.findViewById<View>(R.id.ivSpeech).visibility=
|
||||
|
||||
dragView.findViewById<View>(R.id.ivSpeech).visibility =
|
||||
clickedView.findViewById<View>(R.id.ivSpeech).visibility
|
||||
|
||||
dragView.findViewById<View>(R.id.item_layout).setBackgroundColor(
|
||||
getAttributeColor(
|
||||
this@ActHighlightWordList,
|
||||
R.attr.list_item_bg_pressed_dragged
|
||||
)
|
||||
)
|
||||
|
||||
dragView.findViewById<View>(R.id.item_layout)
|
||||
.setBackgroundColor(getAttributeColor(R.attr.list_item_bg_pressed_dragged))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,23 +248,27 @@ class ActHighlightWordList : AppCompatActivity(), View.OnClickListener {
|
|||
}
|
||||
|
||||
private fun create() {
|
||||
DlgTextInput.show(this, getString(R.string.new_item), "", callback = object : DlgTextInput.Callback {
|
||||
override fun onEmptyError() {
|
||||
showToast(this@ActHighlightWordList, 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()
|
||||
DlgTextInput.show(
|
||||
this,
|
||||
getString(R.string.new_item),
|
||||
"",
|
||||
callback = object : DlgTextInput.Callback {
|
||||
override fun onEmptyError() {
|
||||
showToast(true, R.string.word_empty)
|
||||
}
|
||||
edit(item)
|
||||
|
||||
dialog.dismissSafe()
|
||||
}
|
||||
})
|
||||
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()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun edit(item : HighlightWord) {
|
||||
|
|
|
@ -178,7 +178,7 @@ class ActKeywordFilter
|
|||
onLoadComplete(filter)
|
||||
} else {
|
||||
if(result != null) {
|
||||
showToast(this@ActKeywordFilter, true, result.error ?: "?")
|
||||
showToast(true, result.error ?: "?")
|
||||
}
|
||||
finish()
|
||||
}
|
||||
|
@ -287,9 +287,9 @@ class ActKeywordFilter
|
|||
result ?: return
|
||||
val error = result.error
|
||||
if(error != null) {
|
||||
showToast(this@ActKeywordFilter, true, result.error)
|
||||
showToast(true, result.error)
|
||||
} else {
|
||||
val app_state = App1.prepare(applicationContext,"ActKeywordFilter.save()")
|
||||
val app_state = App1.prepare(applicationContext, "ActKeywordFilter.save()")
|
||||
for(column in app_state.column_list) {
|
||||
if(column.type == ColumnType.KEYWORD_FILTER && column.access_info == account) {
|
||||
column.filter_reload_required = true
|
||||
|
|
|
@ -33,6 +33,7 @@ class ActLanguageFilter : AsyncActivity(), View.OnClickListener {
|
|||
)
|
||||
|
||||
companion object {
|
||||
|
||||
internal val log = LogCategory("ActLanguageFilter")
|
||||
|
||||
internal const val EXTRA_COLUMN_INDEX = "column_index"
|
||||
|
@ -240,7 +241,7 @@ class ActLanguageFilter : AsyncActivity(), View.OnClickListener {
|
|||
getString(if(item.allow) R.string.language_show else R.string.language_hide)
|
||||
)
|
||||
tv.textColor = getAttributeColor(
|
||||
this@ActLanguageFilter, when(item.allow) {
|
||||
when(item.allow) {
|
||||
true -> R.attr.colorContentText
|
||||
false -> R.attr.colorRegexFilterError
|
||||
}
|
||||
|
@ -310,6 +311,7 @@ class ActLanguageFilter : AsyncActivity(), View.OnClickListener {
|
|||
private object DlgLanguageFilter {
|
||||
|
||||
interface Callback {
|
||||
|
||||
fun onOK(code : String, allow : Boolean)
|
||||
fun onDelete(code : String)
|
||||
}
|
||||
|
@ -371,7 +373,7 @@ class ActLanguageFilter : AsyncActivity(), View.OnClickListener {
|
|||
btnPresets.setEnabledColor(
|
||||
activity,
|
||||
R.drawable.ic_edit,
|
||||
getAttributeColor(activity, R.attr.colorVectorDrawable),
|
||||
activity.getAttributeColor(R.attr.colorVectorDrawable),
|
||||
false
|
||||
)
|
||||
}
|
||||
|
@ -439,9 +441,8 @@ class ActLanguageFilter : AsyncActivity(), View.OnClickListener {
|
|||
val intent = intentOpenDocument("*/*")
|
||||
startActivityForResult(intent, REQUEST_CODE_IMPORT)
|
||||
} catch(ex : Throwable) {
|
||||
showToast(this, ex, "import failed.")
|
||||
showToast(ex, "import failed.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode : Int, resultCode : Int, data : Intent?) {
|
||||
|
@ -460,7 +461,7 @@ class ActLanguageFilter : AsyncActivity(), View.OnClickListener {
|
|||
log.d("import2 type=${contentResolver.getType(uri)}")
|
||||
val source = contentResolver.openInputStream(uri)
|
||||
if(source == null) {
|
||||
showToast( true, "openInputStream failed.")
|
||||
showToast(true, "openInputStream failed.")
|
||||
null
|
||||
} else {
|
||||
source.use { inStream ->
|
||||
|
|
|
@ -176,41 +176,41 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// 変更しない変数
|
||||
|
||||
val follow_complete_callback : EmptyCallback = {
|
||||
showToast(this@ActMain, false, R.string.follow_succeeded)
|
||||
val follow_complete_callback : ()->Unit = {
|
||||
showToast(false, R.string.follow_succeeded)
|
||||
}
|
||||
|
||||
val unfollow_complete_callback : EmptyCallback = {
|
||||
showToast(this@ActMain, false, R.string.unfollow_succeeded)
|
||||
val unfollow_complete_callback : ()->Unit = {
|
||||
showToast(false, R.string.unfollow_succeeded)
|
||||
}
|
||||
val cancel_follow_request_complete_callback : EmptyCallback = {
|
||||
showToast(this@ActMain, false, R.string.follow_request_cancelled)
|
||||
val cancel_follow_request_complete_callback : ()->Unit = {
|
||||
showToast(false, R.string.follow_request_cancelled)
|
||||
}
|
||||
|
||||
val favourite_complete_callback : EmptyCallback = {
|
||||
showToast(this@ActMain, false, R.string.favourite_succeeded)
|
||||
val favourite_complete_callback : ()->Unit = {
|
||||
showToast(false, R.string.favourite_succeeded)
|
||||
}
|
||||
val unfavourite_complete_callback : EmptyCallback = {
|
||||
showToast(this@ActMain, false, R.string.unfavourite_succeeded)
|
||||
val unfavourite_complete_callback : ()->Unit = {
|
||||
showToast(false, R.string.unfavourite_succeeded)
|
||||
}
|
||||
|
||||
val bookmark_complete_callback : EmptyCallback = {
|
||||
showToast(this@ActMain, false, R.string.bookmark_succeeded)
|
||||
val bookmark_complete_callback : ()->Unit = {
|
||||
showToast(false, R.string.bookmark_succeeded)
|
||||
}
|
||||
val unbookmark_complete_callback : EmptyCallback = {
|
||||
showToast(this@ActMain, false, R.string.unbookmark_succeeded)
|
||||
val unbookmark_complete_callback : ()->Unit = {
|
||||
showToast(false, R.string.unbookmark_succeeded)
|
||||
}
|
||||
|
||||
val boost_complete_callback : EmptyCallback = {
|
||||
showToast(this@ActMain, false, R.string.boost_succeeded)
|
||||
val boost_complete_callback : ()->Unit = {
|
||||
showToast(false, R.string.boost_succeeded)
|
||||
}
|
||||
|
||||
val unboost_complete_callback : EmptyCallback = {
|
||||
showToast(this@ActMain, false, R.string.unboost_succeeded)
|
||||
val unboost_complete_callback : ()->Unit = {
|
||||
showToast(false, R.string.unboost_succeeded)
|
||||
}
|
||||
|
||||
val reaction_complete_callback : EmptyCallback = {
|
||||
showToast(this@ActMain, false, R.string.reaction_succeeded)
|
||||
val reaction_complete_callback : ()->Unit = {
|
||||
showToast(false, R.string.reaction_succeeded)
|
||||
}
|
||||
|
||||
// 相対時刻の表記を定期的に更新する
|
||||
|
@ -566,7 +566,8 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
ItemViewHolder.toot_color_direct_me = Pref.ipTootColorDirectMe(pref)
|
||||
MyClickableSpan.showLinkUnderline = Pref.bpShowLinkUnderline(pref)
|
||||
MyClickableSpan.defaultLinkColor = Pref.ipLinkColor(pref).notZero()
|
||||
?: getAttributeColor(this, R.attr.colorLink)
|
||||
?: getAttributeColor(R.attr.colorLink)
|
||||
|
||||
CustomShare.reloadCache(this, pref)
|
||||
|
||||
te = SystemClock.elapsedRealtime()
|
||||
|
@ -1099,7 +1100,7 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
}
|
||||
|
||||
if(resultCode == Activity.RESULT_OK && data != null) {
|
||||
App1.openBrowser(this, data.data)
|
||||
openBrowser(data.data)
|
||||
} else if(resultCode == ActAccountSetting.RESULT_INPUT_ACCESS_TOKEN && data != null) {
|
||||
val db_id = data.getLongExtra(ActAccountSetting.EXTRA_DB_ID, - 1L)
|
||||
checkAccessToken2(db_id)
|
||||
|
@ -1195,7 +1196,7 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
) {
|
||||
this@ActMain.finish()
|
||||
} else {
|
||||
showToast(this@ActMain, false, R.string.missing_closeable_column)
|
||||
showToast(false, R.string.missing_closeable_column)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1205,7 +1206,6 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
|
||||
else -> {
|
||||
showToast(
|
||||
this@ActMain,
|
||||
false,
|
||||
R.string.cant_close_column_by_back_button_when_multiple_column_shown
|
||||
)
|
||||
|
@ -2048,28 +2048,25 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
// cancelled.
|
||||
}
|
||||
|
||||
error != null -> showToast(
|
||||
this@ActMain,
|
||||
true,
|
||||
"${result.error} ${result.requestInfo}".trim()
|
||||
)
|
||||
error != null ->
|
||||
showToast(true, "${result.error} ${result.requestInfo}".trim())
|
||||
|
||||
token_info == null -> showToast(this@ActMain, true, "can't get access token.")
|
||||
token_info == null -> showToast(true, "can't get access token.")
|
||||
|
||||
jsonObject == null -> showToast(this@ActMain, true, "can't parse json response.")
|
||||
jsonObject == null -> showToast(true, "can't parse json response.")
|
||||
|
||||
// 自分のユーザネームを取れなかった
|
||||
// …普通はエラーメッセージが設定されてるはずだが
|
||||
ta == null -> showToast(this@ActMain, true, "can't verify user credential.")
|
||||
ta == null -> showToast(true, "can't verify user credential.")
|
||||
|
||||
// アクセストークン更新時
|
||||
// インスタンスは同じだと思うが、ユーザ名が異なる可能性がある
|
||||
sa != null ->
|
||||
if(sa.username != ta.username) {
|
||||
showToast(this@ActMain, true, R.string.user_name_not_match)
|
||||
showToast(true, R.string.user_name_not_match)
|
||||
} else {
|
||||
showToast(
|
||||
this@ActMain,
|
||||
|
||||
false,
|
||||
R.string.access_token_updated_for,
|
||||
sa.acct.pretty
|
||||
|
@ -2100,7 +2097,7 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
|
||||
val apDomain = ti?.uri
|
||||
if(apDomain == null) {
|
||||
showToast(this@ActMain, false, "Can't get ActivityPub domain name.")
|
||||
showToast(false, "Can't get ActivityPub domain name.")
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -2138,7 +2135,7 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
}
|
||||
}
|
||||
|
||||
showToast(this@ActMain, false, R.string.account_confirmed)
|
||||
showToast(false, R.string.account_confirmed)
|
||||
|
||||
// 通知の更新が必要かもしれない
|
||||
PollingWorker.queueUpdateNotification(this@ActMain)
|
||||
|
@ -2221,7 +2218,7 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
}
|
||||
|
||||
override fun onEmptyError() {
|
||||
showToast(this@ActMain, true, R.string.token_not_specified)
|
||||
showToast(true, R.string.token_not_specified)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -2252,7 +2249,7 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
fun closeColumn(column : Column, bConfirmed : Boolean = false) {
|
||||
|
||||
if(column.dont_close) {
|
||||
showToast(this, false, R.string.column_has_dont_close_option)
|
||||
showToast(false, R.string.column_has_dont_close_option)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -2452,9 +2449,9 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
when(fullAcct.host.ascii) {
|
||||
"github.com",
|
||||
"twitter.com" ->
|
||||
App1.openCustomTab(this, mention.url)
|
||||
openCustomTab(mention.url)
|
||||
"gmail.com" ->
|
||||
App1.openBrowser(this, "mailto:${fullAcct.pretty}")
|
||||
openBrowser("mailto:${fullAcct.pretty}")
|
||||
|
||||
else ->
|
||||
Action_User.profile(
|
||||
|
@ -2485,11 +2482,11 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
val instanceHost = Host.parse(instance)
|
||||
when(instanceHost.ascii) {
|
||||
"github.com", "twitter.com" -> {
|
||||
App1.openCustomTab(this, "https://$instance/$user")
|
||||
openCustomTab("https://$instance/$user")
|
||||
}
|
||||
|
||||
"gmail.com" -> {
|
||||
App1.openBrowser(this, "mailto:$user@$instance")
|
||||
openBrowser("mailto:$user@$instance")
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
@ -2535,7 +2532,7 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
|
||||
}
|
||||
|
||||
App1.openCustomTab(this, opener.url)
|
||||
openCustomTab(opener.url)
|
||||
|
||||
} catch(ex : Throwable) {
|
||||
// warning.trace( ex );
|
||||
|
@ -2563,7 +2560,7 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
val footer_tab_indicator_color = Pref.ipFooterTabIndicatorColor(pref)
|
||||
|
||||
val colorColumnStripBackground = footer_tab_bg_color.notZero()
|
||||
?: getAttributeColor(this, R.attr.colorColumnStripBackground)
|
||||
?: getAttributeColor(R.attr.colorColumnStripBackground)
|
||||
|
||||
svColumnStrip.setBackgroundColor(colorColumnStripBackground)
|
||||
llQuickTootBar.setBackgroundColor(colorColumnStripBackground)
|
||||
|
@ -2572,7 +2569,7 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
?: colorColumnStripBackground
|
||||
|
||||
val colorButtonFg = footer_button_fg_color.notZero()
|
||||
?: getAttributeColor(this, R.attr.colorRippleEffect)
|
||||
?: getAttributeColor(R.attr.colorRippleEffect)
|
||||
|
||||
btnMenu.backgroundDrawable =
|
||||
getAdaptiveRippleDrawableRound(this, colorButtonBg, colorButtonFg)
|
||||
|
@ -2585,7 +2582,7 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
|
||||
val csl = ColorStateList.valueOf(
|
||||
footer_button_fg_color.notZero()
|
||||
?: getAttributeColor(this, R.attr.colorVectorDrawable)
|
||||
?: getAttributeColor(R.attr.colorVectorDrawable)
|
||||
)
|
||||
btnToot.imageTintList = csl
|
||||
btnMenu.imageTintList = csl
|
||||
|
@ -2598,7 +2595,7 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
vFooterDivider2.setBackgroundColor(c)
|
||||
|
||||
llColumnStrip.indicatorColor = footer_tab_indicator_color.notZero()
|
||||
?: getAttributeColor(this, R.attr.colorAccent)
|
||||
?: getAttributeColor(R.attr.colorAccent)
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2878,7 +2875,7 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
if(zipEntryCount != 0) {
|
||||
showToast(this@ActMain, ex, "importAppData failed.")
|
||||
showToast(ex, "importAppData failed.")
|
||||
}
|
||||
}
|
||||
// zipではなかった場合、zipEntryがない状態になる。例外はPH-1では出なかったが、出ても問題ないようにする。
|
||||
|
@ -2914,7 +2911,7 @@ class ActMain : AsyncActivity(), Column.Callback, View.OnClickListener,
|
|||
PollingWorker.queueAppDataImportAfter(this@ActMain)
|
||||
}
|
||||
|
||||
showToast(this@ActMain, true, R.string.import_completed_please_restart_app)
|
||||
showToast(true, R.string.import_completed_please_restart_app)
|
||||
finish()
|
||||
},
|
||||
preProc = {
|
||||
|
|
|
@ -107,9 +107,8 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
private lateinit var svDescription : View
|
||||
private lateinit var tvDescription : TextView
|
||||
private lateinit var tvStatus : TextView
|
||||
private lateinit var cbMute: CheckBox
|
||||
private var lastVolume = Float.NaN
|
||||
|
||||
private lateinit var cbMute : CheckBox
|
||||
private var lastVolume = Float.NaN
|
||||
|
||||
internal var buffering_last_shown : Long = 0
|
||||
|
||||
|
@ -149,7 +148,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
val now = SystemClock.elapsedRealtime()
|
||||
if(now - buffering_last_shown >= short_limit && exoPlayer.duration >= short_limit) {
|
||||
buffering_last_shown = now
|
||||
showToast(this@ActMediaViewer, false, R.string.video_buffering)
|
||||
showToast(false, R.string.video_buffering)
|
||||
}
|
||||
/*
|
||||
exoPlayer.getDuration() may returns negative value (TIME_UNSET ,same as Long.MIN_VALUE + 1).
|
||||
|
@ -163,7 +162,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
|
||||
override fun onPlayerError(error : ExoPlaybackException) {
|
||||
log.d("exoPlayer onPlayerError")
|
||||
showToast(this@ActMediaViewer, error, "player error.")
|
||||
showToast(error, "player error.")
|
||||
}
|
||||
|
||||
override fun onPositionDiscontinuity(reason : Int) {
|
||||
|
@ -187,7 +186,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
|
||||
outState.putLong(STATE_PLAYER_POS, exoPlayer.currentPosition)
|
||||
outState.putBoolean(STATE_PLAYER_PLAY_WHEN_READY, exoPlayer.playWhenReady)
|
||||
outState.putFloat(STATE_LAST_VOLUME,lastVolume)
|
||||
outState.putFloat(STATE_LAST_VOLUME, lastVolume)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState : Bundle?) {
|
||||
|
@ -252,14 +251,14 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
findViewById<View>(R.id.btnDownload).setOnClickListener(this)
|
||||
findViewById<View>(R.id.btnMore).setOnClickListener(this)
|
||||
|
||||
cbMute.setOnCheckedChangeListener{_,isChecked->
|
||||
cbMute.setOnCheckedChangeListener { _, isChecked ->
|
||||
if(isChecked) {
|
||||
// mute
|
||||
lastVolume = exoPlayer.volume
|
||||
exoPlayer.volume = 0f
|
||||
}else{
|
||||
} else {
|
||||
// unmute
|
||||
exoPlayer.volume = when{
|
||||
exoPlayer.volume = when {
|
||||
lastVolume.isNaN() -> 1f
|
||||
lastVolume <= 0f -> 1f
|
||||
else -> lastVolume
|
||||
|
@ -361,7 +360,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
private fun loadVideo(ta : TootAttachment, state : Bundle? = null) {
|
||||
|
||||
cbMute.vg(true)
|
||||
if(cbMute.isChecked && lastVolume.isFinite() ) {
|
||||
if(cbMute.isChecked && lastVolume.isFinite()) {
|
||||
exoPlayer.volume = 0f
|
||||
}
|
||||
|
||||
|
@ -399,7 +398,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
} else {
|
||||
exoPlayer.playWhenReady = state.getBoolean(STATE_PLAYER_PLAY_WHEN_READY, true)
|
||||
exoPlayer.seekTo(max(0L, state.getLong(STATE_PLAYER_POS, 0L)))
|
||||
lastVolume = state.getFloat(STATE_LAST_VOLUME,1f)
|
||||
lastVolume = state.getFloat(STATE_LAST_VOLUME, 1f)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,7 +485,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
@SuppressLint("StaticFieldLeak")
|
||||
private fun loadBitmap(ta : TootAttachment) {
|
||||
|
||||
cbMute.visibility=View.INVISIBLE
|
||||
cbMute.visibility = View.INVISIBLE
|
||||
|
||||
val urlList = ta.getLargeUrlList(App1.pref)
|
||||
if(urlList.isEmpty()) {
|
||||
|
@ -546,7 +545,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
return Pair(null, "image size <= 0")
|
||||
}
|
||||
|
||||
val dstSize = rotateSize(orientation,srcWidth,srcHeight)
|
||||
val dstSize = rotateSize(orientation, srcWidth, srcHeight)
|
||||
val dstSizeInt = Point(
|
||||
max(1, (dstSize.x + 0.5f).toInt()),
|
||||
max(1, (dstSize.y + 0.5f).toInt())
|
||||
|
@ -599,13 +598,13 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
) : Pair<TootApiResult?, ByteArray?> {
|
||||
val result = TootApiResult.makeWithCaption(url)
|
||||
|
||||
val request = try{
|
||||
val request = try {
|
||||
Request.Builder()
|
||||
.url(url)
|
||||
.cacheControl(App1.CACHE_CONTROL)
|
||||
.addHeader("Accept", "image/webp,image/*,*/*;q=0.8")
|
||||
.build()
|
||||
}catch(ex:Throwable){
|
||||
} catch(ex : Throwable) {
|
||||
result.setError(ex.withCaption("incorrect URL."))
|
||||
return Pair(result, null)
|
||||
}
|
||||
|
@ -667,7 +666,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
if(bitmap != null) {
|
||||
pbvImage.setBitmap(bitmap)
|
||||
} else if(result != null) {
|
||||
showToast(this@ActMediaViewer, true, result.error)
|
||||
showToast(true, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -684,7 +683,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
R.id.btnMore -> more(media_list[idx])
|
||||
}
|
||||
} catch(ex : Throwable) {
|
||||
showToast(this, ex, "action failed.")
|
||||
showToast(ex, "action failed.")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -702,7 +701,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
return
|
||||
}
|
||||
|
||||
val downLoadManager :DownloadManager = systemService(this)
|
||||
val downLoadManager : DownloadManager = systemService(this)
|
||||
?: error("missing DownloadManager system service")
|
||||
|
||||
val url = if(ta is TootAttachment) {
|
||||
|
@ -724,7 +723,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
it.remove()
|
||||
} else if(url == dh.url) {
|
||||
// 履歴に同じURLがあればエラーとする
|
||||
showToast(this, false, R.string.dont_repeat_download_to_same_url)
|
||||
showToast(false, R.string.dont_repeat_download_to_same_url)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -773,7 +772,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
|
||||
|
||||
downLoadManager.enqueue(request)
|
||||
showToast(this, false, R.string.downloading)
|
||||
showToast(false, R.string.downloading)
|
||||
}
|
||||
|
||||
private fun share(action : String, url : String) {
|
||||
|
@ -790,7 +789,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
|
||||
startActivity(intent)
|
||||
} catch(ex : Throwable) {
|
||||
showToast(this, ex, "can't open app.")
|
||||
showToast(ex, "can't open app.")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -812,10 +811,10 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
//クリップボードにデータを格納
|
||||
cm.setPrimaryClip(cd)
|
||||
|
||||
showToast(this, false, R.string.url_is_copied)
|
||||
showToast(false, R.string.url_is_copied)
|
||||
|
||||
} catch(ex : Throwable) {
|
||||
showToast(this, ex, "clipboard access failed.")
|
||||
showToast(ex, "clipboard access failed.")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -862,7 +861,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
startActivity(intent)
|
||||
} catch(ex : Throwable) {
|
||||
showToast(this@ActMediaViewer, ex, "can't open app.")
|
||||
showToast(ex, "can't open app.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -873,7 +872,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), PERMISSION_REQUEST_CODE
|
||||
)
|
||||
} else {
|
||||
showToast(this, true, R.string.missing_permission_to_access_media)
|
||||
showToast(true, R.string.missing_permission_to_access_media)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -892,7 +891,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
++ i
|
||||
}
|
||||
if(bNotGranted) {
|
||||
showToast(this, true, R.string.missing_permission_to_access_media)
|
||||
showToast(true, R.string.missing_permission_to_access_media)
|
||||
} else {
|
||||
download(media_list[idx])
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import com.woxthebox.draglistview.swipe.ListSwipeItem
|
|||
class ActMutedApp : AppCompatActivity() {
|
||||
|
||||
companion object {
|
||||
|
||||
private val log = LogCategory("ActMutedApp")
|
||||
}
|
||||
|
||||
|
@ -168,9 +169,8 @@ class ActMutedApp : AppCompatActivity() {
|
|||
dragView.findViewById<TextView>(R.id.tvName).text =
|
||||
clickedView.findViewById<TextView>(R.id.tvName).text
|
||||
|
||||
dragView.findViewById<View>(R.id.item_layout).setBackgroundColor(
|
||||
getAttributeColor(this@ActMutedApp, R.attr.list_item_bg_pressed_dragged)
|
||||
)
|
||||
dragView.findViewById<View>(R.id.item_layout)
|
||||
.setBackgroundColor(getAttributeColor(R.attr.list_item_bg_pressed_dragged))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.*
|
|||
class ActMutedPseudoAccount : AppCompatActivity() {
|
||||
|
||||
companion object {
|
||||
|
||||
private val log = LogCategory("ActMutedPseudoAccount")
|
||||
}
|
||||
|
||||
|
@ -167,9 +168,8 @@ class ActMutedPseudoAccount : AppCompatActivity() {
|
|||
dragView.findViewById<TextView>(R.id.tvName).text =
|
||||
clickedView.findViewById<TextView>(R.id.tvName).text
|
||||
|
||||
dragView.findViewById<View>(R.id.item_layout).setBackgroundColor(
|
||||
getAttributeColor(this@ActMutedPseudoAccount, R.attr.list_item_bg_pressed_dragged)
|
||||
)
|
||||
dragView.findViewById<View>(R.id.item_layout)
|
||||
.setBackgroundColor(getAttributeColor(R.attr.list_item_bg_pressed_dragged))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -168,9 +168,8 @@ class ActMutedWord : AppCompatActivity() {
|
|||
dragView.findViewById<TextView>(R.id.tvName).text =
|
||||
clickedView.findViewById<TextView>(R.id.tvName).text
|
||||
|
||||
dragView.findViewById<View>(R.id.item_layout).setBackgroundColor(
|
||||
getAttributeColor(this@ActMutedWord, R.attr.list_item_bg_pressed_dragged)
|
||||
)
|
||||
dragView.findViewById<View>(R.id.item_layout)
|
||||
.setBackgroundColor(getAttributeColor(R.attr.list_item_bg_pressed_dragged))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ class ActNickname : AppCompatActivity(), View.OnClickListener, ColorPickerDialog
|
|||
|
||||
tvAcct.text = acctPretty
|
||||
|
||||
val ac = AcctColor.load(acctAscii,acctPretty)
|
||||
val ac = AcctColor.load(acctAscii, acctPretty)
|
||||
color_bg = ac.color_bg
|
||||
color_fg = ac.color_fg
|
||||
etNickname.setText(ac.nickname)
|
||||
|
@ -180,7 +180,7 @@ class ActNickname : AppCompatActivity(), View.OnClickListener, ColorPickerDialog
|
|||
private fun show() {
|
||||
val s = etNickname.text.toString().trim { it <= ' ' }
|
||||
tvPreview.text = s.notEmpty() ?: acctPretty
|
||||
tvPreview.textColor = color_fg.notZero() ?: getAttributeColor(this, R.attr.colorTimeSmall)
|
||||
tvPreview.textColor = color_fg.notZero() ?: getAttributeColor(R.attr.colorTimeSmall)
|
||||
tvPreview.backgroundColor = color_bg
|
||||
}
|
||||
|
||||
|
|
|
@ -493,7 +493,7 @@ class ActPost : AsyncActivity(),
|
|||
private var mushroom_end : Int = 0
|
||||
|
||||
private val link_click_listener : (View, MyClickableSpan) -> Unit = { _, span ->
|
||||
App1.openBrowser(this@ActPost, span.linkInfo.url)
|
||||
openBrowser(span.linkInfo.url)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
@ -557,7 +557,7 @@ class ActPost : AsyncActivity(),
|
|||
if(uri != null) {
|
||||
addAttachment(uri)
|
||||
} else {
|
||||
showToast(this@ActPost, false, "missing image uri")
|
||||
showToast(false, "missing image uri")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -612,7 +612,7 @@ class ActPost : AsyncActivity(),
|
|||
}
|
||||
|
||||
if(account_list.isEmpty()) {
|
||||
showToast(this, true, R.string.please_add_account)
|
||||
showToast(true, R.string.please_add_account)
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
@ -1413,7 +1413,6 @@ class ActPost : AsyncActivity(),
|
|||
tvCharCount.text = remain.toString()
|
||||
tvCharCount.setTextColor(
|
||||
getAttributeColor(
|
||||
this,
|
||||
if(remain < 0)
|
||||
R.attr.colorRegexFilterError
|
||||
else
|
||||
|
@ -1495,7 +1494,7 @@ class ActPost : AsyncActivity(),
|
|||
|
||||
if(a == null) {
|
||||
btnAccount.text = getString(R.string.not_selected)
|
||||
btnAccount.setTextColor(getAttributeColor(this, android.R.attr.textColorPrimary))
|
||||
btnAccount.setTextColor(getAttributeColor(android.R.attr.textColorPrimary))
|
||||
btnAccount.setBackgroundResource(R.drawable.btn_bg_transparent_round6dp)
|
||||
} else {
|
||||
|
||||
|
@ -1515,7 +1514,7 @@ class ActPost : AsyncActivity(),
|
|||
}
|
||||
|
||||
btnAccount.textColor = ac.color_fg.notZero()
|
||||
?: getAttributeColor(this, android.R.attr.textColorPrimary)
|
||||
?: getAttributeColor(android.R.attr.textColorPrimary)
|
||||
}
|
||||
updateTextCount()
|
||||
updateFeaturedTags()
|
||||
|
@ -1525,19 +1524,19 @@ class ActPost : AsyncActivity(),
|
|||
|
||||
if(scheduledStatus != null) {
|
||||
// 予約投稿の再編集ではアカウントを切り替えられない
|
||||
showToast(this, false, R.string.cant_change_account_when_editing_scheduled_status)
|
||||
showToast(false, R.string.cant_change_account_when_editing_scheduled_status)
|
||||
return
|
||||
}
|
||||
|
||||
if(attachment_list.isNotEmpty()) {
|
||||
// 添付ファイルがあったら確認の上添付ファイルを捨てないと切り替えられない
|
||||
showToast(this, false, R.string.cant_change_account_when_attachment_specified)
|
||||
showToast(false, R.string.cant_change_account_when_attachment_specified)
|
||||
return
|
||||
}
|
||||
|
||||
if(redraft_status_id != null) {
|
||||
// 添付ファイルがあったら確認の上添付ファイルを捨てないと切り替えられない
|
||||
showToast(this, false, R.string.cant_change_account_when_redraft)
|
||||
showToast(false, R.string.cant_change_account_when_redraft)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1598,7 +1597,7 @@ class ActPost : AsyncActivity(),
|
|||
selectAccount(a)
|
||||
try {
|
||||
if(TootVisibility.isVisibilitySpoilRequired(this.visibility, a.visibility)) {
|
||||
showToast(this@ActPost, true, R.string.spoil_visibility_for_account)
|
||||
showToast(true, R.string.spoil_visibility_for_account)
|
||||
this.visibility = a.visibility
|
||||
}
|
||||
|
||||
|
@ -1644,7 +1643,6 @@ class ActPost : AsyncActivity(),
|
|||
setAccountWithVisibilityConversion(access_info)
|
||||
} else {
|
||||
showToast(
|
||||
this@ActPost,
|
||||
true,
|
||||
getString(R.string.in_reply_to_id_conversion_failed) + "\n" + result.error
|
||||
)
|
||||
|
@ -1701,7 +1699,7 @@ class ActPost : AsyncActivity(),
|
|||
val pa = try {
|
||||
attachment_list[idx]
|
||||
} catch(ex : Throwable) {
|
||||
showToast(this, false, ex.withCaption("can't get attachment item[$idx]."))
|
||||
showToast(false, ex.withCaption("can't get attachment item[$idx]."))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1771,7 +1769,7 @@ class ActPost : AsyncActivity(),
|
|||
if(new_attachment != null) {
|
||||
pa.attachment = attachment
|
||||
} else {
|
||||
showToast(this@ActPost, true, result.error)
|
||||
showToast(true, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -1798,7 +1796,7 @@ class ActPost : AsyncActivity(),
|
|||
startActivityForResult(intent, REQUEST_CODE_CUSTOM_THUMBNAIL)
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(this, ex, "ACTION_GET_CONTENT failed.")
|
||||
showToast(ex, "ACTION_GET_CONTENT failed.")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1809,19 +1807,19 @@ class ActPost : AsyncActivity(),
|
|||
|
||||
val account = this@ActPost.account
|
||||
if(account == null) {
|
||||
showToast(this, false, R.string.account_select_please)
|
||||
showToast(false, R.string.account_select_please)
|
||||
return
|
||||
}
|
||||
|
||||
val mime_type = getMimeType(src.uri, src.mimeType)
|
||||
if(mime_type?.isEmpty() != false) {
|
||||
showToast(this, false, R.string.mime_type_missing)
|
||||
showToast(false, R.string.mime_type_missing)
|
||||
return
|
||||
}
|
||||
|
||||
val pa = lastPostAttachment
|
||||
if(pa == null || ! attachment_list.contains(pa)) {
|
||||
showToast(this, true, "lost attachment information")
|
||||
showToast(true, "lost attachment information")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1922,7 +1920,7 @@ class ActPost : AsyncActivity(),
|
|||
|
||||
override fun handleResult(result : TootApiResult?) {
|
||||
showMediaAttachment()
|
||||
result?.error?.let { showToast(this@ActPost, true, it) }
|
||||
result?.error?.let { showToast(true, it) }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1946,7 +1944,7 @@ class ActPost : AsyncActivity(),
|
|||
private fun editAttachmentDescription(pa : PostAttachment) {
|
||||
val a = pa.attachment
|
||||
if(a == null) {
|
||||
showToast(this, true, R.string.attachment_description_cant_edit_while_uploading)
|
||||
showToast(true, R.string.attachment_description_cant_edit_while_uploading)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1960,7 +1958,7 @@ class ActPost : AsyncActivity(),
|
|||
}
|
||||
|
||||
override fun onEmptyError() {
|
||||
showToast(this@ActPost, true, R.string.description_empty)
|
||||
showToast(true, R.string.description_empty)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1998,7 +1996,7 @@ class ActPost : AsyncActivity(),
|
|||
dialog.dismissSafe()
|
||||
|
||||
} else {
|
||||
showToast(this@ActPost, true, result.error)
|
||||
showToast(true, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -2007,12 +2005,12 @@ class ActPost : AsyncActivity(),
|
|||
private fun openAttachment() {
|
||||
|
||||
if(attachment_list.size >= 4) {
|
||||
showToast(this, false, R.string.attachment_too_many)
|
||||
showToast(false, R.string.attachment_too_many)
|
||||
return
|
||||
}
|
||||
|
||||
if(account == null) {
|
||||
showToast(this, false, R.string.account_select_please)
|
||||
showToast(false, R.string.account_select_please)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -2068,7 +2066,7 @@ class ActPost : AsyncActivity(),
|
|||
startActivityForResult(intent, REQUEST_CODE_ATTACHMENT_OLD)
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(this, ex, "ACTION_GET_CONTENT failed.")
|
||||
showToast(ex, "ACTION_GET_CONTENT failed.")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2109,7 +2107,7 @@ class ActPost : AsyncActivity(),
|
|||
try {
|
||||
val cache_dir = externalCacheDir
|
||||
if(cache_dir == null) {
|
||||
showToast(this, false, "getExternalCacheDir returns null.")
|
||||
showToast(false, "getExternalCacheDir returns null.")
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -2145,7 +2143,7 @@ class ActPost : AsyncActivity(),
|
|||
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(this, ex, "Resizing image failed.")
|
||||
showToast(ex, "Resizing image failed.")
|
||||
}
|
||||
|
||||
break
|
||||
|
@ -2219,35 +2217,35 @@ class ActPost : AsyncActivity(),
|
|||
) {
|
||||
|
||||
if(attachment_list.size >= 4) {
|
||||
showToast(this, false, R.string.attachment_too_many)
|
||||
showToast(false, R.string.attachment_too_many)
|
||||
return
|
||||
}
|
||||
|
||||
val account = this@ActPost.account
|
||||
if(account == null) {
|
||||
showToast(this, false, R.string.account_select_please)
|
||||
showToast(false, R.string.account_select_please)
|
||||
return
|
||||
}
|
||||
|
||||
val mime_type = getMimeType(uri, mimeTypeArg)
|
||||
if(mime_type?.isEmpty() != false) {
|
||||
showToast(this, false, R.string.mime_type_missing)
|
||||
showToast(false, R.string.mime_type_missing)
|
||||
return
|
||||
}
|
||||
|
||||
val instance = TootInstance.getCached(account.apiHost.ascii)
|
||||
if(instance?.instanceType == TootInstance.InstanceType.Pixelfed) {
|
||||
if(in_reply_to_id != null) {
|
||||
showToast(this, true, R.string.pixelfed_does_not_allow_reply_with_media)
|
||||
showToast(true, R.string.pixelfed_does_not_allow_reply_with_media)
|
||||
return
|
||||
}
|
||||
if(! acceptable_mime_types_pixelfed.contains(mime_type)) {
|
||||
showToast(this, true, R.string.mime_type_not_acceptable, mime_type)
|
||||
showToast(true, R.string.mime_type_not_acceptable, mime_type)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if(! acceptable_mime_types.contains(mime_type)) {
|
||||
showToast(this, true, R.string.mime_type_not_acceptable, mime_type)
|
||||
showToast(true, R.string.mime_type_not_acceptable, mime_type)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -2261,7 +2259,7 @@ class ActPost : AsyncActivity(),
|
|||
// アップロード開始トースト(連発しない)
|
||||
val now = System.currentTimeMillis()
|
||||
if(now - lastAttachmentAdd >= 5000L) {
|
||||
showToast(this, false, R.string.attachment_uploading)
|
||||
showToast(false, R.string.attachment_uploading)
|
||||
}
|
||||
lastAttachmentAdd = now
|
||||
|
||||
|
@ -2547,7 +2545,6 @@ class ActPost : AsyncActivity(),
|
|||
pa.status = PostAttachment.STATUS_UPLOAD_FAILED
|
||||
if(result != null) {
|
||||
showToast(
|
||||
this@ActPost,
|
||||
true,
|
||||
"${result.error} ${result.response?.request?.method} ${result.response?.request?.url}"
|
||||
)
|
||||
|
@ -2581,7 +2578,7 @@ class ActPost : AsyncActivity(),
|
|||
|
||||
val now = System.currentTimeMillis()
|
||||
if(now - lastAttachmentComplete >= 5000L) {
|
||||
showToast(this@ActPost, false, R.string.attachment_uploaded)
|
||||
showToast(false, R.string.attachment_uploaded)
|
||||
}
|
||||
lastAttachmentComplete = now
|
||||
|
||||
|
@ -2626,7 +2623,7 @@ class ActPost : AsyncActivity(),
|
|||
startActivityForResult(intent, REQUEST_CODE_CAMERA)
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(this, ex, "opening camera app failed.")
|
||||
showToast(ex, "opening camera app failed.")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2636,7 +2633,7 @@ class ActPost : AsyncActivity(),
|
|||
startActivityForResult(Intent(action), requestCode)
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(this, ex, errorCaption)
|
||||
showToast(ex, errorCaption)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2648,7 +2645,7 @@ class ActPost : AsyncActivity(),
|
|||
PERMISSION_REQUEST_CODE
|
||||
)
|
||||
} else {
|
||||
showToast(this, true, R.string.missing_permission_to_access_media)
|
||||
showToast(true, R.string.missing_permission_to_access_media)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2667,7 +2664,7 @@ class ActPost : AsyncActivity(),
|
|||
++ i
|
||||
}
|
||||
if(bNotGranted) {
|
||||
showToast(this, true, R.string.missing_permission_to_access_media)
|
||||
showToast(true, R.string.missing_permission_to_access_media)
|
||||
} else {
|
||||
openAttachment()
|
||||
}
|
||||
|
@ -2763,7 +2760,7 @@ class ActPost : AsyncActivity(),
|
|||
// アップロード中は投稿できない
|
||||
for(pa in attachment_list) {
|
||||
if(pa.status == PostAttachment.STATUS_UPLOADING) {
|
||||
showToast(this, false, R.string.media_attachment_still_uploading)
|
||||
showToast(false, R.string.media_attachment_still_uploading)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -2850,7 +2847,7 @@ class ActPost : AsyncActivity(),
|
|||
}
|
||||
|
||||
override fun onScheduledPostComplete(target_account : SavedAccount) {
|
||||
showToast(this@ActPost, false, getString(R.string.scheduled_status_sent))
|
||||
showToast(false, getString(R.string.scheduled_status_sent))
|
||||
val data = Intent()
|
||||
data.putExtra(EXTRA_POSTED_ACCT, target_account.acct.ascii)
|
||||
setResult(RESULT_OK, data)
|
||||
|
|
|
@ -161,7 +161,7 @@ class ActText : AppCompatActivity(), View.OnClickListener {
|
|||
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(this, ex, "send failed.")
|
||||
showToast(ex, "send failed.")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ class ActText : AppCompatActivity(), View.OnClickListener {
|
|||
private fun search() {
|
||||
val sv = selection
|
||||
if(sv.isEmpty()) {
|
||||
showToast(this, false, "please select search keyword")
|
||||
showToast(false, "please select search keyword")
|
||||
return
|
||||
}
|
||||
try {
|
||||
|
@ -180,7 +180,7 @@ class ActText : AppCompatActivity(), View.OnClickListener {
|
|||
}
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(this, ex, "search failed.")
|
||||
showToast(ex, "search failed.")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ class ActText : AppCompatActivity(), View.OnClickListener {
|
|||
private fun searchToot(@Suppress("SameParameterValue") resultCode : Int) {
|
||||
val sv = selection
|
||||
if(sv.isEmpty()) {
|
||||
showToast(this, false, "please select search keyword")
|
||||
showToast(false, "please select search keyword")
|
||||
return
|
||||
}
|
||||
try {
|
||||
|
@ -206,10 +206,10 @@ class ActText : AppCompatActivity(), View.OnClickListener {
|
|||
try {
|
||||
MutedWord.save(selection)
|
||||
App1.getAppState(this).onMuteUpdated()
|
||||
showToast(this, false, R.string.word_was_muted)
|
||||
showToast(false, R.string.word_was_muted)
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(this, ex, "muteWord failed.")
|
||||
showToast(ex, "muteWord failed.")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,27 +3,14 @@ package jp.juggler.subwaytooter
|
|||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.content.res.ColorStateList
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.database.sqlite.SQLiteOpenHelper
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.WindowInsetsController
|
||||
import android.view.WindowManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.GlideBuilder
|
||||
import com.bumptech.glide.Registry
|
||||
|
@ -32,13 +19,10 @@ import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory
|
|||
import com.bumptech.glide.load.engine.executor.GlideExecutor
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
import jp.juggler.subwaytooter.api.TootApiClient
|
||||
import jp.juggler.subwaytooter.api.entity.TootAttachment
|
||||
import jp.juggler.subwaytooter.dialog.DlgAppPicker
|
||||
import jp.juggler.subwaytooter.table.*
|
||||
import jp.juggler.subwaytooter.util.CustomEmojiCache
|
||||
import jp.juggler.subwaytooter.util.CustomEmojiLister
|
||||
import jp.juggler.subwaytooter.util.ProgressResponseBody
|
||||
import jp.juggler.subwaytooter.util.cn
|
||||
import jp.juggler.util.*
|
||||
import okhttp3.*
|
||||
import org.conscrypt.Conscrypt
|
||||
|
@ -51,7 +35,6 @@ import java.security.Security
|
|||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.math.max
|
||||
import kotlin.math.pow
|
||||
|
||||
class App1 : Application() {
|
||||
|
||||
|
@ -315,7 +298,7 @@ class App1 : Application() {
|
|||
|
||||
initializeFont()
|
||||
|
||||
pref = Pref.pref(app_context)
|
||||
pref = app_context.pref()
|
||||
|
||||
run {
|
||||
|
||||
|
@ -518,7 +501,7 @@ class App1 : Application() {
|
|||
}
|
||||
|
||||
fun setActivityTheme(
|
||||
activity : Activity,
|
||||
activity : AppCompatActivity,
|
||||
noActionBar : Boolean = false,
|
||||
forceDark : Boolean = false
|
||||
) {
|
||||
|
@ -534,7 +517,7 @@ class App1 : Application() {
|
|||
}
|
||||
)
|
||||
|
||||
setStatusBarColor(activity, forceDark = forceDark)
|
||||
activity.setStatusBarColor(forceDark = forceDark)
|
||||
}
|
||||
|
||||
internal val CACHE_CONTROL = CacheControl.Builder()
|
||||
|
@ -610,147 +593,6 @@ class App1 : Application() {
|
|||
|
||||
}
|
||||
|
||||
// returns true if activity is opened.
|
||||
// returns false if fallback required
|
||||
private fun startActivityExcludeMyApp(
|
||||
activity : AppCompatActivity,
|
||||
intent : Intent,
|
||||
startAnimationBundle : Bundle? = null
|
||||
) : Boolean {
|
||||
try {
|
||||
val pm = activity.packageManager !!
|
||||
val myName = activity.packageName
|
||||
|
||||
val filter : (ResolveInfo) -> Boolean = {
|
||||
it.activityInfo.packageName != myName &&
|
||||
it.activityInfo.exported &&
|
||||
- 1 == it.activityInfo.packageName.indexOf("com.huawei.android.internal")
|
||||
}
|
||||
|
||||
// resolveActivity がこのアプリ以外のActivityを返すなら、それがベストなんだろう
|
||||
// ただしAndroid M以降はMATCH_DEFAULT_ONLYだと「常時」が設定されてないとnullを返す
|
||||
val ri = pm.resolveActivity(
|
||||
intent,
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PackageManager.MATCH_ALL
|
||||
} else {
|
||||
PackageManager.MATCH_DEFAULT_ONLY
|
||||
}
|
||||
)?.takeIf(filter)
|
||||
|
||||
if(ri != null) {
|
||||
intent.setClassName(ri.activityInfo.packageName, ri.activityInfo.name)
|
||||
activity.startActivity(intent, startAnimationBundle)
|
||||
return true
|
||||
}
|
||||
|
||||
return DlgAppPicker(
|
||||
activity,
|
||||
intent,
|
||||
autoSelect = true,
|
||||
filter = filter
|
||||
) {
|
||||
try {
|
||||
intent.component = it.cn()
|
||||
activity.startActivity(intent, startAnimationBundle)
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(activity, ex, "can't open. ${intent.data}")
|
||||
}
|
||||
}.show()
|
||||
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(activity, ex, "can't open. ${intent.data}")
|
||||
return true // fallback not required in this case
|
||||
}
|
||||
}
|
||||
|
||||
fun openBrowser(activity : AppCompatActivity, uri : Uri?) {
|
||||
if(uri != null) {
|
||||
val rv = startActivityExcludeMyApp(activity, Intent(Intent.ACTION_VIEW, uri))
|
||||
if(! rv) showToast(activity, true, "there is no app that can open $uri")
|
||||
}
|
||||
}
|
||||
|
||||
fun openBrowser(activity : AppCompatActivity, url : String?) =
|
||||
openBrowser(activity, url.mayUri())
|
||||
|
||||
// ubway Tooterの「アプリ設定/挙動/リンクを開く際にCustom Tabsを使わない」をONにして
|
||||
// 投稿のコンテキストメニューの「トゥートへのアクション/Webページを開く」「ユーザへのアクション/Webページを開く」を使うと
|
||||
// 投げたインテントをST自身が受け取って「次のアカウントから開く」ダイアログが出て
|
||||
// 「Webページを開く」をまた押すと無限ループしてダイアログの影が徐々に濃くなりそのうち壊れる
|
||||
// これを避けるには、投稿やトゥートを開く際に bpDontUseCustomTabs がオンならST以外のアプリを列挙したアプリ選択ダイアログを出すしかない
|
||||
fun openCustomTabOrBrowser(activity : AppCompatActivity, url : String) {
|
||||
if(! Pref.bpDontUseCustomTabs(pref)) {
|
||||
openCustomTab(activity, url)
|
||||
} else {
|
||||
openBrowser(activity, url)
|
||||
}
|
||||
}
|
||||
|
||||
// Chrome Custom Tab を開く
|
||||
fun openCustomTab(activity : AppCompatActivity, url : String) {
|
||||
if(Pref.bpDontUseCustomTabs(pref)) {
|
||||
openCustomTabOrBrowser(activity, url)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if(url.startsWith("http") && Pref.bpPriorChrome(pref)) {
|
||||
try {
|
||||
// 初回はChrome指定で試す
|
||||
val customTabsIntent = CustomTabsIntent.Builder()
|
||||
.setToolbarColor(getAttributeColor(activity, R.attr.colorPrimary))
|
||||
.setShowTitle(true)
|
||||
.build()
|
||||
|
||||
val rv = startActivityExcludeMyApp(
|
||||
activity,
|
||||
customTabsIntent.intent.also {
|
||||
it.component = ComponentName(
|
||||
"com.android.chrome",
|
||||
"com.google.android.apps.chrome.Main"
|
||||
)
|
||||
it.data = url.toUri()
|
||||
},
|
||||
customTabsIntent.startAnimationBundle
|
||||
)
|
||||
if(rv) return
|
||||
} catch(ex2 : Throwable) {
|
||||
log.e(ex2, "openChromeTab: missing chrome. retry to other application.")
|
||||
}
|
||||
}
|
||||
|
||||
// Chromeがないようなのでcomponent指定なしでリトライ
|
||||
val customTabsIntent = CustomTabsIntent.Builder()
|
||||
.setToolbarColor(getAttributeColor(activity, R.attr.colorPrimary))
|
||||
.setShowTitle(true)
|
||||
.build()
|
||||
|
||||
val rv = startActivityExcludeMyApp(
|
||||
activity,
|
||||
customTabsIntent.intent.also {
|
||||
it.data = url.toUri()
|
||||
},
|
||||
customTabsIntent.startAnimationBundle
|
||||
)
|
||||
if(! rv) {
|
||||
showToast(activity, true, "the browser app is not installed.")
|
||||
}
|
||||
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
val scheme = url.mayUri()?.scheme ?: url
|
||||
showToast(activity, true, "can't open browser app for %s", scheme)
|
||||
}
|
||||
}
|
||||
|
||||
fun openCustomTab(activity : AppCompatActivity, ta : TootAttachment) {
|
||||
val url = ta.getLargeUrl(pref) ?: return
|
||||
openCustomTab(activity, url)
|
||||
}
|
||||
|
||||
// https://developer.android.com/preview/features/gesturalnav?hl=ja
|
||||
fun initEdgeToEdge(@Suppress("UNUSED_PARAMETER") activity : Activity) {
|
||||
// if(Build.VERSION.SDK_INT >= 29){
|
||||
|
|
|
@ -10,6 +10,7 @@ import android.widget.TextView
|
|||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import jp.juggler.subwaytooter.util.CustomShareTarget
|
||||
import jp.juggler.subwaytooter.util.openBrowser
|
||||
import jp.juggler.util.*
|
||||
import org.jetbrains.anko.backgroundDrawable
|
||||
|
||||
|
@ -537,7 +538,7 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
val intent = intentOpenDocument("*/*")
|
||||
startActivityForResult(intent, ActAppSetting.REQUEST_CODE_TIMELINE_FONT)
|
||||
} catch(ex : Throwable) {
|
||||
showToast(this, ex, "could not open picker for font")
|
||||
showToast(ex, "could not open picker for font")
|
||||
}
|
||||
}
|
||||
onClickReset = {
|
||||
|
@ -559,7 +560,7 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
val intent = intentOpenDocument("*/*")
|
||||
startActivityForResult(intent, ActAppSetting.REQUEST_CODE_TIMELINE_FONT_BOLD)
|
||||
} catch(ex : Throwable) {
|
||||
showToast(this, ex, "could not open picker for font")
|
||||
showToast(ex, "could not open picker for font")
|
||||
}
|
||||
}
|
||||
onClickReset = {
|
||||
|
@ -701,10 +702,7 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
sw(Pref.bpInstanceTicker, R.string.show_instance_ticker) {
|
||||
desc = R.string.instance_ticker_copyright
|
||||
descClick = {
|
||||
App1.openBrowser(
|
||||
this,
|
||||
"https://github.com/MiyonMiyon/InstanceTicker_List"
|
||||
)
|
||||
openBrowser("https://github.com/MiyonMiyon/InstanceTicker_List")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -769,12 +767,12 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
colorAlpha(Pref.ipEventBgColorQuote, R.string.quote_renote)
|
||||
colorAlpha(Pref.ipEventBgColorVote, R.string.vote_polls)
|
||||
colorAlpha(Pref.ipEventBgColorStatus, R.string.status)
|
||||
|
||||
|
||||
colorAlpha(
|
||||
Pref.ipConversationMainTootBgColor,
|
||||
R.string.conversation_main_toot_background_color
|
||||
)
|
||||
|
||||
|
||||
colorAlpha(Pref.ipEventBgColorGap, R.string.gap)
|
||||
}
|
||||
|
||||
|
@ -800,12 +798,12 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
|
||||
val header_bg = when {
|
||||
color_column_header_bg != 0 -> color_column_header_bg
|
||||
else -> getAttributeColor(activity, R.attr.color_column_header)
|
||||
else -> activity.getAttributeColor(R.attr.color_column_header)
|
||||
}
|
||||
|
||||
val header_fg = when {
|
||||
color_column_header_fg != 0 -> color_column_header_fg
|
||||
else -> getAttributeColor(activity, R.attr.colorColumnHeaderName)
|
||||
else -> activity.getAttributeColor(R.attr.colorColumnHeaderName)
|
||||
}
|
||||
|
||||
llColumnHeader.background = getAdaptiveRippleDrawable(header_bg, header_fg)
|
||||
|
@ -836,12 +834,12 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
|
||||
tvSampleAcct.setTextColor(
|
||||
color_column_acct.notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorTimeSmall)
|
||||
?: activity.getAttributeColor(R.attr.colorTimeSmall)
|
||||
)
|
||||
|
||||
tvSampleContent.setTextColor(
|
||||
color_column_text.notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorContentText)
|
||||
?: activity.getAttributeColor(R.attr.colorContentText)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -876,7 +874,7 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
val footer_tab_indicator_color = Pref.ipFooterTabIndicatorColor(pref)
|
||||
|
||||
val colorColumnStripBackground = footer_tab_bg_color.notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorColumnStripBackground)
|
||||
?: activity.getAttributeColor(R.attr.colorColumnStripBackground)
|
||||
|
||||
llFooterBG.setBackgroundColor(colorColumnStripBackground)
|
||||
|
||||
|
@ -884,7 +882,7 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
?: colorColumnStripBackground
|
||||
|
||||
val colorButtonFg = footer_button_fg_color.notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorRippleEffect)
|
||||
?: activity.getAttributeColor(R.attr.colorRippleEffect)
|
||||
|
||||
ivFooterMenu.backgroundDrawable =
|
||||
getAdaptiveRippleDrawableRound(activity, colorButtonBg, colorButtonFg)
|
||||
|
@ -893,7 +891,7 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
|
||||
val csl = ColorStateList.valueOf(
|
||||
footer_button_fg_color.notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorVectorDrawable)
|
||||
?: activity.getAttributeColor(R.attr.colorVectorDrawable)
|
||||
)
|
||||
ivFooterToot.imageTintList = csl
|
||||
ivFooterMenu.imageTintList = csl
|
||||
|
@ -905,7 +903,7 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
|
||||
vIndicator.setBackgroundColor(
|
||||
footer_tab_indicator_color.notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorAccent)
|
||||
?: activity.getAttributeColor(R.attr.colorAccent)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -931,11 +929,11 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
}
|
||||
|
||||
colorOpaque(Pref.ipStatusBarColor, R.string.status_bar_color) {
|
||||
changed = { setStatusBarColor(this) }
|
||||
changed = { setStatusBarColor() }
|
||||
}
|
||||
|
||||
colorOpaque(Pref.ipNavigationBarColor, R.string.navigation_bar_color) {
|
||||
changed = { setStatusBarColor(this) }
|
||||
changed = { setStatusBarColor() }
|
||||
}
|
||||
|
||||
colorOpaque(Pref.ipSearchBgColor, R.string.search_bar_background_color)
|
||||
|
@ -958,15 +956,15 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
|
||||
section(R.string.developer_options) {
|
||||
sw(Pref.bpCheckBetaVersion, R.string.check_beta_release)
|
||||
|
||||
|
||||
action(R.string.drawable_list) {
|
||||
action = { startActivity(Intent(this, ActDrawableList::class.java)) }
|
||||
}
|
||||
action(R.string.exit_reasons) {
|
||||
action = {
|
||||
if(Build.VERSION.SDK_INT >= 30 ){
|
||||
if(Build.VERSION.SDK_INT >= 30) {
|
||||
startActivity(Intent(this, ActExitReasons::class.java))
|
||||
}else{
|
||||
} else {
|
||||
showToast(false, "this feature requires Android 11")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ class AppState(
|
|||
) {
|
||||
|
||||
companion object {
|
||||
|
||||
internal val log = LogCategory("AppState")
|
||||
|
||||
private const val FILE_COLUMN_LIST = "column_list"
|
||||
|
@ -86,7 +87,7 @@ class AppState(
|
|||
}
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(context, ex, "saveColumnList failed.")
|
||||
context.showToast(ex, "saveColumnList failed.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +103,7 @@ class AppState(
|
|||
} catch(ignored : FileNotFoundException) {
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(context, ex, "loadColumnList failed.")
|
||||
context.showToast(ex, "loadColumnList failed.")
|
||||
}
|
||||
|
||||
return null
|
||||
|
@ -355,11 +356,11 @@ class AppState(
|
|||
|
||||
if(willSpeechEnabled && tts == null && tts_status == TTS_STATUS_NONE) {
|
||||
tts_status = TTS_STATUS_INITIALIZING
|
||||
showToast(context, false, R.string.text_to_speech_initializing)
|
||||
context.showToast(false, R.string.text_to_speech_initializing)
|
||||
log.d("initializing TextToSpeech…")
|
||||
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
|
||||
|
||||
var tmp_tts : TextToSpeech? = null
|
||||
|
||||
val tts_init_listener : TextToSpeech.OnInitListener =
|
||||
|
@ -367,8 +368,7 @@ class AppState(
|
|||
|
||||
val tts = tmp_tts
|
||||
if(tts == null || TextToSpeech.SUCCESS != status) {
|
||||
showToast(
|
||||
context,
|
||||
context.showToast(
|
||||
false,
|
||||
R.string.text_to_speech_initialize_failed,
|
||||
status
|
||||
|
@ -379,7 +379,7 @@ class AppState(
|
|||
|
||||
runOnMainLooper {
|
||||
if(! willSpeechEnabled) {
|
||||
showToast(context, false, R.string.text_to_speech_shutdown)
|
||||
context.showToast(false, R.string.text_to_speech_shutdown)
|
||||
log.d("shutdown TextToSpeech…")
|
||||
tts.shutdown()
|
||||
} else {
|
||||
|
@ -450,7 +450,7 @@ class AppState(
|
|||
}
|
||||
|
||||
if(! willSpeechEnabled && tts != null) {
|
||||
showToast(context, false, R.string.text_to_speech_shutdown)
|
||||
context.showToast(false, R.string.text_to_speech_shutdown)
|
||||
log.d("shutdown TextToSpeech…")
|
||||
tts?.shutdown()
|
||||
tts = null
|
||||
|
|
|
@ -352,22 +352,22 @@ class Column(
|
|||
fun reloadDefaultColor(activity : AppCompatActivity, pref : SharedPreferences) {
|
||||
|
||||
defaultColorHeaderBg = Pref.ipCcdHeaderBg(pref).notZero()
|
||||
?: getAttributeColor(activity, R.attr.color_column_header)
|
||||
?: activity.getAttributeColor(R.attr.color_column_header)
|
||||
|
||||
defaultColorHeaderName = Pref.ipCcdHeaderFg(pref).notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorColumnHeaderName)
|
||||
?: activity.getAttributeColor(R.attr.colorColumnHeaderName)
|
||||
|
||||
defaultColorHeaderPageNumber = Pref.ipCcdHeaderFg(pref).notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorColumnHeaderPageNumber)
|
||||
?: activity.getAttributeColor(R.attr.colorColumnHeaderPageNumber)
|
||||
|
||||
defaultColorContentBg = Pref.ipCcdContentBg(pref)
|
||||
// may zero
|
||||
|
||||
defaultColorContentAcct = Pref.ipCcdContentAcct(pref).notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorTimeSmall)
|
||||
?: activity.getAttributeColor(R.attr.colorTimeSmall)
|
||||
|
||||
defaultColorContentText = Pref.ipCcdContentText(pref).notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorContentText)
|
||||
?: activity.getAttributeColor(R.attr.colorContentText)
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -2131,14 +2131,14 @@ class Column(
|
|||
|
||||
if(lastTask != null) {
|
||||
if(! bSilent) {
|
||||
showToast(context, true, R.string.column_is_busy)
|
||||
context.showToast(true, R.string.column_is_busy)
|
||||
val holder = viewHolder
|
||||
if(holder != null) holder.refreshLayout.isRefreshing = false
|
||||
}
|
||||
return
|
||||
} else if(bBottom && ! canRefreshBottom()) {
|
||||
if(! bSilent) {
|
||||
showToast(context, true, R.string.end_of_list)
|
||||
context.showToast(true, R.string.end_of_list)
|
||||
val holder = viewHolder
|
||||
if(holder != null) holder.refreshLayout.isRefreshing = false
|
||||
}
|
||||
|
@ -2175,12 +2175,12 @@ class Column(
|
|||
internal fun startGap(gap : TimelineItem?, isHead : Boolean) {
|
||||
|
||||
if(gap == null) {
|
||||
showToast(context, true, "gap is null")
|
||||
context.showToast(true, "gap is null")
|
||||
return
|
||||
}
|
||||
|
||||
if(lastTask != null) {
|
||||
showToast(context, true, R.string.column_is_busy)
|
||||
context.showToast(true, R.string.column_is_busy)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -415,7 +415,7 @@ class ColumnTask_Gap(
|
|||
}
|
||||
|
||||
if(max_id == null) {
|
||||
showToast(context, false, "gap-getConversationSummaryList: missing max_id")
|
||||
context.showToast(false, "$logCaption: missing max_id")
|
||||
log.d("$logCaption: missing max_id")
|
||||
break
|
||||
}
|
||||
|
@ -563,7 +563,7 @@ class ColumnTask_Gap(
|
|||
defaultAccountListParser
|
||||
) : TootApiResult? {
|
||||
|
||||
if( column.pagingType != ColumnPagingType.Default ) {
|
||||
if(column.pagingType != ColumnPagingType.Default) {
|
||||
return TootApiResult("can't support gap")
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ class ColumnViewHolder(
|
|||
CompoundButton.OnCheckedChangeListener, View.OnLongClickListener {
|
||||
|
||||
companion object {
|
||||
|
||||
private val log = LogCategory("ColumnViewHolder")
|
||||
|
||||
val fieldRecycler : Field by lazy {
|
||||
|
@ -540,8 +541,8 @@ class ColumnViewHolder(
|
|||
// }
|
||||
|
||||
log.d(
|
||||
"restoreScrollPosition [$page_idx] %s , column has no saved scroll position."
|
||||
, column.getColumnName(true)
|
||||
"restoreScrollPosition [$page_idx] %s , column has no saved scroll position.",
|
||||
column.getColumnName(true)
|
||||
)
|
||||
return
|
||||
}
|
||||
|
@ -550,18 +551,18 @@ class ColumnViewHolder(
|
|||
|
||||
if(listView.visibility != View.VISIBLE) {
|
||||
log.d(
|
||||
"restoreScrollPosition [$page_idx] %s , listView is not visible. saved position %s,%s is dropped."
|
||||
, column.getColumnName(true)
|
||||
, sp.adapterIndex
|
||||
, sp.offset
|
||||
"restoreScrollPosition [$page_idx] %s , listView is not visible. saved position %s,%s is dropped.",
|
||||
column.getColumnName(true),
|
||||
sp.adapterIndex,
|
||||
sp.offset
|
||||
)
|
||||
} else {
|
||||
log.d(
|
||||
"restoreScrollPosition [%d] %s , listView is visible. resume %s,%s"
|
||||
, page_idx
|
||||
, column.getColumnName(true)
|
||||
, sp.adapterIndex
|
||||
, sp.offset
|
||||
"restoreScrollPosition [%d] %s , listView is visible. resume %s,%s",
|
||||
page_idx,
|
||||
column.getColumnName(true),
|
||||
sp.adapterIndex,
|
||||
sp.offset
|
||||
)
|
||||
sp.restore(this@ColumnViewHolder)
|
||||
}
|
||||
|
@ -717,21 +718,21 @@ class ColumnViewHolder(
|
|||
fun dip(dp : Int) : Int = (activity.density * dp + 0.5f).toInt()
|
||||
val context = activity
|
||||
|
||||
val announcementsBgColor = Pref.ipAnnouncementsBgColor(activity.pref).notZero()
|
||||
?: getAttributeColor(context, R.attr.colorSearchFormBackground)
|
||||
val announcementsBgColor = Pref.ipAnnouncementsBgColor(App1.pref).notZero()
|
||||
?: context.getAttributeColor(R.attr.colorSearchFormBackground)
|
||||
|
||||
btnAnnouncementsCutout.apply {
|
||||
color = announcementsBgColor
|
||||
}
|
||||
|
||||
llAnnouncementsBox.apply {
|
||||
background = createRoundDrawable( dip(6).toFloat(), announcementsBgColor )
|
||||
background = createRoundDrawable(dip(6).toFloat(), announcementsBgColor)
|
||||
val pad_tb = dip(2)
|
||||
setPadding(0, pad_tb, 0, pad_tb)
|
||||
}
|
||||
|
||||
val searchBgColor = Pref.ipSearchBgColor(activity.pref).notZero()
|
||||
?: getAttributeColor(context, R.attr.colorSearchFormBackground)
|
||||
val searchBgColor = Pref.ipSearchBgColor(App1.pref).notZero()
|
||||
?: context.getAttributeColor(R.attr.colorSearchFormBackground)
|
||||
|
||||
llSearch.apply {
|
||||
backgroundColor = searchBgColor
|
||||
|
@ -740,7 +741,7 @@ class ColumnViewHolder(
|
|||
topPadding = dip(3)
|
||||
bottomPadding = dip(3)
|
||||
}
|
||||
|
||||
|
||||
llListList.apply {
|
||||
backgroundColor = searchBgColor
|
||||
startPadding = dip(12)
|
||||
|
@ -1145,7 +1146,7 @@ class ColumnViewHolder(
|
|||
btnListAdd -> {
|
||||
val tv = etListName.text.toString().trim { it <= ' ' }
|
||||
if(tv.isEmpty()) {
|
||||
showToast(activity, true, R.string.list_name_empty)
|
||||
activity.showToast(true, R.string.list_name_empty)
|
||||
return
|
||||
}
|
||||
Action_List.create(activity, column.access_info, tv, null)
|
||||
|
@ -1161,7 +1162,7 @@ class ColumnViewHolder(
|
|||
btnQuickFilterFavourite -> clickQuickFilter(Column.QUICK_FILTER_FAVOURITE)
|
||||
btnQuickFilterBoost -> clickQuickFilter(Column.QUICK_FILTER_BOOST)
|
||||
btnQuickFilterFollow -> clickQuickFilter(Column.QUICK_FILTER_FOLLOW)
|
||||
btnQuickFilterPost-> clickQuickFilter(Column.QUICK_FILTER_POST)
|
||||
btnQuickFilterPost -> clickQuickFilter(Column.QUICK_FILTER_POST)
|
||||
btnQuickFilterReaction -> clickQuickFilter(Column.QUICK_FILTER_REACTION)
|
||||
btnQuickFilterVote -> clickQuickFilter(Column.QUICK_FILTER_VOTE)
|
||||
|
||||
|
@ -1232,7 +1233,7 @@ class ColumnViewHolder(
|
|||
tvColumnContext.text = ac.nickname
|
||||
tvColumnContext.setTextColor(
|
||||
ac.color_fg.notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorTimeSmall)
|
||||
?: activity.getAttributeColor(R.attr.colorTimeSmall)
|
||||
)
|
||||
|
||||
tvColumnContext.setBackgroundColor(ac.color_bg)
|
||||
|
@ -1393,11 +1394,11 @@ class ColumnViewHolder(
|
|||
val scroll_save = ScrollPosition()
|
||||
column.scroll_save = scroll_save
|
||||
log.d(
|
||||
"saveScrollPosition [%d] %s , listView is not visible, save %s,%s"
|
||||
, page_idx
|
||||
, column.getColumnName(true)
|
||||
, scroll_save.adapterIndex
|
||||
, scroll_save.offset
|
||||
"saveScrollPosition [%d] %s , listView is not visible, save %s,%s",
|
||||
page_idx,
|
||||
column.getColumnName(true),
|
||||
scroll_save.adapterIndex,
|
||||
scroll_save.offset
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
@ -1406,11 +1407,11 @@ class ColumnViewHolder(
|
|||
val scroll_save = ScrollPosition(this)
|
||||
column.scroll_save = scroll_save
|
||||
log.d(
|
||||
"saveScrollPosition [%d] %s , listView is visible, save %s,%s"
|
||||
, page_idx
|
||||
, column.getColumnName(true)
|
||||
, scroll_save.adapterIndex
|
||||
, scroll_save.offset
|
||||
"saveScrollPosition [%d] %s , listView is visible, save %s,%s",
|
||||
page_idx,
|
||||
column.getColumnName(true),
|
||||
scroll_save.adapterIndex,
|
||||
scroll_save.offset
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
@ -1586,10 +1587,10 @@ class ColumnViewHolder(
|
|||
if(insideColumnSetting) {
|
||||
svQuickFilter.setBackgroundColor(0)
|
||||
|
||||
val colorFg = getAttributeColor(activity, R.attr.colorContentText)
|
||||
val colorFg = activity.getAttributeColor(R.attr.colorContentText)
|
||||
val colorBgSelected = colorFg.applyAlphaMultiplier(0.25f)
|
||||
val colorFgList = ColorStateList.valueOf(colorFg)
|
||||
val colorBg = getAttributeColor(activity, R.attr.colorColumnSettingBackground)
|
||||
val colorBg = activity.getAttributeColor(R.attr.colorColumnSettingBackground)
|
||||
showQuickFilterButton = { btn, iconId, selected ->
|
||||
btn.backgroundDrawable =
|
||||
getAdaptiveRippleDrawableRound(
|
||||
|
@ -1721,7 +1722,7 @@ class ColumnViewHolder(
|
|||
gravity = Gravity.END
|
||||
startPadding = dip(4)
|
||||
endPadding = dip(4)
|
||||
textColor = getAttributeColor(context, R.attr.colorColumnHeaderAcct)
|
||||
textColor = context.getAttributeColor(R.attr.colorColumnHeaderAcct)
|
||||
textSize = 12f
|
||||
|
||||
}.lparams(0, wrapContent) {
|
||||
|
@ -1730,7 +1731,7 @@ class ColumnViewHolder(
|
|||
|
||||
tvColumnStatus = textView {
|
||||
gravity = Gravity.END
|
||||
textColor = getAttributeColor(context, R.attr.colorColumnHeaderPageNumber)
|
||||
textColor = context.getAttributeColor(R.attr.colorColumnHeaderPageNumber)
|
||||
textSize = 12f
|
||||
|
||||
}.lparams(wrapContent, wrapContent) {
|
||||
|
@ -1739,7 +1740,7 @@ class ColumnViewHolder(
|
|||
|
||||
tvColumnIndex = textView {
|
||||
gravity = Gravity.END
|
||||
textColor = getAttributeColor(context, R.attr.colorColumnHeaderPageNumber)
|
||||
textColor = context.getAttributeColor(R.attr.colorColumnHeaderPageNumber)
|
||||
textSize = 12f
|
||||
|
||||
}.lparams(wrapContent, wrapContent) {
|
||||
|
@ -1843,7 +1844,7 @@ class ColumnViewHolder(
|
|||
val paint = Paint().apply {
|
||||
isAntiAlias = true
|
||||
color =
|
||||
getAttributeColor(context, R.attr.colorColumnSettingBackground)
|
||||
context.getAttributeColor(R.attr.colorColumnSettingBackground)
|
||||
}
|
||||
val path = Path()
|
||||
addOutsideDrawer(this) { canvas, parent, view, left, top ->
|
||||
|
@ -1909,7 +1910,7 @@ class ColumnViewHolder(
|
|||
maxHeight = dip(240)
|
||||
|
||||
backgroundColor =
|
||||
getAttributeColor(context, R.attr.colorColumnSettingBackground)
|
||||
context.getAttributeColor(R.attr.colorColumnSettingBackground)
|
||||
|
||||
llColumnSettingInside = verticalLayout {
|
||||
lparams(matchParent, wrapContent)
|
||||
|
@ -1924,7 +1925,7 @@ class ColumnViewHolder(
|
|||
|
||||
label = textView {
|
||||
textColor =
|
||||
getAttributeColor(context, R.attr.colorColumnHeaderPageNumber)
|
||||
context.getAttributeColor(R.attr.colorColumnHeaderPageNumber)
|
||||
text = context.getString(R.string.hashtag_extra_any)
|
||||
}.lparams(matchParent, wrapContent)
|
||||
|
||||
|
@ -1939,7 +1940,7 @@ class ColumnViewHolder(
|
|||
|
||||
label = textView {
|
||||
textColor =
|
||||
getAttributeColor(context, R.attr.colorColumnHeaderPageNumber)
|
||||
context.getAttributeColor(R.attr.colorColumnHeaderPageNumber)
|
||||
text = context.getString(R.string.hashtag_extra_all)
|
||||
}.lparams(matchParent, wrapContent)
|
||||
|
||||
|
@ -1954,7 +1955,7 @@ class ColumnViewHolder(
|
|||
|
||||
label = textView {
|
||||
textColor =
|
||||
getAttributeColor(context, R.attr.colorColumnHeaderPageNumber)
|
||||
context.getAttributeColor(R.attr.colorColumnHeaderPageNumber)
|
||||
text = context.getString(R.string.hashtag_extra_none)
|
||||
}.lparams(matchParent, wrapContent)
|
||||
|
||||
|
@ -2049,12 +2050,12 @@ class ColumnViewHolder(
|
|||
|
||||
label = textView {
|
||||
textColor =
|
||||
getAttributeColor(context, R.attr.colorColumnHeaderPageNumber)
|
||||
context.getAttributeColor(R.attr.colorColumnHeaderPageNumber)
|
||||
text = context.getString(R.string.regex_filter)
|
||||
}.lparams(wrapContent, wrapContent)
|
||||
|
||||
tvRegexFilterError = textView {
|
||||
textColor = getAttributeColor(context, R.attr.colorRegexFilterError)
|
||||
textColor = context.getAttributeColor(R.attr.colorRegexFilterError)
|
||||
}.lparams(0, wrapContent) {
|
||||
weight = 1f
|
||||
startMargin = dip(4)
|
||||
|
@ -2220,10 +2221,7 @@ class ColumnViewHolder(
|
|||
contentDescription = context.getString(R.string.clear)
|
||||
imageResource = R.drawable.ic_close
|
||||
imageTintList = ColorStateList.valueOf(
|
||||
getAttributeColor(
|
||||
context,
|
||||
R.attr.colorVectorDrawable
|
||||
)
|
||||
context.getAttributeColor(R.attr.colorVectorDrawable)
|
||||
)
|
||||
}.lparams(dip(40), dip(40)) {
|
||||
startMargin = dip(4)
|
||||
|
@ -2234,10 +2232,7 @@ class ColumnViewHolder(
|
|||
contentDescription = context.getString(R.string.search)
|
||||
imageResource = R.drawable.ic_search
|
||||
imageTintList = ColorStateList.valueOf(
|
||||
getAttributeColor(
|
||||
context,
|
||||
R.attr.colorVectorDrawable
|
||||
)
|
||||
context.getAttributeColor(R.attr.colorVectorDrawable)
|
||||
)
|
||||
}.lparams(dip(40), dip(40)) {
|
||||
startMargin = dip(4)
|
||||
|
@ -2269,8 +2264,7 @@ class ColumnViewHolder(
|
|||
contentDescription = context.getString(R.string.add)
|
||||
imageResource = R.drawable.ic_add
|
||||
imageTintList = ColorStateList.valueOf(
|
||||
getAttributeColor(
|
||||
context,
|
||||
context.getAttributeColor(
|
||||
R.attr.colorVectorDrawable
|
||||
)
|
||||
)
|
||||
|
@ -2688,8 +2682,8 @@ class ColumnViewHolder(
|
|||
btn.background = if(reaction.me == true) {
|
||||
getAdaptiveRippleDrawableRound(
|
||||
actMain,
|
||||
getAttributeColor(actMain, R.attr.colorButtonBgCw),
|
||||
getAttributeColor(actMain, R.attr.colorRippleEffect)
|
||||
actMain.getAttributeColor(R.attr.colorButtonBgCw),
|
||||
actMain.getAttributeColor(R.attr.colorRippleEffect)
|
||||
)
|
||||
} else {
|
||||
ContextCompat.getDrawable(actMain, R.drawable.btn_bg_transparent_round6dp)
|
||||
|
@ -2775,7 +2769,7 @@ class ColumnViewHolder(
|
|||
override fun handleResult(result : TootApiResult?) {
|
||||
result ?: return
|
||||
if(result.jsonObject == null) {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast(true, result.error)
|
||||
} else {
|
||||
sample.count = 0
|
||||
val list = item.reactions
|
||||
|
@ -2811,7 +2805,7 @@ class ColumnViewHolder(
|
|||
override fun handleResult(result : TootApiResult?) {
|
||||
result ?: return
|
||||
if(result.jsonObject == null) {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast(true, result.error)
|
||||
} else {
|
||||
val it = item.reactions?.iterator() ?: return
|
||||
while(it.hasNext()) {
|
||||
|
|
|
@ -19,9 +19,7 @@ import jp.juggler.subwaytooter.span.MyClickableSpan
|
|||
import jp.juggler.subwaytooter.table.FavMute
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.table.UserRelation
|
||||
import jp.juggler.subwaytooter.util.CustomShare
|
||||
import jp.juggler.subwaytooter.util.CustomShareTarget
|
||||
import jp.juggler.subwaytooter.util.matchHost
|
||||
import jp.juggler.subwaytooter.util.*
|
||||
import jp.juggler.util.*
|
||||
import org.jetbrains.anko.allCaps
|
||||
import org.jetbrains.anko.backgroundDrawable
|
||||
|
@ -349,14 +347,14 @@ internal class DlgContextMenu(
|
|||
|
||||
val colorButtonAccent =
|
||||
Pref.ipButtonFollowingColor(activity.pref).notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorImageButtonAccent)
|
||||
?: activity.getAttributeColor(R.attr.colorImageButtonAccent)
|
||||
|
||||
val colorButtonError =
|
||||
Pref.ipButtonFollowRequestColor(activity.pref).notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorRegexFilterError)
|
||||
?: activity.getAttributeColor(R.attr.colorRegexFilterError)
|
||||
|
||||
val colorButtonNormal =
|
||||
getAttributeColor(activity, R.attr.colorImageButton)
|
||||
activity.getAttributeColor(R.attr.colorImageButton)
|
||||
|
||||
fun showRelation(relation : UserRelation) {
|
||||
|
||||
|
@ -407,7 +405,7 @@ internal class DlgContextMenu(
|
|||
ivFollowedBy.vg(false)
|
||||
btnFollow.setImageResource(R.drawable.ic_follow_plus)
|
||||
btnFollow.imageTintList =
|
||||
ColorStateList.valueOf(getAttributeColor(activity, R.attr.colorImageButton))
|
||||
ColorStateList.valueOf(activity.getAttributeColor(R.attr.colorImageButton))
|
||||
|
||||
btnNotificationFrom.visibility = View.GONE
|
||||
} else {
|
||||
|
@ -585,7 +583,7 @@ internal class DlgContextMenu(
|
|||
R.drawable.ic_arrow_drop_down
|
||||
}
|
||||
|
||||
val iconColor = getAttributeColor(activity, R.attr.colorTimeSmall)
|
||||
val iconColor = activity.getAttributeColor(R.attr.colorTimeSmall)
|
||||
val drawable = createColoredDrawable(activity, iconId, iconColor, 1f)
|
||||
btn.setCompoundDrawablesRelativeWithIntrinsicBounds(drawable, null, null, null)
|
||||
}
|
||||
|
@ -713,7 +711,7 @@ internal class DlgContextMenu(
|
|||
Action_User.mention(activity, access_info, who)
|
||||
|
||||
R.id.btnAccountWebPage -> who.url?.let { url ->
|
||||
App1.openCustomTabOrBrowser(activity, url)
|
||||
activity.openCustomTabOrBrowser(url)
|
||||
}
|
||||
|
||||
R.id.btnFollowRequestOK ->
|
||||
|
@ -752,13 +750,13 @@ internal class DlgContextMenu(
|
|||
R.id.btnDomainBlock ->
|
||||
if(access_info.isPseudo) {
|
||||
// 疑似アカウントではドメインブロックできない
|
||||
showToast(activity, false, R.string.domain_block_from_pseudo)
|
||||
activity.showToast(false, R.string.domain_block_from_pseudo)
|
||||
return
|
||||
} else {
|
||||
val whoApDomain = who.apDomain
|
||||
// 自分のドメインではブロックできない
|
||||
if(access_info.matchHost(whoApDomain)) {
|
||||
showToast(activity, false, R.string.domain_block_from_local)
|
||||
activity.showToast(false, R.string.domain_block_from_local)
|
||||
return
|
||||
}
|
||||
AlertDialog.Builder(activity)
|
||||
|
@ -794,7 +792,7 @@ internal class DlgContextMenu(
|
|||
|
||||
R.id.btnAvatarImage -> {
|
||||
val url = if(! who.avatar.isNullOrEmpty()) who.avatar else who.avatar_static
|
||||
if(url != null && url.isNotEmpty()) App1.openCustomTab(activity, url)
|
||||
activity.openCustomTab(url)
|
||||
// XXX: 設定によっては内蔵メディアビューアで開けないか?
|
||||
}
|
||||
|
||||
|
@ -821,7 +819,7 @@ internal class DlgContextMenu(
|
|||
R.id.btnHideFavourite -> {
|
||||
val acct = access_info.getFullAcct(who)
|
||||
FavMute.save(acct)
|
||||
showToast(activity, false, R.string.changed)
|
||||
activity.showToast(false, R.string.changed)
|
||||
for(column in activity.app_state.column_list) {
|
||||
column.onHideFavouriteNotification(acct)
|
||||
}
|
||||
|
@ -829,7 +827,7 @@ internal class DlgContextMenu(
|
|||
|
||||
R.id.btnShowFavourite -> {
|
||||
FavMute.delete(access_info.getFullAcct(who))
|
||||
showToast(activity, false, R.string.changed)
|
||||
activity.showToast(false, R.string.changed)
|
||||
}
|
||||
|
||||
R.id.btnListMemberAddRemove ->
|
||||
|
@ -884,14 +882,12 @@ internal class DlgContextMenu(
|
|||
R.id.btnCopyAccountId -> who.id.toString().copyToClipboard(activity)
|
||||
|
||||
R.id.btnOpenAccountInAdminWebUi ->
|
||||
App1.openBrowser(
|
||||
activity,
|
||||
activity.openBrowser(
|
||||
"https://${access_info.apiHost.ascii}/admin/accounts/${who.id}"
|
||||
)
|
||||
|
||||
R.id.btnOpenInstanceInAdminWebUi ->
|
||||
App1.openBrowser(
|
||||
activity,
|
||||
activity.openBrowser(
|
||||
"https://${access_info.apiHost.ascii}/admin/instances/${who.apDomain.ascii}"
|
||||
)
|
||||
|
||||
|
@ -929,8 +925,8 @@ internal class DlgContextMenu(
|
|||
status,
|
||||
access_info.getFullAcct(status.account),
|
||||
NOT_CROSS_ACCOUNT,
|
||||
activity.boost_complete_callback,
|
||||
visibility = list[which]
|
||||
visibility = list[which],
|
||||
callback =activity.boost_complete_callback,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -940,7 +936,7 @@ internal class DlgContextMenu(
|
|||
|
||||
R.id.btnNotificationFrom -> {
|
||||
if(access_info.isMisskey) {
|
||||
showToast(activity, false, R.string.misskey_account_not_supported)
|
||||
activity.showToast(false, R.string.misskey_account_not_supported)
|
||||
} else {
|
||||
access_info.getFullAcct(who).validFull()?.let {
|
||||
activity.addColumn(
|
||||
|
@ -963,9 +959,8 @@ internal class DlgContextMenu(
|
|||
|
||||
when(v.id) {
|
||||
|
||||
R.id.btnStatusWebPage -> status?.url?.let { url ->
|
||||
App1.openCustomTabOrBrowser(activity, url)
|
||||
}
|
||||
R.id.btnStatusWebPage ->
|
||||
activity.openCustomTabOrBrowser(status?.url)
|
||||
|
||||
R.id.btnText -> if(status != null) {
|
||||
ActText.open(activity, ActMain.REQUEST_CODE_TEXT, access_info, status)
|
||||
|
|
|
@ -12,6 +12,7 @@ import jp.juggler.util.showToast
|
|||
class DownloadReceiver : BroadcastReceiver() {
|
||||
|
||||
companion object {
|
||||
|
||||
private val log = LogCategory("DownloadReceiver")
|
||||
}
|
||||
|
||||
|
@ -33,8 +34,7 @@ class DownloadReceiver : BroadcastReceiver() {
|
|||
}
|
||||
val title = cursor.getStringOrNull(DownloadManager.COLUMN_TITLE)
|
||||
val status = cursor.getIntOrNull(DownloadManager.COLUMN_STATUS)
|
||||
showToast(
|
||||
context,
|
||||
context.showToast(
|
||||
false,
|
||||
if(status == DownloadManager.STATUS_SUCCESSFUL) {
|
||||
context.getString(R.string.download_complete, title)
|
||||
|
|
|
@ -330,7 +330,7 @@ internal class ItemViewHolder(
|
|||
|
||||
val textShowMedia = SpannableString(activity.getString(R.string.tap_to_show))
|
||||
.apply {
|
||||
val colorBg = getAttributeColor(activity, R.attr.colorShowMediaBackground)
|
||||
val colorBg = activity.getAttributeColor(R.attr.colorShowMediaBackground)
|
||||
.applyAlphaMultiplier(0.5f)
|
||||
setSpan(
|
||||
BackgroundColorSpan(colorBg),
|
||||
|
@ -1259,10 +1259,7 @@ internal class ItemViewHolder(
|
|||
|
||||
val conversationMainBgColor =
|
||||
Pref.ipConversationMainTootBgColor(activity.pref).notZero()
|
||||
?: (getAttributeColor(
|
||||
activity,
|
||||
R.attr.colorImageButtonAccent
|
||||
) and 0xffffff) or 0x20000000
|
||||
?: (activity.getAttributeColor(R.attr.colorImageButtonAccent) and 0xffffff) or 0x20000000
|
||||
|
||||
this.viewRoot.setBackgroundColor(conversationMainBgColor)
|
||||
|
||||
|
@ -1976,7 +1973,7 @@ internal class ItemViewHolder(
|
|||
column.startGap(item, isHead = false)
|
||||
|
||||
else ->
|
||||
showToast(activity, true, "This column can't support gap reading.")
|
||||
activity.showToast(true, "This column can't support gap reading.")
|
||||
}
|
||||
|
||||
is TootSearchGap -> column.startGap(item, isHead = true)
|
||||
|
@ -2018,7 +2015,7 @@ internal class ItemViewHolder(
|
|||
.addAction(activity.getString(R.string.delete)) {
|
||||
Action_Toot.deleteScheduledPost(activity, access_info, item) {
|
||||
column.onScheduleDeleted(item)
|
||||
showToast(activity, false, R.string.scheduled_post_deleted)
|
||||
activity.showToast(false, R.string.scheduled_post_deleted)
|
||||
}
|
||||
}
|
||||
.show(activity)
|
||||
|
@ -2279,8 +2276,8 @@ internal class ItemViewHolder(
|
|||
// メディアタイプがunknownの場合、そのほとんどはリモートから来たURLである
|
||||
// Pref.bpPriorLocalURL の状態に関わらずリモートURLがあればそれをブラウザで開く
|
||||
when(val remoteUrl = item.remote_url.notEmpty()) {
|
||||
null -> App1.openCustomTab(activity, item)
|
||||
else -> App1.openCustomTab(activity, remoteUrl)
|
||||
null -> activity.openCustomTab(item)
|
||||
else -> activity.openCustomTab(remoteUrl)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2297,7 +2294,7 @@ internal class ItemViewHolder(
|
|||
)
|
||||
|
||||
// ブラウザで開く
|
||||
else -> App1.openCustomTab(activity, item)
|
||||
else -> activity.openCustomTab(item)
|
||||
}
|
||||
}
|
||||
} catch(ex : Throwable) {
|
||||
|
@ -2674,7 +2671,7 @@ internal class ItemViewHolder(
|
|||
private fun addReaction(status : TootStatus, code : String?) {
|
||||
|
||||
if(status.myReaction?.isNotEmpty() == true) {
|
||||
showToast(activity, false, R.string.already_reactioned)
|
||||
activity.showToast(false, R.string.already_reactioned)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -2718,7 +2715,7 @@ internal class ItemViewHolder(
|
|||
|
||||
val error = result.error
|
||||
if(error != null) {
|
||||
showToast(activity, false, error)
|
||||
activity.showToast(false, error)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -2739,7 +2736,7 @@ internal class ItemViewHolder(
|
|||
val reaction = status.myReaction
|
||||
|
||||
if(reaction?.isNotEmpty() != true) {
|
||||
showToast(activity, false, R.string.not_reactioned)
|
||||
activity.showToast(false, R.string.not_reactioned)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -2773,7 +2770,7 @@ internal class ItemViewHolder(
|
|||
|
||||
val error = result.error
|
||||
if(error != null) {
|
||||
showToast(activity, false, error)
|
||||
activity.showToast(false, error)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -3050,7 +3047,7 @@ internal class ItemViewHolder(
|
|||
idx : Int
|
||||
) {
|
||||
if(enquete.ownVoted) {
|
||||
showToast(context, false, R.string.already_voted)
|
||||
context.showToast(false, R.string.already_voted)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -3064,14 +3061,14 @@ internal class ItemViewHolder(
|
|||
TootPollsType.FriendsNico -> {
|
||||
val remain = enquete.time_start + TootPolls.ENQUETE_EXPIRE - now
|
||||
if(remain <= 0L) {
|
||||
showToast(context, false, R.string.enquete_was_end)
|
||||
context.showToast(false, R.string.enquete_was_end)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
TootPollsType.Mastodon -> {
|
||||
if(enquete.expired || now >= enquete.expired_at) {
|
||||
showToast(context, false, R.string.enquete_was_end)
|
||||
context.showToast(false, R.string.enquete_was_end)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -3108,7 +3105,7 @@ internal class ItemViewHolder(
|
|||
if(data != null) {
|
||||
when(enquete.pollType) {
|
||||
TootPollsType.Misskey -> if(enquete.increaseVote(activity, idx, true)) {
|
||||
showToast(context, false, R.string.enquete_voted)
|
||||
context.showToast(false, R.string.enquete_voted)
|
||||
|
||||
// 1個だけ開閉するのではなく、例えば通知TLにある複数の要素をまとめて開閉するなどある
|
||||
list_adapter.notifyChange(reason = "onClickEnqueteChoice", reset = true)
|
||||
|
@ -3130,7 +3127,7 @@ internal class ItemViewHolder(
|
|||
reset = true
|
||||
)
|
||||
} else if(result.error != null) {
|
||||
showToast(context, true, "response parse error")
|
||||
context.showToast(true, "response parse error")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3138,14 +3135,14 @@ internal class ItemViewHolder(
|
|||
val message = data.string("message") ?: "?"
|
||||
val valid = data.optBoolean("valid")
|
||||
if(valid) {
|
||||
showToast(context, false, R.string.enquete_voted)
|
||||
context.showToast(false, R.string.enquete_voted)
|
||||
} else {
|
||||
showToast(context, true, R.string.enquete_vote_failed, message)
|
||||
context.showToast(true, R.string.enquete_vote_failed, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
showToast(context, true, result.error)
|
||||
context.showToast(true, result.error)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3160,12 +3157,12 @@ internal class ItemViewHolder(
|
|||
) {
|
||||
val now = System.currentTimeMillis()
|
||||
if(now >= enquete.expired_at) {
|
||||
showToast(context, false, R.string.enquete_was_end)
|
||||
context.showToast(false, R.string.enquete_was_end)
|
||||
return
|
||||
}
|
||||
|
||||
if(enquete.items?.find { it.checked } == null) {
|
||||
showToast(context, false, R.string.polls_choice_not_selected)
|
||||
context.showToast(false, R.string.polls_choice_not_selected)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -3207,7 +3204,7 @@ internal class ItemViewHolder(
|
|||
// 1個だけ開閉するのではなく、例えば通知TLにある複数の要素をまとめて開閉するなどある
|
||||
list_adapter.notifyChange(reason = "onClickEnqueteChoice", reset = true)
|
||||
} else if(result.error != null) {
|
||||
showToast(context, true, result.error)
|
||||
context.showToast(true, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -3322,13 +3319,11 @@ internal class ItemViewHolder(
|
|||
tvFollowerAcct = textView {
|
||||
setPaddingStartEnd(dip(4), dip(4))
|
||||
textSize = 12f // SP
|
||||
// tools:text="aaaaaaaaaaaaaaaa"
|
||||
}.lparams(matchParent, wrapContent)
|
||||
|
||||
tvLastStatusAt = myTextView {
|
||||
setPaddingStartEnd(dip(4), dip(4))
|
||||
textSize = 12f // SP
|
||||
// tools:text="aaaaaaaaaaaaaaaa"
|
||||
}.lparams(matchParent, wrapContent)
|
||||
}
|
||||
|
||||
|
@ -3580,14 +3575,14 @@ internal class ItemViewHolder(
|
|||
|
||||
btnShowMedia = blurhashView {
|
||||
|
||||
errorColor = getAttributeColor(
|
||||
context,
|
||||
errorColor = context.getAttributeColor(
|
||||
|
||||
R.attr.colorShowMediaBackground
|
||||
)
|
||||
gravity = Gravity.CENTER
|
||||
|
||||
textColor = getAttributeColor(
|
||||
context,
|
||||
textColor = context.getAttributeColor(
|
||||
|
||||
R.attr.colorShowMediaText
|
||||
)
|
||||
|
||||
|
@ -3678,14 +3673,12 @@ internal class ItemViewHolder(
|
|||
|
||||
btnShowMedia = blurhashView {
|
||||
|
||||
errorColor = getAttributeColor(
|
||||
context,
|
||||
errorColor = context.getAttributeColor(
|
||||
R.attr.colorShowMediaBackground
|
||||
)
|
||||
gravity = Gravity.CENTER
|
||||
|
||||
textColor = getAttributeColor(
|
||||
context,
|
||||
textColor = context.getAttributeColor(
|
||||
R.attr.colorShowMediaText
|
||||
)
|
||||
|
||||
|
@ -3745,14 +3738,12 @@ internal class ItemViewHolder(
|
|||
|
||||
btnCardImageShow = blurhashView {
|
||||
|
||||
errorColor = getAttributeColor(
|
||||
context,
|
||||
errorColor = context.getAttributeColor(
|
||||
R.attr.colorShowMediaBackground
|
||||
)
|
||||
gravity = Gravity.CENTER
|
||||
|
||||
textColor = getAttributeColor(
|
||||
context,
|
||||
textColor = context.getAttributeColor(
|
||||
R.attr.colorShowMediaText
|
||||
)
|
||||
|
||||
|
|
|
@ -230,7 +230,7 @@ class PollingWorker private constructor(contextArg : Context) {
|
|||
|
||||
val intervalMillis = max(
|
||||
minute * 5L,
|
||||
minute * Pref.spPullNotificationCheckInterval.toInt(Pref.pref(context))
|
||||
minute * Pref.spPullNotificationCheckInterval.toInt(context.pref())
|
||||
)
|
||||
|
||||
val flexMillis = max(
|
||||
|
|
|
@ -6,6 +6,9 @@ import android.graphics.Color
|
|||
import androidx.preference.PreferenceManager
|
||||
import jp.juggler.util.optInt
|
||||
|
||||
fun Context.pref() : SharedPreferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(this)
|
||||
|
||||
@Suppress("EqualsOrHashCode")
|
||||
abstract class BasePref<T>(val key : String, val defVal : T) {
|
||||
|
||||
|
@ -17,28 +20,25 @@ abstract class BasePref<T>(val key : String, val defVal : T) {
|
|||
Pref.map[key] = this
|
||||
}
|
||||
|
||||
override fun equals(other : Any?) : Boolean {
|
||||
return this === other
|
||||
}
|
||||
|
||||
fun remove(e : SharedPreferences.Editor) {
|
||||
e.remove(key)
|
||||
}
|
||||
|
||||
abstract fun put(editor : SharedPreferences.Editor, v : T)
|
||||
abstract fun invoke(pref : SharedPreferences) : T
|
||||
|
||||
override fun equals(other : Any?) =
|
||||
this === other
|
||||
|
||||
operator fun invoke(context : Context) : T {
|
||||
return invoke(Pref.pref(context))
|
||||
}
|
||||
operator fun invoke(context : Context) : T =
|
||||
invoke(context.pref())
|
||||
|
||||
fun removeDefault(pref : SharedPreferences, e : SharedPreferences.Editor) : Boolean {
|
||||
fun remove(e : SharedPreferences.Editor) : SharedPreferences.Editor =
|
||||
e.remove(key)
|
||||
|
||||
fun removeDefault(pref : SharedPreferences, e : SharedPreferences.Editor) =
|
||||
if(pref.contains(key) && this.invoke(pref) == defVal) {
|
||||
e.remove(key)
|
||||
return true
|
||||
true
|
||||
}else {
|
||||
false
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
fun SharedPreferences.Editor.remove(item : BasePref<*>) : SharedPreferences.Editor {
|
||||
|
@ -125,10 +125,6 @@ fun SharedPreferences.Editor.put(item : FloatPref, v : Float) =
|
|||
|
||||
object Pref {
|
||||
|
||||
fun pref(context : Context) : SharedPreferences {
|
||||
return PreferenceManager.getDefaultSharedPreferences(context)
|
||||
}
|
||||
|
||||
// キー名と設定項目のマップ。インポートやアプリ設定で使う
|
||||
val map = HashMap<String, BasePref<*>>()
|
||||
|
||||
|
@ -445,6 +441,7 @@ object Pref {
|
|||
// int
|
||||
|
||||
val ipBackButtonAction = IntPref("back_button_action", 0)
|
||||
|
||||
@Suppress("unused")
|
||||
const val BACK_ASK_ALWAYS = 0
|
||||
const val BACK_CLOSE_COLUMN = 1
|
||||
|
@ -454,18 +451,18 @@ object Pref {
|
|||
val ipUiTheme = IntPref("ui_theme", 0)
|
||||
val ipResizeImage = IntPref("resize_image", 4)
|
||||
|
||||
|
||||
const val RC_SIMPLE = 0
|
||||
const val RC_ACTUAL = 1
|
||||
|
||||
@Suppress("unused")
|
||||
const val RC_NONE = 2
|
||||
val ipRepliesCount = IntPref("RepliesCount", RC_SIMPLE)
|
||||
val ipBoostsCount = IntPref("BoostsCount", RC_ACTUAL)
|
||||
val ipFavouritesCount = IntPref("FavouritesCount", RC_ACTUAL)
|
||||
|
||||
|
||||
val ipRefreshAfterToot = IntPref("refresh_after_toot", 0)
|
||||
const val RAT_REFRESH_SCROLL = 0
|
||||
|
||||
@Suppress("unused")
|
||||
const val RAT_REFRESH_DONT_SCROLL = 1
|
||||
const val RAT_DONT_REFRESH = 2
|
||||
|
@ -477,6 +474,7 @@ object Pref {
|
|||
val ipVisibilityStyle = IntPref("ipVisibilityStyle", VS_BY_ACCOUNT)
|
||||
|
||||
const val ABP_TOP = 0
|
||||
|
||||
@Suppress("unused")
|
||||
const val ABP_BOTTOM = 1
|
||||
const val ABP_START = 2
|
||||
|
@ -547,8 +545,6 @@ object Pref {
|
|||
val ipVerifiedLinkBgColor = IntPref("VerifiedLinkBgColor", 0)
|
||||
val ipVerifiedLinkFgColor = IntPref("VerifiedLinkFgColor", 0)
|
||||
|
||||
|
||||
|
||||
// val ipTrendTagCountShowing = IntPref("TrendTagCountShowing", 0)
|
||||
// const val TTCS_WEEKLY = 0
|
||||
// const val TTCS_DAILY = 1
|
||||
|
@ -577,7 +573,7 @@ object Pref {
|
|||
val spBoostAlpha = StringPref("BoostAlpha", "60")
|
||||
|
||||
val spScreenBottomPadding = StringPref("ScreenBottomPadding", "8")
|
||||
|
||||
|
||||
val spPullNotificationCheckInterval = StringPref("PullNotificationCheckInterval", "15")
|
||||
val spUserAgent = StringPref("UserAgent", "")
|
||||
|
||||
|
@ -611,3 +607,4 @@ object Pref {
|
|||
internal const val default_header_font_size = 14f
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import jp.juggler.subwaytooter.action.Action_Instance
|
|||
import jp.juggler.subwaytooter.api.entity.TootStatus
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.util.VersionString
|
||||
import jp.juggler.subwaytooter.util.openBrowser
|
||||
import jp.juggler.util.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
|
@ -52,7 +53,7 @@ class SideMenuAdapter(
|
|||
private fun clickableSpan(url : String) =
|
||||
object : ClickableSpan() {
|
||||
override fun onClick(widget : View) {
|
||||
App1.openBrowser(widget.activity as ActMain, url)
|
||||
widget.activity?.openBrowser(url)
|
||||
}
|
||||
|
||||
override fun updateDrawState(ds : TextPaint) {
|
||||
|
@ -89,10 +90,9 @@ class SideMenuAdapter(
|
|||
currentVersion
|
||||
)
|
||||
)
|
||||
val newRelease = when(Pref.bpCheckBetaVersion(Pref.pref(appContext))) {
|
||||
false -> releaseInfo?.jsonObject("stable")
|
||||
else -> releaseInfo?.jsonObject("beta")
|
||||
}
|
||||
val newRelease = releaseInfo?.jsonObject(
|
||||
if(Pref.bpCheckBetaVersion(App1.pref)) "beta" else "stable"
|
||||
)
|
||||
|
||||
val newVersion =
|
||||
(newRelease?.string("name")?.notEmpty() ?: newRelease?.string("tag_name"))
|
||||
|
@ -122,10 +122,7 @@ class SideMenuAdapter(
|
|||
)
|
||||
setSpan(
|
||||
ForegroundColorSpan(
|
||||
getAttributeColor(
|
||||
appContext,
|
||||
R.attr.colorRegexFilterError
|
||||
)
|
||||
appContext.getAttributeColor(R.attr.colorRegexFilterError)
|
||||
),
|
||||
start, length,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
|
@ -362,7 +359,7 @@ class SideMenuAdapter(
|
|||
}
|
||||
)
|
||||
|
||||
private val iconColor = getAttributeColor(actMain, R.attr.colorTimeSmall)
|
||||
private val iconColor = actMain.getAttributeColor(R.attr.colorTimeSmall)
|
||||
|
||||
override fun getCount() : Int = list.size
|
||||
override fun getItem(position : Int) : Any = list[position]
|
||||
|
@ -427,7 +424,7 @@ class SideMenuAdapter(
|
|||
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||
FrameLayout.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
backgroundColor = getAttributeColor(actMain, R.attr.colorWindowBackground)
|
||||
backgroundColor = actMain.getAttributeColor(R.attr.colorWindowBackground)
|
||||
selector = StateListDrawable()
|
||||
divider = null
|
||||
dividerHeight = 0
|
||||
|
|
|
@ -19,6 +19,7 @@ import jp.juggler.subwaytooter.table.SavedAccount
|
|||
import jp.juggler.subwaytooter.table.UserRelation
|
||||
import jp.juggler.subwaytooter.util.CustomShare
|
||||
import jp.juggler.subwaytooter.util.CustomShareTarget
|
||||
import jp.juggler.subwaytooter.util.emptyCallback
|
||||
import jp.juggler.subwaytooter.util.startMargin
|
||||
import jp.juggler.subwaytooter.view.CountImageButton
|
||||
import jp.juggler.util.*
|
||||
|
@ -36,6 +37,7 @@ internal class StatusButtons(
|
|||
) : View.OnClickListener, View.OnLongClickListener {
|
||||
|
||||
companion object {
|
||||
|
||||
val log = LogCategory("StatusButtons")
|
||||
}
|
||||
|
||||
|
@ -64,7 +66,7 @@ internal class StatusButtons(
|
|||
private val color_normal = column.getContentColor()
|
||||
|
||||
private val color_accent : Int
|
||||
get() = getAttributeColor(activity, R.attr.colorImageButtonAccent)
|
||||
get() = activity.getAttributeColor(R.attr.colorImageButtonAccent)
|
||||
|
||||
init {
|
||||
this.access_info = column.access_info
|
||||
|
@ -494,13 +496,13 @@ internal class StatusButtons(
|
|||
status,
|
||||
access_info.getFullAcct(status.account),
|
||||
NOT_CROSS_ACCOUNT,
|
||||
when {
|
||||
! bSimpleList -> null
|
||||
bSet = bSet,
|
||||
callback = when {
|
||||
! bSimpleList -> emptyCallback
|
||||
// 簡略表示なら結果をトースト表示
|
||||
bSet -> activity.boost_complete_callback
|
||||
else -> activity.unboost_complete_callback
|
||||
},
|
||||
bSet = bSet
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -518,13 +520,13 @@ internal class StatusButtons(
|
|||
access_info,
|
||||
status,
|
||||
NOT_CROSS_ACCOUNT,
|
||||
when {
|
||||
! bSimpleList -> null
|
||||
bSet = bSet,
|
||||
callback = when {
|
||||
! bSimpleList -> emptyCallback
|
||||
// 簡略表示なら結果をトースト表示
|
||||
bSet -> activity.favourite_complete_callback
|
||||
else -> activity.unfavourite_complete_callback
|
||||
},
|
||||
bSet = bSet
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -542,13 +544,13 @@ internal class StatusButtons(
|
|||
access_info,
|
||||
status,
|
||||
NOT_CROSS_ACCOUNT,
|
||||
when {
|
||||
! bSimpleList -> null
|
||||
bSet = bSet,
|
||||
callback = when {
|
||||
! bSimpleList -> emptyCallback
|
||||
// 簡略表示なら結果をトースト表示
|
||||
bSet -> activity.bookmark_complete_callback
|
||||
else -> activity.unbookmark_complete_callback
|
||||
},
|
||||
bSet = bSet
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -720,6 +722,7 @@ internal class StatusButtons(
|
|||
}
|
||||
|
||||
open class _FlexboxLayout(ctx : Context) : FlexboxLayout(ctx) {
|
||||
|
||||
inline fun <T : View> T.lparams(
|
||||
width : Int = android.view.ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
height : Int = android.view.ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
|
@ -733,10 +736,10 @@ open class _FlexboxLayout(ctx : Context) : FlexboxLayout(ctx) {
|
|||
}
|
||||
|
||||
class StatusButtonsViewHolder(
|
||||
activity : ActMain
|
||||
, lpWidth : Int
|
||||
, topMarginDp : Float
|
||||
, @JustifyContent justifyContent : Int = JustifyContent.CENTER
|
||||
activity : ActMain,
|
||||
lpWidth : Int,
|
||||
topMarginDp : Float,
|
||||
@JustifyContent justifyContent : Int = JustifyContent.CENTER
|
||||
) {
|
||||
|
||||
private val buttonHeight = ActMain.boostButtonSize
|
||||
|
|
|
@ -30,7 +30,7 @@ object Styler {
|
|||
|
||||
fun defaultColorIcon(context : Context, iconId : Int) : Drawable? =
|
||||
ContextCompat.getDrawable(context, iconId)?.also {
|
||||
it.setTint(getAttributeColor(context, R.attr.colorVectorDrawable))
|
||||
it.setTint(context.getAttributeColor(R.attr.colorVectorDrawable))
|
||||
it.setTintMode(PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ object Styler {
|
|||
|
||||
val icon_id = getVisibilityIconId(isMisskeyData, visibility)
|
||||
val sv = getVisibilityString(context, isMisskeyData, visibility)
|
||||
val color = getAttributeColor(context, R.attr.colorVectorDrawable)
|
||||
val color = context.getAttributeColor(R.attr.colorVectorDrawable)
|
||||
val sb = SpannableStringBuilder()
|
||||
|
||||
// アイコン部分
|
||||
|
@ -159,12 +159,12 @@ object Styler {
|
|||
alphaMultiplier : Float
|
||||
) {
|
||||
fun colorAccent() =
|
||||
Pref.ipButtonFollowingColor(Pref.pref(context)).notZero()
|
||||
?: getAttributeColor(context, R.attr.colorImageButtonAccent)
|
||||
Pref.ipButtonFollowingColor(context.pref()).notZero()
|
||||
?: context.getAttributeColor(R.attr.colorImageButtonAccent)
|
||||
|
||||
fun colorError() =
|
||||
Pref.ipButtonFollowRequestColor(Pref.pref(context)).notZero()
|
||||
?: getAttributeColor(context, R.attr.colorRegexFilterError)
|
||||
Pref.ipButtonFollowRequestColor(context.pref()).notZero()
|
||||
?: context.getAttributeColor(R.attr.colorRegexFilterError)
|
||||
|
||||
// 被フォロー状態
|
||||
when {
|
||||
|
|
|
@ -10,6 +10,8 @@ import jp.juggler.subwaytooter.action.Action_Instance
|
|||
import jp.juggler.subwaytooter.api.entity.Host
|
||||
import jp.juggler.subwaytooter.api.entity.TootInstance
|
||||
import jp.juggler.subwaytooter.util.DecodeOptions
|
||||
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
|
||||
|
@ -20,10 +22,10 @@ import org.conscrypt.OpenSSLX509Certificate
|
|||
internal class ViewHolderHeaderInstance(
|
||||
arg_activity : ActMain,
|
||||
viewRoot : View
|
||||
) : ViewHolderHeaderBase(arg_activity, viewRoot)
|
||||
, View.OnClickListener {
|
||||
) : ViewHolderHeaderBase(arg_activity, viewRoot), View.OnClickListener {
|
||||
|
||||
companion object {
|
||||
|
||||
private val log = LogCategory("ViewHolderHeaderInstance")
|
||||
|
||||
}
|
||||
|
@ -122,12 +124,13 @@ internal class ViewHolderHeaderInstance(
|
|||
btnEmail.isEnabled = email.isNotEmpty()
|
||||
|
||||
val contact_acct =
|
||||
instance.contact_account?.let { who -> "@${who.username}@${who.apDomain.pretty}" } ?: ""
|
||||
instance.contact_account?.let { who -> "@${who.username}@${who.apDomain.pretty}" }
|
||||
?: ""
|
||||
btnContact.text = contact_acct
|
||||
btnContact.isEnabled = contact_acct.isNotEmpty()
|
||||
|
||||
tvLanguages.text = instance.languages?.joinToString(", ") ?: ""
|
||||
tvInvitesEnabled.text = when(instance.invites_enabled){
|
||||
tvInvitesEnabled.text = when(instance.invites_enabled) {
|
||||
null -> "?"
|
||||
true -> activity.getString(R.string.yes)
|
||||
false -> activity.getString(R.string.no)
|
||||
|
@ -183,15 +186,15 @@ internal class ViewHolderHeaderInstance(
|
|||
Certificate : ${cert.type}
|
||||
subject : ${cert.subjectDN}
|
||||
subjectAlternativeNames : ${
|
||||
cert.subjectAlternativeNames
|
||||
?.joinToString(", ") {
|
||||
try {
|
||||
it?.last()
|
||||
} catch(ignored : Throwable) {
|
||||
it
|
||||
cert.subjectAlternativeNames
|
||||
?.joinToString(", ") {
|
||||
try {
|
||||
it?.last()
|
||||
} catch(ignored : Throwable) {
|
||||
it
|
||||
}
|
||||
?.toString() ?: "null"
|
||||
}
|
||||
?.toString() ?: "null"
|
||||
}
|
||||
}
|
||||
issuer : ${cert.issuerX500Principal}
|
||||
end : ${cert.notAfter}
|
||||
|
@ -216,7 +219,7 @@ internal class ViewHolderHeaderInstance(
|
|||
R.id.btnEmail -> instance?.email?.let { email ->
|
||||
try {
|
||||
if(email.contains("://")) {
|
||||
App1.openCustomTab(activity, email)
|
||||
activity.openCustomTab(email)
|
||||
} else {
|
||||
val intent = Intent(Intent.ACTION_SEND)
|
||||
intent.type = "text/plain"
|
||||
|
@ -227,28 +230,31 @@ internal class ViewHolderHeaderInstance(
|
|||
|
||||
} catch(ex : Throwable) {
|
||||
log.e(ex, "startActivity failed. mail=$email")
|
||||
showToast(activity, true, R.string.missing_mail_app)
|
||||
activity.showToast(true, R.string.missing_mail_app)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
R.id.btnContact -> instance?.contact_account?.let { who ->
|
||||
Action_Account.timeline(
|
||||
activity
|
||||
, activity.nextPosition(column)
|
||||
, ColumnType.SEARCH
|
||||
, args = arrayOf("@${who.username}@${who.apDomain.ascii}", true)
|
||||
activity,
|
||||
activity.nextPosition(column),
|
||||
ColumnType.SEARCH,
|
||||
args = arrayOf("@${who.username}@${who.apDomain.ascii}", true)
|
||||
)
|
||||
}
|
||||
|
||||
R.id.btnInstance -> App1.openBrowser(activity, "https://${host.pretty}/about")
|
||||
R.id.ivThumbnail -> App1.openBrowser(activity, instance?.thumbnail)
|
||||
R.id.btnInstance ->
|
||||
activity.openBrowser("https://${host.ascii}/about")
|
||||
|
||||
R.id.ivThumbnail ->
|
||||
activity.openBrowser(instance?.thumbnail)
|
||||
|
||||
R.id.btnAbout ->
|
||||
App1.openBrowser(activity, "https://${host.pretty}/about")
|
||||
activity.openBrowser("https://${host.ascii}/about")
|
||||
|
||||
R.id.btnAboutMore ->
|
||||
App1.openBrowser(activity, "https://${host.pretty}/about/more")
|
||||
activity.openBrowser("https://${host.ascii}/about/more")
|
||||
|
||||
R.id.btnExplore -> Action_Instance.profileDirectoryFromInstanceInformation(
|
||||
activity,
|
||||
|
|
|
@ -22,6 +22,7 @@ import jp.juggler.subwaytooter.table.SavedAccount
|
|||
import jp.juggler.subwaytooter.table.UserRelation
|
||||
import jp.juggler.subwaytooter.util.DecodeOptions
|
||||
import jp.juggler.subwaytooter.util.NetworkEmojiInvalidator
|
||||
import jp.juggler.subwaytooter.util.openCustomTab
|
||||
import jp.juggler.subwaytooter.util.startMargin
|
||||
import jp.juggler.subwaytooter.view.MyLinkMovementMethod
|
||||
import jp.juggler.subwaytooter.view.MyNetworkImageView
|
||||
|
@ -139,7 +140,7 @@ internal class ViewHolderHeaderProfile(
|
|||
override fun showColor() {
|
||||
llProfile.setBackgroundColor(
|
||||
when(val c = column.column_bg_color) {
|
||||
0 -> getAttributeColor(activity, R.attr.colorProfileBackgroundMask)
|
||||
0 -> activity.getAttributeColor(R.attr.colorProfileBackgroundMask)
|
||||
else -> - 0x40000000 or (0x00ffffff and c)
|
||||
}
|
||||
)
|
||||
|
@ -194,7 +195,7 @@ internal class ViewHolderHeaderProfile(
|
|||
color = contentColor,
|
||||
alphaMultiplier = Styler.boost_alpha
|
||||
)
|
||||
|
||||
|
||||
setIconDrawableId(
|
||||
activity,
|
||||
btnPersonalNotesEdit,
|
||||
|
@ -202,7 +203,7 @@ internal class ViewHolderHeaderProfile(
|
|||
color = contentColor,
|
||||
alphaMultiplier = Styler.boost_alpha
|
||||
)
|
||||
|
||||
|
||||
val acctColor = column.getAcctColor()
|
||||
tvCreated.textColor = acctColor
|
||||
tvMovedAcct.textColor = acctColor
|
||||
|
@ -354,8 +355,10 @@ internal class ViewHolderHeaderProfile(
|
|||
tvMisskeyExtra.vg(tvMisskeyExtra.text.isNotEmpty())
|
||||
|
||||
btnStatusCount.text =
|
||||
"${activity.getString(R.string.statuses)}\n${whoDetail?.statuses_count
|
||||
?: who.statuses_count}"
|
||||
"${activity.getString(R.string.statuses)}\n${
|
||||
whoDetail?.statuses_count
|
||||
?: who.statuses_count
|
||||
}"
|
||||
|
||||
if(Pref.bpHideFollowCount(activity.pref)) {
|
||||
btnFollowing.text = activity.getString(R.string.following)
|
||||
|
@ -363,18 +366,18 @@ internal class ViewHolderHeaderProfile(
|
|||
} else {
|
||||
btnFollowing.text =
|
||||
"${activity.getString(R.string.following)}\n${
|
||||
whoDetail?.following_count ?: who.following_count
|
||||
whoDetail?.following_count ?: who.following_count
|
||||
}"
|
||||
btnFollowers.text =
|
||||
"${activity.getString(R.string.followers)}\n${
|
||||
whoDetail?.followers_count ?: who.followers_count
|
||||
whoDetail?.followers_count ?: who.followers_count
|
||||
}"
|
||||
|
||||
}
|
||||
|
||||
val relation = UserRelation.load(access_info.db_id, who.id)
|
||||
this.relation = relation
|
||||
|
||||
|
||||
Styler.setFollowIcon(
|
||||
activity,
|
||||
btnFollow,
|
||||
|
@ -386,7 +389,7 @@ internal class ViewHolderHeaderProfile(
|
|||
)
|
||||
|
||||
tvPersonalNotes.text = relation.note ?: ""
|
||||
|
||||
|
||||
showMoved(who, who.movedRef)
|
||||
|
||||
val fields = whoDetail?.fields ?: who.fields
|
||||
|
@ -451,8 +454,10 @@ internal class ViewHolderHeaderProfile(
|
|||
?: (Color.BLACK or 0x7fbc99)
|
||||
|
||||
valueText.setSpan(
|
||||
ForegroundColorSpan(linkFgColor)
|
||||
, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
ForegroundColorSpan(linkFgColor),
|
||||
start,
|
||||
end,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -537,9 +542,8 @@ internal class ViewHolderHeaderProfile(
|
|||
|
||||
when(v.id) {
|
||||
|
||||
R.id.ivBackground, R.id.tvRemoteProfileWarning -> whoRef?.get()?.url?.let { url ->
|
||||
App1.openCustomTab(activity, url)
|
||||
}
|
||||
R.id.ivBackground, R.id.tvRemoteProfileWarning ->
|
||||
activity.openCustomTab(whoRef?.get()?.url)
|
||||
|
||||
R.id.btnFollowing -> {
|
||||
column.profile_tab = ProfileTab.Following
|
||||
|
@ -584,44 +588,45 @@ internal class ViewHolderHeaderProfile(
|
|||
}
|
||||
}
|
||||
|
||||
R.id.btnPersonalNotesEdit -> whoRef?.let{ whoRef->
|
||||
R.id.btnPersonalNotesEdit -> whoRef?.let { whoRef ->
|
||||
val who = whoRef.get()
|
||||
val relation = this.relation
|
||||
val lastColumn = column
|
||||
DlgTextInput.show(
|
||||
activity,
|
||||
AcctColor.getStringWithNickname(activity,R.string.personal_notes_of,who.acct),
|
||||
AcctColor.getStringWithNickname(activity, R.string.personal_notes_of, who.acct),
|
||||
relation?.note ?: "",
|
||||
allowEmpty = true,
|
||||
callback = object: DlgTextInput.Callback{
|
||||
callback = object : DlgTextInput.Callback {
|
||||
override fun onEmptyError() {
|
||||
}
|
||||
|
||||
|
||||
override fun onOK(dialog : Dialog, text : String) {
|
||||
TootTaskRunner(activity).run(column.access_info,object:TootTask{
|
||||
TootTaskRunner(activity).run(column.access_info, object : TootTask {
|
||||
override fun background(client : TootApiClient) : TootApiResult? {
|
||||
|
||||
|
||||
if(access_info.isPseudo)
|
||||
return TootApiResult("Personal notes is not supported on pseudo account.")
|
||||
|
||||
|
||||
if(access_info.isMisskey)
|
||||
return TootApiResult("Personal notes is not supported on Misskey account.")
|
||||
|
||||
return client.request("/api/v1/accounts/${who.id}/note",
|
||||
return client.request(
|
||||
"/api/v1/accounts/${who.id}/note",
|
||||
jsonObject {
|
||||
put("comment",text)
|
||||
put("comment", text)
|
||||
}.toPostRequestBuilder()
|
||||
)
|
||||
}
|
||||
|
||||
override fun handleResult(result : TootApiResult?) {
|
||||
if(result==null) return
|
||||
if(result.error!=null)
|
||||
showToast(activity,true,result.error)
|
||||
else{
|
||||
if(result == null) return
|
||||
if(result.error != null)
|
||||
activity.showToast(true, result.error)
|
||||
else {
|
||||
relation?.note = text
|
||||
dialog.dismissSafe()
|
||||
if(lastColumn==column) bindData(column)
|
||||
if(lastColumn == column) bindData(column)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -22,7 +22,7 @@ internal fun addPseudoAccount(
|
|||
callback : (SavedAccount) -> Unit
|
||||
) {
|
||||
try {
|
||||
val acct = Acct.parse("?",host)
|
||||
val acct = Acct.parse("?", host)
|
||||
|
||||
var account = SavedAccount.loadAccountByAcct(context, acct.ascii)
|
||||
if(account != null) {
|
||||
|
@ -45,7 +45,7 @@ internal fun addPseudoAccount(
|
|||
result == null -> {
|
||||
}
|
||||
|
||||
targetInstance == null -> showToast(context, false, result.error)
|
||||
targetInstance == null -> context.showToast(false, result.error)
|
||||
else -> addPseudoAccount(context, host, targetInstance, callback)
|
||||
}
|
||||
})
|
||||
|
@ -58,7 +58,7 @@ internal fun addPseudoAccount(
|
|||
}
|
||||
|
||||
val row_id = SavedAccount.insert(
|
||||
acct =acct.ascii,
|
||||
acct = acct.ascii,
|
||||
host = host.ascii,
|
||||
domain = instanceInfo.uri,
|
||||
account = account_info,
|
||||
|
@ -85,7 +85,7 @@ internal fun addPseudoAccount(
|
|||
val log = LogCategory("addPseudoAccount")
|
||||
log.trace(ex)
|
||||
log.e(ex, "failed.")
|
||||
showToast(context, ex, "addPseudoAccount failed.")
|
||||
context.showToast(ex, "addPseudoAccount failed.")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ fun makeAccountListNonPseudo(
|
|||
for(a in SavedAccount.loadAccountList(context)) {
|
||||
if(a.isPseudo) continue
|
||||
when(pickup_host) {
|
||||
null, a.apDomain,a.apiHost -> list_same_host
|
||||
null, a.apDomain, a.apiHost -> list_same_host
|
||||
else -> list_other_host
|
||||
}.add(a)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package jp.juggler.subwaytooter.action
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import jp.juggler.subwaytooter.*
|
||||
|
@ -14,6 +13,7 @@ import jp.juggler.subwaytooter.dialog.LoginForm
|
|||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.table.UserRelation
|
||||
import jp.juggler.subwaytooter.util.LinkHelper
|
||||
import jp.juggler.subwaytooter.util.openBrowser
|
||||
import jp.juggler.util.*
|
||||
|
||||
object Action_Account {
|
||||
|
@ -57,7 +57,7 @@ object Action_Account {
|
|||
when(action) {
|
||||
LoginForm.Action.Existing -> if(data is String) {
|
||||
// ブラウザ用URLが生成された
|
||||
App1.openBrowser(activity, data.toUri())
|
||||
activity.openBrowser(data.toUri())
|
||||
dialog.dismissSafe()
|
||||
return
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ object Action_Account {
|
|||
instance,
|
||||
instanceInfo = data
|
||||
) { a ->
|
||||
showToast(activity, false, R.string.server_confirmed)
|
||||
activity.showToast(false, R.string.server_confirmed)
|
||||
val pos = App1.getAppState(activity).column_list.size
|
||||
activity.addColumn(pos, a, ColumnType.LOCAL)
|
||||
dialog.dismissSafe()
|
||||
|
@ -111,7 +111,7 @@ object Action_Account {
|
|||
}
|
||||
|
||||
override fun onEmptyError() {
|
||||
showToast(activity, true, R.string.token_not_specified)
|
||||
activity.showToast(true, R.string.token_not_specified)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -131,7 +131,7 @@ object Action_Account {
|
|||
.setNeutralButton(R.string.close, null)
|
||||
.show()
|
||||
} else {
|
||||
showToast(activity, true, "$errorText ${result.requestInfo}".trim())
|
||||
activity.showToast(true, "$errorText ${result.requestInfo}".trim())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -284,7 +284,7 @@ object Action_Account {
|
|||
bSet : Boolean
|
||||
) {
|
||||
if(access_info.isMisskey) {
|
||||
showToast(activity, false, "This feature is not provided on Misskey account.")
|
||||
activity.showToast(false, "This feature is not provided on Misskey account.")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -319,10 +319,10 @@ object Action_Account {
|
|||
result ?: return
|
||||
|
||||
if(result.error != null) {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast(true, result.error)
|
||||
} else {
|
||||
showToast(
|
||||
activity, false, when(bSet) {
|
||||
activity.showToast(
|
||||
false, when(bSet) {
|
||||
true -> R.string.endorse_succeeded
|
||||
else -> R.string.remove_endorse_succeeded
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ object Action_App {
|
|||
|
||||
MutedApp.save(application.name)
|
||||
App1.getAppState(activity).onMuteUpdated()
|
||||
showToast(activity, false, R.string.app_was_muted)
|
||||
activity.showToast(false, R.string.app_was_muted)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,32 +10,40 @@ import jp.juggler.subwaytooter.api.TootTaskRunner
|
|||
import jp.juggler.subwaytooter.api.entity.TootFilter
|
||||
import jp.juggler.subwaytooter.dialog.DlgConfirm
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.util.LogCategory
|
||||
import jp.juggler.util.showToast
|
||||
import okhttp3.Request
|
||||
|
||||
object Action_Filter {
|
||||
|
||||
private val log = LogCategory("Action_Filter")
|
||||
// private val log = LogCategory("Action_Filter")
|
||||
|
||||
fun delete( activity : ActMain, access_info : SavedAccount,filter: TootFilter ,bConfirmed :Boolean = false){
|
||||
if(!bConfirmed){
|
||||
DlgConfirm.openSimple(activity,activity.getString(R.string.filter_delete_confirm, filter.phrase)){
|
||||
delete(activity,access_info,filter,bConfirmed=true)
|
||||
fun delete(
|
||||
activity : ActMain,
|
||||
access_info : SavedAccount,
|
||||
filter : TootFilter,
|
||||
bConfirmed : Boolean = false
|
||||
) {
|
||||
if(! bConfirmed) {
|
||||
DlgConfirm.openSimple(
|
||||
activity,
|
||||
activity.getString(R.string.filter_delete_confirm, filter.phrase)
|
||||
) {
|
||||
delete(activity, access_info, filter, bConfirmed = true)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
TootTaskRunner(activity).run(access_info, object : TootTask {
|
||||
|
||||
|
||||
var filterList : ArrayList<TootFilter>? = null
|
||||
|
||||
|
||||
override fun background(client : TootApiClient) : TootApiResult? {
|
||||
var result = client.request("/api/v1/filters/${filter.id}", Request.Builder().delete())
|
||||
if( result != null && result.error == null){
|
||||
var result =
|
||||
client.request("/api/v1/filters/${filter.id}", Request.Builder().delete())
|
||||
if(result != null && result.error == null) {
|
||||
result = client.request("/api/v1/filters")
|
||||
val jsonArray = result?.jsonArray
|
||||
if( jsonArray != null ) filterList = TootFilter.parseList(jsonArray)
|
||||
if(jsonArray != null) filterList = TootFilter.parseList(jsonArray)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -44,15 +52,15 @@ object Action_Filter {
|
|||
if(result == null) return // cancelled.
|
||||
|
||||
val filterList = this.filterList
|
||||
if( filterList != null) {
|
||||
showToast(activity, false, R.string.delete_succeeded)
|
||||
if(filterList != null) {
|
||||
activity.showToast(false, R.string.delete_succeeded)
|
||||
for(column in App1.getAppState(activity).column_list) {
|
||||
if( column.access_info == access_info ){
|
||||
column.onFilterDeleted(filter,filterList)
|
||||
if(column.access_info == access_info) {
|
||||
column.onFilterDeleted(filter, filterList)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package jp.juggler.subwaytooter.action
|
||||
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import jp.juggler.subwaytooter.*
|
||||
import jp.juggler.subwaytooter.ActMain
|
||||
import jp.juggler.subwaytooter.App1
|
||||
import jp.juggler.subwaytooter.ColumnType
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.*
|
||||
import jp.juggler.subwaytooter.api.entity.*
|
||||
import jp.juggler.subwaytooter.dialog.AccountPicker
|
||||
|
@ -9,8 +12,10 @@ import jp.juggler.subwaytooter.dialog.DlgConfirm
|
|||
import jp.juggler.subwaytooter.table.AcctColor
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.table.UserRelation
|
||||
import jp.juggler.subwaytooter.util.EmptyCallback
|
||||
import jp.juggler.util.*
|
||||
import jp.juggler.util.showToast
|
||||
import jp.juggler.util.toFormRequestBody
|
||||
import jp.juggler.util.toPost
|
||||
import jp.juggler.util.toPostRequestBuilder
|
||||
|
||||
object Action_Follow {
|
||||
|
||||
|
@ -22,12 +27,12 @@ object Action_Follow {
|
|||
bFollow : Boolean = true,
|
||||
bConfirmMoved : Boolean = false,
|
||||
bConfirmed : Boolean = false,
|
||||
callback : EmptyCallback? = null
|
||||
callback : () -> Unit = {}
|
||||
) {
|
||||
val who = whoRef.get()
|
||||
|
||||
if(access_info.isMe(who)) {
|
||||
showToast(activity, false, R.string.it_is_you)
|
||||
activity.showToast(false, R.string.it_is_you)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -73,8 +78,7 @@ object Action_Follow {
|
|||
R.string.confirm_follow_request_who_from,
|
||||
whoRef.decoded_display_name,
|
||||
AcctColor.getNickname(access_info)
|
||||
)
|
||||
, object : DlgConfirm.Callback {
|
||||
), object : DlgConfirm.Callback {
|
||||
|
||||
override fun onOK() {
|
||||
follow(
|
||||
|
@ -242,8 +246,8 @@ object Action_Follow {
|
|||
|
||||
} else {
|
||||
client.request(
|
||||
"/api/v1/accounts/${userId}/${if(bFollow) "follow" else "unfollow"}"
|
||||
, "".toFormRequestBody().toPost()
|
||||
"/api/v1/accounts/${userId}/${if(bFollow) "follow" else "unfollow"}",
|
||||
"".toFormRequestBody().toPost()
|
||||
)?.also { result ->
|
||||
val newRelation = parseItem(::TootRelationShip, parser, result.jsonObject)
|
||||
if(newRelation != null) {
|
||||
|
@ -262,21 +266,21 @@ object Action_Follow {
|
|||
|
||||
if(bFollow && relation.getRequested(who)) {
|
||||
// 鍵付きアカウントにフォローリクエストを申請した状態
|
||||
showToast(activity, false, R.string.follow_requested)
|
||||
activity.showToast(false, R.string.follow_requested)
|
||||
} else if(! bFollow && relation.getRequested(who)) {
|
||||
showToast(activity, false, R.string.follow_request_cant_remove_by_sender)
|
||||
activity.showToast(false, R.string.follow_request_cant_remove_by_sender)
|
||||
} else {
|
||||
// ローカル操作成功、もしくはリモートフォロー成功
|
||||
|
||||
if(callback != null) callback()
|
||||
callback()
|
||||
}
|
||||
|
||||
activity.showColumnMatchAccount(access_info)
|
||||
|
||||
} else if(bFollow && who.locked && (result.response?.code ?: - 1) == 422) {
|
||||
showToast(activity, false, R.string.cant_follow_locked_user)
|
||||
activity.showToast(false, R.string.cant_follow_locked_user)
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -289,7 +293,7 @@ object Action_Follow {
|
|||
access_info : SavedAccount,
|
||||
whoRef : TootAccountRef,
|
||||
bConfirmed : Boolean = false,
|
||||
callback : EmptyCallback? = null
|
||||
callback : () -> Unit = {}
|
||||
) {
|
||||
if(! access_info.isMisskey) {
|
||||
follow(
|
||||
|
@ -307,7 +311,7 @@ object Action_Follow {
|
|||
val who = whoRef.get()
|
||||
|
||||
if(access_info.isMe(who)) {
|
||||
showToast(activity, false, R.string.it_is_you)
|
||||
activity.showToast(false, R.string.it_is_you)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -350,8 +354,7 @@ object Action_Follow {
|
|||
}
|
||||
|
||||
client.request(
|
||||
"/api/following/requests/cancel"
|
||||
, access_info.putMisskeyApiToken().apply {
|
||||
"/api/following/requests/cancel", access_info.putMisskeyApiToken().apply {
|
||||
put("userId", userId)
|
||||
}
|
||||
.toPostRequestBuilder()
|
||||
|
@ -375,16 +378,15 @@ object Action_Follow {
|
|||
val relation = this.relation
|
||||
if(relation != null) {
|
||||
// ローカル操作成功、もしくはリモートフォロー成功
|
||||
if(callback != null) callback()
|
||||
callback()
|
||||
activity.showColumnMatchAccount(access_info)
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// acct で指定したユーザをリモートフォローする
|
||||
fun followRemote(
|
||||
|
@ -393,11 +395,11 @@ object Action_Follow {
|
|||
acct : Acct,
|
||||
locked : Boolean,
|
||||
bConfirmed : Boolean = false,
|
||||
callback : EmptyCallback? = null
|
||||
callback : () -> Unit = {}
|
||||
) {
|
||||
|
||||
if(access_info.isMe(acct)) {
|
||||
showToast(activity, false, R.string.it_is_you)
|
||||
activity.showToast(false, R.string.it_is_you)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -499,8 +501,7 @@ object Action_Follow {
|
|||
}
|
||||
} else {
|
||||
client.request(
|
||||
"/api/v1/accounts/${userId}/follow"
|
||||
, "".toFormRequestBody().toPost()
|
||||
"/api/v1/accounts/${userId}/follow", "".toFormRequestBody().toPost()
|
||||
)?.also { result ->
|
||||
val newRelation = parseItem(::TootRelationShip, parser, result.jsonObject)
|
||||
if(newRelation != null) {
|
||||
|
@ -515,15 +516,12 @@ object Action_Follow {
|
|||
if(result == null) return // cancelled.
|
||||
|
||||
if(relation != null) {
|
||||
|
||||
callback()
|
||||
activity.showColumnMatchAccount(access_info)
|
||||
|
||||
if(callback != null) callback()
|
||||
|
||||
} else if(locked && (result.response?.code ?: - 1) == 422) {
|
||||
showToast(activity, false, R.string.cant_follow_locked_user)
|
||||
activity.showToast(false, R.string.cant_follow_locked_user)
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -590,7 +588,7 @@ object Action_Follow {
|
|||
) {
|
||||
val who = whoRef.get()
|
||||
if(access_info.isMe(who)) {
|
||||
showToast(activity, false, R.string.it_is_you)
|
||||
activity.showToast(false, R.string.it_is_you)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -647,14 +645,13 @@ object Action_Follow {
|
|||
}
|
||||
}
|
||||
|
||||
showToast(
|
||||
activity,
|
||||
activity.showToast(
|
||||
false,
|
||||
if(bAllow) R.string.follow_request_authorized else R.string.follow_request_rejected,
|
||||
whoRef.decoded_display_name
|
||||
)
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package jp.juggler.subwaytooter.action
|
||||
|
||||
import jp.juggler.subwaytooter.ActMain
|
||||
import jp.juggler.subwaytooter.App1
|
||||
import jp.juggler.subwaytooter.ColumnType
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.entity.Acct
|
||||
|
@ -10,6 +9,7 @@ import jp.juggler.subwaytooter.dialog.ActionsDialog
|
|||
import jp.juggler.subwaytooter.table.AcctColor
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.util.matchHost
|
||||
import jp.juggler.subwaytooter.util.openCustomTab
|
||||
import jp.juggler.util.encodePercent
|
||||
import java.util.*
|
||||
|
||||
|
@ -23,7 +23,7 @@ object Action_HashTag {
|
|||
host : Host,
|
||||
tag_without_sharp : String,
|
||||
tag_list : ArrayList<String>?,
|
||||
whoAcct: Acct?
|
||||
whoAcct : Acct?
|
||||
) {
|
||||
val tag_with_sharp = "#$tag_without_sharp"
|
||||
|
||||
|
@ -40,12 +40,18 @@ object Action_HashTag {
|
|||
|
||||
// https://mastodon.juggler.jp/@tateisu/101865456016473337
|
||||
// 一時的に使えなくする
|
||||
if( whoAcct != null ){
|
||||
d.addAction(AcctColor.getStringWithNickname(activity, R.string.open_hashtag_from_account ,whoAcct)) {
|
||||
if(whoAcct != null) {
|
||||
d.addAction(
|
||||
AcctColor.getStringWithNickname(
|
||||
activity,
|
||||
R.string.open_hashtag_from_account,
|
||||
whoAcct
|
||||
)
|
||||
) {
|
||||
timelineOtherInstance(
|
||||
activity,
|
||||
pos,
|
||||
"https://${whoAcct.host?.ascii}/@${whoAcct.username}/tagged/${ tag_without_sharp.encodePercent()}",
|
||||
"https://${whoAcct.host?.ascii}/@${whoAcct.username}/tagged/${tag_without_sharp.encodePercent()}",
|
||||
host,
|
||||
tag_without_sharp,
|
||||
whoAcct
|
||||
|
@ -54,18 +60,10 @@ object Action_HashTag {
|
|||
}
|
||||
|
||||
|
||||
d.addAction(activity.getString(R.string.open_in_browser)) {
|
||||
App1.openCustomTab(
|
||||
activity,
|
||||
url
|
||||
)
|
||||
}
|
||||
.addAction(
|
||||
activity.getString(
|
||||
R.string.quote_hashtag_of,
|
||||
tag_with_sharp
|
||||
)
|
||||
) { Action_Account.openPost(activity, "$tag_with_sharp ") }
|
||||
d.addAction(activity.getString(R.string.open_in_browser))
|
||||
{ activity.openCustomTab(url) }
|
||||
.addAction(activity.getString(R.string.quote_hashtag_of, tag_with_sharp))
|
||||
{ Action_Account.openPost(activity, "$tag_with_sharp ") }
|
||||
|
||||
|
||||
if(tag_list != null && tag_list.size > 1) {
|
||||
|
@ -94,10 +92,16 @@ object Action_HashTag {
|
|||
tag_without_sharp : String,
|
||||
acctAscii : String? = null
|
||||
) {
|
||||
if( acctAscii == null) {
|
||||
if(acctAscii == null) {
|
||||
activity.addColumn(pos, access_info, ColumnType.HASHTAG, tag_without_sharp)
|
||||
}else {
|
||||
activity.addColumn(pos, access_info, ColumnType.HASHTAG_FROM_ACCT, tag_without_sharp,acctAscii)
|
||||
} else {
|
||||
activity.addColumn(
|
||||
pos,
|
||||
access_info,
|
||||
ColumnType.HASHTAG_FROM_ACCT,
|
||||
tag_without_sharp,
|
||||
acctAscii
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +112,7 @@ object Action_HashTag {
|
|||
url : String,
|
||||
host : Host,
|
||||
tag_without_sharp : String,
|
||||
acct :Acct? = null
|
||||
acct : Acct? = null
|
||||
) {
|
||||
|
||||
val dialog = ActionsDialog()
|
||||
|
@ -124,37 +128,36 @@ object Action_HashTag {
|
|||
val list_original_pseudo = ArrayList<SavedAccount>()
|
||||
val list_other = ArrayList<SavedAccount>()
|
||||
for(a in account_list) {
|
||||
if( acct == null){
|
||||
if(acct == null) {
|
||||
when {
|
||||
!a.matchHost(host) -> list_other.add(a)
|
||||
! a.matchHost(host) -> list_other.add(a)
|
||||
a.isPseudo -> list_original_pseudo.add(a)
|
||||
else -> list_original.add(a)
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
when {
|
||||
|
||||
|
||||
// acctからidを取得できない
|
||||
a.isPseudo -> {
|
||||
}
|
||||
|
||||
|
||||
// ミスキーのアカウント別タグTLは未対応
|
||||
a.isMisskey -> {
|
||||
}
|
||||
|
||||
!a.matchHost(host) -> list_other.add(a)
|
||||
! a.matchHost(host) -> list_other.add(a)
|
||||
else -> list_original.add(a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ブラウザで表示する
|
||||
dialog.addAction(activity.getString(R.string.open_web_on_host, host)) {
|
||||
App1.openCustomTab(activity,url)
|
||||
}
|
||||
dialog.addAction(activity.getString(R.string.open_web_on_host, host))
|
||||
{ activity.openCustomTab(url) }
|
||||
|
||||
// 同タンスのアカウントがない場合は疑似アカウントを作成して開く
|
||||
// ただし疑似アカウントではアカウントの同期ができないため、特定ユーザのタグTLは読めない)
|
||||
if( acct == null && list_original.isEmpty() && list_original_pseudo.isEmpty()) {
|
||||
if(acct == null && list_original.isEmpty() && list_original_pseudo.isEmpty()) {
|
||||
dialog.addAction(activity.getString(R.string.open_in_pseudo_account, "?@$host")) {
|
||||
addPseudoAccount(activity, host) { sa ->
|
||||
timeline(activity, pos, sa, tag_without_sharp)
|
||||
|
@ -171,7 +174,7 @@ object Action_HashTag {
|
|||
a.acct
|
||||
)
|
||||
)
|
||||
{ timeline(activity, pos, a, tag_without_sharp,acct?.ascii) }
|
||||
{ timeline(activity, pos, a, tag_without_sharp, acct?.ascii) }
|
||||
}
|
||||
for(a in list_original_pseudo) {
|
||||
dialog.addAction(
|
||||
|
@ -181,7 +184,7 @@ object Action_HashTag {
|
|||
a.acct
|
||||
)
|
||||
)
|
||||
{ timeline(activity, pos, a, tag_without_sharp,acct?.ascii) }
|
||||
{ timeline(activity, pos, a, tag_without_sharp, acct?.ascii) }
|
||||
}
|
||||
for(a in list_other) {
|
||||
dialog.addAction(
|
||||
|
@ -191,7 +194,7 @@ object Action_HashTag {
|
|||
a.acct
|
||||
)
|
||||
)
|
||||
{ timeline(activity, pos, a, tag_without_sharp,acct?.ascii) }
|
||||
{ timeline(activity, pos, a, tag_without_sharp, acct?.ascii) }
|
||||
}
|
||||
|
||||
dialog.show(activity, "#$tag_without_sharp")
|
||||
|
|
|
@ -9,6 +9,7 @@ import jp.juggler.subwaytooter.api.entity.TootStatus
|
|||
import jp.juggler.subwaytooter.dialog.AccountPicker
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.util.matchHost
|
||||
import jp.juggler.subwaytooter.util.openBrowser
|
||||
import jp.juggler.util.*
|
||||
import java.util.*
|
||||
|
||||
|
@ -35,7 +36,7 @@ object Action_Instance {
|
|||
override fun handleResult(result : TootApiResult?) {
|
||||
result ?: return // cancelled.
|
||||
when(val ti = targetInstance) {
|
||||
null -> showToast(activity, true, result.error)
|
||||
null -> activity.showToast(true, result.error)
|
||||
else -> profileDirectory(activity, accessInfo, host, ti, pos)
|
||||
}
|
||||
}
|
||||
|
@ -43,11 +44,11 @@ object Action_Instance {
|
|||
|
||||
// Misskey非対応
|
||||
instance.instanceType == TootInstance.InstanceType.Misskey ->
|
||||
showToast(activity, false, R.string.profile_directory_not_supported_on_misskey)
|
||||
activity.showToast(false, R.string.profile_directory_not_supported_on_misskey)
|
||||
|
||||
// バージョンが足りないならWebページを開く
|
||||
! instance.versionGE(TootInstance.VERSION_3_0_0_rc1) ->
|
||||
App1.openBrowser(activity, "https://${host.ascii}/explore")
|
||||
activity.openBrowser("https://${host.ascii}/explore")
|
||||
|
||||
// ホスト名部分が一致するならそのアカウントで開く
|
||||
accessInfo.matchHost(host) ->
|
||||
|
@ -123,10 +124,10 @@ object Action_Instance {
|
|||
fun timelineDomain(
|
||||
activity : ActMain,
|
||||
pos : Int,
|
||||
accessInfo: SavedAccount,
|
||||
accessInfo : SavedAccount,
|
||||
host : Host
|
||||
){
|
||||
activity.addColumn(pos, accessInfo, ColumnType.DOMAIN_TIMELINE,host)
|
||||
) {
|
||||
activity.addColumn(pos, accessInfo, ColumnType.DOMAIN_TIMELINE, host)
|
||||
}
|
||||
|
||||
// 指定タンスのローカルタイムラインを開く
|
||||
|
@ -167,7 +168,7 @@ object Action_Instance {
|
|||
) {
|
||||
|
||||
if(access_info.matchHost(domain)) {
|
||||
showToast(activity, false, R.string.it_is_you)
|
||||
activity.showToast(false, R.string.it_is_you)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -190,14 +191,13 @@ object Action_Instance {
|
|||
column.onDomainBlockChanged(access_info, domain, bBlock)
|
||||
}
|
||||
|
||||
showToast(
|
||||
activity,
|
||||
activity.showToast(
|
||||
false,
|
||||
if(bBlock) R.string.block_succeeded else R.string.unblock_succeeded
|
||||
)
|
||||
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -235,7 +235,7 @@ object Action_Instance {
|
|||
if(localStatus != null) {
|
||||
timelinePublicAround2(activity, access_info, pos, localStatus.id, type)
|
||||
} else {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast(true, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -298,7 +298,7 @@ object Action_Instance {
|
|||
return
|
||||
}
|
||||
|
||||
showToast(activity, false, R.string.missing_available_account)
|
||||
activity.showToast(false, R.string.missing_available_account)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import okhttp3.Request
|
|||
object Action_List {
|
||||
|
||||
fun interface CreateCallback {
|
||||
|
||||
fun onCreated(list : TootList)
|
||||
}
|
||||
|
||||
|
@ -65,11 +66,11 @@ object Action_List {
|
|||
column.onListListUpdated(access_info)
|
||||
}
|
||||
|
||||
showToast(activity, false, R.string.list_created)
|
||||
activity.showToast(false, R.string.list_created)
|
||||
|
||||
callback?.onCreated(list)
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -85,8 +86,7 @@ object Action_List {
|
|||
|
||||
if(! bConfirmed) {
|
||||
DlgConfirm.openSimple(
|
||||
activity
|
||||
, activity.getString(R.string.list_delete_confirm, list.title)
|
||||
activity, activity.getString(R.string.list_delete_confirm, list.title)
|
||||
) {
|
||||
delete(activity, access_info, list, bConfirmed = true)
|
||||
}
|
||||
|
@ -121,10 +121,10 @@ object Action_List {
|
|||
column.onListListUpdated(access_info)
|
||||
}
|
||||
|
||||
showToast(activity, false, R.string.delete_succeeded)
|
||||
activity.showToast(false, R.string.delete_succeeded)
|
||||
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -142,7 +142,7 @@ object Action_List {
|
|||
item.title,
|
||||
callback = object : DlgTextInput.Callback {
|
||||
override fun onEmptyError() {
|
||||
showToast(activity, false, R.string.list_name_empty)
|
||||
activity.showToast(false, R.string.list_name_empty)
|
||||
}
|
||||
|
||||
override fun onOK(dialog : Dialog, text : String) {
|
||||
|
@ -191,7 +191,7 @@ object Action_List {
|
|||
}
|
||||
dialog.dismissSafe()
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -17,6 +17,7 @@ object Action_ListMember {
|
|||
private val reFollowError = "follow".asciiPattern(Pattern.CASE_INSENSITIVE)
|
||||
|
||||
fun interface Callback {
|
||||
|
||||
fun onListMemberUpdated(willRegistered : Boolean, bSuccess : Boolean)
|
||||
}
|
||||
|
||||
|
@ -51,13 +52,13 @@ object Action_ListMember {
|
|||
} else {
|
||||
|
||||
val isMe = access_info.isMe(local_who)
|
||||
if( isMe ) {
|
||||
if(isMe) {
|
||||
val (ti, ri) = TootInstance.get(client)
|
||||
if(ti == null) return ri
|
||||
if(! ti.versionGE(TootInstance.VERSION_3_1_0_rc1)) {
|
||||
return TootApiResult(activity.getString(R.string.it_is_you))
|
||||
}
|
||||
}else if(bFollow) {
|
||||
} else if(bFollow) {
|
||||
// リモートユーザの解決
|
||||
if(! access_info.isLocalUser(local_who)) {
|
||||
val (r2, ar) = client.syncAccountByAcct(access_info, local_who.acct)
|
||||
|
@ -119,7 +120,7 @@ object Action_ListMember {
|
|||
// フォロー状態の更新を表示に反映させる
|
||||
if(bFollow) activity.showColumnMatchAccount(access_info)
|
||||
|
||||
showToast(activity, false, R.string.list_member_added)
|
||||
activity.showToast(false, R.string.list_member_added)
|
||||
|
||||
bSuccess = true
|
||||
|
||||
|
@ -159,7 +160,7 @@ object Action_ListMember {
|
|||
return
|
||||
}
|
||||
|
||||
showToast(activity, true, error)
|
||||
activity.showToast(true, error)
|
||||
|
||||
}
|
||||
} finally {
|
||||
|
@ -209,12 +210,12 @@ object Action_ListMember {
|
|||
column.onListMemberUpdated(access_info, list_id, local_who, false)
|
||||
}
|
||||
|
||||
showToast(activity, false, R.string.delete_succeeded)
|
||||
activity.showToast(false, R.string.delete_succeeded)
|
||||
|
||||
bSuccess = true
|
||||
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
} finally {
|
||||
callback?.onListMemberUpdated(false, bSuccess)
|
||||
|
|
|
@ -44,13 +44,13 @@ object Action_Notification {
|
|||
if(result.jsonObject != null) {
|
||||
// ok. api have return empty object.
|
||||
for(column in App1.getAppState(activity).column_list) {
|
||||
if(column.isNotificationColumn && column.access_info == target_account ) {
|
||||
if(column.isNotificationColumn && column.access_info == target_account) {
|
||||
column.removeNotifications()
|
||||
}
|
||||
}
|
||||
showToast(activity, false, R.string.delete_succeeded)
|
||||
activity.showToast(false, R.string.delete_succeeded)
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -92,9 +92,9 @@ object Action_Notification {
|
|||
for(column in App1.getAppState(activity).column_list) {
|
||||
column.removeNotificationOne(access_info, notification)
|
||||
}
|
||||
showToast(activity, true, R.string.delete_succeeded)
|
||||
activity.showToast(true, R.string.delete_succeeded)
|
||||
} else {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast(true, result.error)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ import jp.juggler.subwaytooter.dialog.ActionsDialog
|
|||
import jp.juggler.subwaytooter.dialog.DlgConfirm
|
||||
import jp.juggler.subwaytooter.table.AcctColor
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.util.EmptyCallback
|
||||
import jp.juggler.subwaytooter.util.SavedAccountCallback
|
||||
import jp.juggler.subwaytooter.util.matchHost
|
||||
import jp.juggler.subwaytooter.util.openCustomTab
|
||||
import jp.juggler.util.*
|
||||
import okhttp3.Request
|
||||
import java.util.*
|
||||
|
@ -56,12 +56,12 @@ object Action_Toot {
|
|||
access_info : SavedAccount,
|
||||
arg_status : TootStatus,
|
||||
nCrossAccountMode : Int,
|
||||
callback : EmptyCallback?,
|
||||
callback : () -> Unit,
|
||||
bSet : Boolean = true,
|
||||
bConfirmed : Boolean = false
|
||||
) {
|
||||
if(App1.getAppState(activity).isBusyFav(access_info, arg_status)) {
|
||||
showToast(activity, false, R.string.wait_previous_operation)
|
||||
activity.showToast(false, R.string.wait_previous_operation)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -209,11 +209,10 @@ object Action_Toot {
|
|||
true
|
||||
}
|
||||
}
|
||||
if(callback != null) callback()
|
||||
|
||||
callback()
|
||||
}
|
||||
|
||||
else -> showToast(activity, true, result.error)
|
||||
else -> activity.showToast(true, result.error)
|
||||
}
|
||||
// 結果に関わらず、更新中状態から復帰させる
|
||||
activity.showColumnMatchAccount(access_info)
|
||||
|
@ -256,16 +255,16 @@ object Action_Toot {
|
|||
access_info : SavedAccount,
|
||||
arg_status : TootStatus,
|
||||
nCrossAccountMode : Int,
|
||||
callback : EmptyCallback?,
|
||||
callback : () -> Unit,
|
||||
bSet : Boolean = true,
|
||||
bConfirmed : Boolean = false
|
||||
) {
|
||||
if(App1.getAppState(activity).isBusyFav(access_info, arg_status)) {
|
||||
showToast(activity, false, R.string.wait_previous_operation)
|
||||
activity.showToast(false, R.string.wait_previous_operation)
|
||||
return
|
||||
}
|
||||
if(access_info.isMisskey) {
|
||||
showToast(activity, false, R.string.misskey_account_not_supported)
|
||||
activity.showToast(false, R.string.misskey_account_not_supported)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -344,10 +343,10 @@ object Action_Toot {
|
|||
true
|
||||
}
|
||||
}
|
||||
if(callback != null) callback()
|
||||
callback()
|
||||
}
|
||||
|
||||
else -> showToast(activity, true, result.error)
|
||||
else -> activity.showToast(true, result.error)
|
||||
}
|
||||
|
||||
// 結果に関わらず、更新中状態から復帰させる
|
||||
|
@ -377,7 +376,7 @@ object Action_Toot {
|
|||
if(a.acct == status_owner) list.add(a)
|
||||
}
|
||||
if(list.isEmpty()) {
|
||||
showToast(activity, false, R.string.boost_private_toot_not_allowed)
|
||||
activity.showToast(false, R.string.boost_private_toot_not_allowed)
|
||||
return
|
||||
}
|
||||
AccountPicker.pick(
|
||||
|
@ -393,7 +392,7 @@ object Action_Toot {
|
|||
status,
|
||||
status_owner,
|
||||
calcCrossAccountMode(timeline_account, action_account),
|
||||
activity.boost_complete_callback
|
||||
callback = activity.boost_complete_callback
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
@ -410,7 +409,7 @@ object Action_Toot {
|
|||
status,
|
||||
status_owner,
|
||||
calcCrossAccountMode(timeline_account, action_account),
|
||||
activity.boost_complete_callback
|
||||
callback = activity.boost_complete_callback
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -422,15 +421,15 @@ object Action_Toot {
|
|||
arg_status : TootStatus,
|
||||
status_owner : Acct,
|
||||
nCrossAccountMode : Int,
|
||||
callback : EmptyCallback?,
|
||||
bSet : Boolean = true,
|
||||
bConfirmed : Boolean = false,
|
||||
visibility : TootVisibility? = null
|
||||
visibility : TootVisibility? = null,
|
||||
callback : () -> Unit
|
||||
) {
|
||||
|
||||
// アカウントからステータスにブースト操作を行っているなら、何もしない
|
||||
if(App1.getAppState(activity).isBusyBoost(access_info, arg_status)) {
|
||||
showToast(activity, false, R.string.wait_previous_operation)
|
||||
activity.showToast(false, R.string.wait_previous_operation)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -438,7 +437,7 @@ object Action_Toot {
|
|||
val isPrivateToot = access_info.isMastodon &&
|
||||
arg_status.visibility == TootVisibility.PrivateFollowers
|
||||
if(isPrivateToot && access_info.acct != status_owner) {
|
||||
showToast(activity, false, R.string.boost_private_toot_not_allowed)
|
||||
activity.showToast(false, R.string.boost_private_toot_not_allowed)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -463,10 +462,10 @@ object Action_Toot {
|
|||
arg_status,
|
||||
status_owner,
|
||||
nCrossAccountMode,
|
||||
callback,
|
||||
bSet = bSet,
|
||||
bConfirmed = true,
|
||||
visibility = visibility
|
||||
visibility = visibility,
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -606,7 +605,7 @@ object Action_Toot {
|
|||
true
|
||||
}
|
||||
}
|
||||
if(callback != null) callback()
|
||||
callback()
|
||||
}
|
||||
|
||||
new_status != null -> {
|
||||
|
@ -652,10 +651,10 @@ object Action_Toot {
|
|||
true
|
||||
}
|
||||
}
|
||||
if(callback != null) callback()
|
||||
callback()
|
||||
}
|
||||
|
||||
else -> showToast(activity, true, result.error)
|
||||
else -> activity.showToast(true, result.error)
|
||||
}
|
||||
|
||||
// 結果に関わらず、更新中状態から復帰させる
|
||||
|
@ -694,12 +693,12 @@ object Action_Toot {
|
|||
if(result == null) return // cancelled.
|
||||
|
||||
if(result.jsonObject != null) {
|
||||
showToast(activity, false, R.string.delete_succeeded)
|
||||
activity.showToast(false, R.string.delete_succeeded)
|
||||
for(column in App1.getAppState(activity).column_list) {
|
||||
column.onStatusRemoved(access_info.apDomain, status_id)
|
||||
}
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -820,12 +819,8 @@ object Action_Toot {
|
|||
val host_original = Host.parse(url.toUri().authority ?: "")
|
||||
|
||||
// 選択肢:ブラウザで表示する
|
||||
dialog.addAction(
|
||||
activity.getString(
|
||||
R.string.open_web_on_host,
|
||||
host_original.pretty
|
||||
)
|
||||
) { App1.openCustomTab(activity, url) }
|
||||
dialog.addAction(activity.getString(R.string.open_web_on_host, host_original.pretty))
|
||||
{ activity.openCustomTab(url) }
|
||||
|
||||
// トゥートの投稿元タンスにあるアカウント
|
||||
val local_account_list = ArrayList<SavedAccount>()
|
||||
|
@ -962,7 +957,7 @@ object Action_Toot {
|
|||
if(local_status_id != null) {
|
||||
conversationLocal(activity, pos, access_info, local_status_id)
|
||||
} else {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast(true, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -993,9 +988,9 @@ object Action_Toot {
|
|||
val status = tmp
|
||||
val replyId = status?.in_reply_to_id
|
||||
when {
|
||||
status == null -> showToast(activity, true, result.error ?: "?")
|
||||
replyId == null -> showToast(
|
||||
activity, true,
|
||||
status == null -> activity.showToast(true, result.error ?: "?")
|
||||
replyId == null -> activity.showToast(
|
||||
true,
|
||||
"showReplyTootsearch: in_reply_to_id is null"
|
||||
)
|
||||
else -> conversationLocal(activity, pos, a, replyId)
|
||||
|
@ -1096,7 +1091,7 @@ object Action_Toot {
|
|||
}
|
||||
}
|
||||
|
||||
else -> showToast(activity, true, result.error)
|
||||
else -> activity.showToast(true, result.error)
|
||||
}
|
||||
|
||||
// 結果に関わらず、更新中状態から復帰させる
|
||||
|
@ -1153,7 +1148,7 @@ object Action_Toot {
|
|||
if(ls != null) {
|
||||
reply(activity, access_info, ls, quote = quote)
|
||||
} else {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast(true, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -1252,7 +1247,7 @@ object Action_Toot {
|
|||
return
|
||||
}
|
||||
val error = result.error ?: "(no information)"
|
||||
showToast(activity, true, activity.getString(R.string.cant_sync_toot) + " : $error")
|
||||
activity.showToast(true, activity.getString(R.string.cant_sync_toot) + " : $error")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1293,13 +1288,12 @@ object Action_Toot {
|
|||
}
|
||||
}
|
||||
}
|
||||
showToast(
|
||||
activity,
|
||||
activity.showToast(
|
||||
true,
|
||||
if(bMute) R.string.mute_succeeded else R.string.unmute_succeeded
|
||||
)
|
||||
} else {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast(true, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -1311,7 +1305,7 @@ object Action_Toot {
|
|||
arg_status : TootStatus,
|
||||
status_owner_acct : Acct,
|
||||
nCrossAccountMode : Int,
|
||||
callback : EmptyCallback?,
|
||||
callback : () -> Unit,
|
||||
bSet : Boolean = true,
|
||||
code : String? = null
|
||||
) {
|
||||
|
@ -1319,7 +1313,7 @@ object Action_Toot {
|
|||
|
||||
// 自分の投稿にはリアクション出来ない
|
||||
if(access_info.acct == status_owner_acct) {
|
||||
showToast(activity, false, R.string.it_is_you)
|
||||
activity.showToast(false, R.string.it_is_you)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1404,11 +1398,11 @@ object Action_Toot {
|
|||
|
||||
val error = result.error
|
||||
if(error != null) {
|
||||
showToast(activity, false, error)
|
||||
activity.showToast(false, error)
|
||||
return
|
||||
}
|
||||
|
||||
if(callback != null) callback()
|
||||
callback()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1481,7 +1475,7 @@ object Action_Toot {
|
|||
|
||||
val error = result.error
|
||||
if(error != null) {
|
||||
showToast(activity, false, error)
|
||||
activity.showToast(false, error)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1512,7 +1506,7 @@ object Action_Toot {
|
|||
|
||||
val error = result.error
|
||||
if(error != null) {
|
||||
showToast(activity, false, error)
|
||||
activity.showToast(false, error)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import jp.juggler.subwaytooter.table.SavedAccount
|
|||
import jp.juggler.subwaytooter.table.UserRelation
|
||||
import jp.juggler.subwaytooter.util.TootApiResultCallback
|
||||
import jp.juggler.subwaytooter.util.matchHost
|
||||
import jp.juggler.subwaytooter.util.openCustomTab
|
||||
import jp.juggler.util.*
|
||||
import okhttp3.Request
|
||||
|
||||
|
@ -35,7 +36,7 @@ object Action_User {
|
|||
val whoAcct = whoArg.acct
|
||||
|
||||
if(access_info.isMe(whoAcct)) {
|
||||
showToast(activity, false, R.string.it_is_you)
|
||||
activity.showToast(false, R.string.it_is_you)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -56,7 +57,7 @@ object Action_User {
|
|||
TootApiResult()
|
||||
}
|
||||
|
||||
val whoId = if(access_info.matchHost(whoAccessInfo) ) {
|
||||
val whoId = if(access_info.matchHost(whoAccessInfo)) {
|
||||
whoArg.id
|
||||
} else {
|
||||
val (result, accountRef) = client.syncAccountByAcct(access_info, whoAcct)
|
||||
|
@ -124,7 +125,7 @@ object Action_User {
|
|||
if(relation != null && whoId != null) {
|
||||
// 未確認だが、自分をミュートしようとするとリクエストは成功するがレスポンス中のmutingはfalseになるはず
|
||||
if(bMute && ! relation.muting) {
|
||||
showToast(activity, false, R.string.not_muted)
|
||||
activity.showToast(false, R.string.not_muted)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -163,14 +164,13 @@ object Action_User {
|
|||
}
|
||||
}
|
||||
|
||||
showToast(
|
||||
activity,
|
||||
activity.showToast(
|
||||
false,
|
||||
if(relation.muting) R.string.mute_succeeded else R.string.unmute_succeeded
|
||||
)
|
||||
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -220,7 +220,11 @@ object Action_User {
|
|||
.show()
|
||||
}
|
||||
|
||||
fun muteFromAnotherAccount(activity : ActMain, who : TootAccount,whoAccessInfo : SavedAccount) {
|
||||
fun muteFromAnotherAccount(
|
||||
activity : ActMain,
|
||||
who : TootAccount,
|
||||
whoAccessInfo : SavedAccount
|
||||
) {
|
||||
AccountPicker.pick(
|
||||
activity,
|
||||
bAllowPseudo = false,
|
||||
|
@ -228,7 +232,7 @@ object Action_User {
|
|||
message = activity.getString(R.string.account_picker_mute, who.acct.pretty),
|
||||
accountListArg = makeAccountListNonPseudo(activity, who.apDomain)
|
||||
) { ai ->
|
||||
muteConfirm(activity, ai, who,whoAccessInfo)
|
||||
muteConfirm(activity, ai, who, whoAccessInfo)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,7 +247,7 @@ object Action_User {
|
|||
val whoAcct = whoArg.acct
|
||||
|
||||
if(access_info.isMe(whoAcct)) {
|
||||
showToast(activity, false, R.string.it_is_you)
|
||||
activity.showToast(false, R.string.it_is_you)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -264,7 +268,7 @@ object Action_User {
|
|||
TootApiResult()
|
||||
}
|
||||
|
||||
val whoId = if(access_info.matchHost(whoAccessInfo) ) {
|
||||
val whoId = if(access_info.matchHost(whoAccessInfo)) {
|
||||
whoArg.id
|
||||
} else {
|
||||
val (result, accountRef) = client.syncAccountByAcct(access_info, whoAcct)
|
||||
|
@ -334,7 +338,7 @@ object Action_User {
|
|||
|
||||
// 自分をブロックしようとすると、blocking==falseで帰ってくる
|
||||
if(bBlock && ! relation.blocking) {
|
||||
showToast(activity, false, R.string.not_blocked)
|
||||
activity.showToast(false, R.string.not_blocked)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -377,8 +381,7 @@ object Action_User {
|
|||
}
|
||||
}
|
||||
|
||||
showToast(
|
||||
activity,
|
||||
activity.showToast(
|
||||
false,
|
||||
if(relation.blocking)
|
||||
R.string.block_succeeded
|
||||
|
@ -386,7 +389,7 @@ object Action_User {
|
|||
R.string.unblock_succeeded
|
||||
)
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
activity.showToast(false, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -464,9 +467,9 @@ object Action_User {
|
|||
|
||||
when(val who = this.who) {
|
||||
null -> {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast(true, result.error)
|
||||
// 仕方ないのでchrome tab で開く
|
||||
App1.openCustomTab(activity, who_url)
|
||||
activity.openCustomTab(who_url)
|
||||
}
|
||||
|
||||
else -> activity.addColumn(pos, access_info, ColumnType.PROFILE, who.id)
|
||||
|
@ -550,7 +553,7 @@ object Action_User {
|
|||
when(val who = this.who) {
|
||||
null -> {
|
||||
// ダメならchromeで開く
|
||||
App1.openCustomTab(activity, url)
|
||||
activity.openCustomTab(url)
|
||||
}
|
||||
|
||||
else -> profileLocal(activity, pos, access_info, who)
|
||||
|
@ -570,7 +573,7 @@ object Action_User {
|
|||
if(! SavedAccount.hasRealAccount()) {
|
||||
// 疑似アカウントしか登録されていない
|
||||
// chrome tab で開く
|
||||
App1.openCustomTab(activity, original_url)
|
||||
activity.openCustomTab(original_url)
|
||||
} else {
|
||||
AccountPicker.pick(
|
||||
activity,
|
||||
|
@ -599,7 +602,7 @@ object Action_User {
|
|||
b.setBackgroundResource(R.drawable.btn_bg_transparent_round6dp)
|
||||
|
||||
b.setOnClickListener {
|
||||
App1.openCustomTab(activity, original_url)
|
||||
activity.openCustomTab(original_url)
|
||||
}
|
||||
ll.addView(b, 0)
|
||||
}
|
||||
|
@ -636,7 +639,7 @@ object Action_User {
|
|||
onReportComplete : TootApiResultCallback
|
||||
) {
|
||||
if(access_info.isMe(who)) {
|
||||
showToast(activity, false, R.string.it_is_you)
|
||||
activity.showToast(false, R.string.it_is_you)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -663,9 +666,9 @@ object Action_User {
|
|||
if(result.jsonObject != null) {
|
||||
onReportComplete(result)
|
||||
|
||||
showToast(activity, false, R.string.report_completed)
|
||||
activity.showToast(false, R.string.report_completed)
|
||||
} else {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast(true, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -676,7 +679,7 @@ object Action_User {
|
|||
activity : ActMain, access_info : SavedAccount, who : TootAccount, bShow : Boolean
|
||||
) {
|
||||
if(access_info.isMe(who)) {
|
||||
showToast(activity, false, R.string.it_is_you)
|
||||
activity.showToast(false, R.string.it_is_you)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -716,9 +719,9 @@ object Action_User {
|
|||
if(result == null) return // cancelled.
|
||||
|
||||
if(relation != null) {
|
||||
showToast(activity, true, R.string.operation_succeeded)
|
||||
activity.showToast(true, R.string.operation_succeeded)
|
||||
} else {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast(true, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -751,7 +754,6 @@ object Action_User {
|
|||
) {
|
||||
if(who == null) return
|
||||
|
||||
|
||||
val initial_text = "@${access_info.getFullAcct(who).ascii} "
|
||||
AccountPicker.pick(
|
||||
activity,
|
||||
|
@ -794,11 +796,11 @@ object Action_User {
|
|||
// error
|
||||
val error = result.error
|
||||
if(error != null) {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast(true, result.error)
|
||||
return
|
||||
}
|
||||
|
||||
showToast(activity, false, R.string.delete_succeeded)
|
||||
activity.showToast(false, R.string.delete_succeeded)
|
||||
|
||||
// update suggestion column
|
||||
for(column in activity.app_state.column_list) {
|
||||
|
@ -819,12 +821,20 @@ object Action_User {
|
|||
return client.request(
|
||||
"/api/v1/accounts/$whoId/follow",
|
||||
jsonObject {
|
||||
put("notify",enabled)
|
||||
put("notify", enabled)
|
||||
}.toPostRequestBuilder()
|
||||
)?.also{ result->
|
||||
val relation = parseItem( ::TootRelationShip, TootParser(activity,accessInfo),result.jsonObject)
|
||||
if(relation!=null){
|
||||
UserRelation.save1Mastodon(System.currentTimeMillis(),accessInfo.db_id,relation)
|
||||
)?.also { result ->
|
||||
val relation = parseItem(
|
||||
::TootRelationShip,
|
||||
TootParser(activity, accessInfo),
|
||||
result.jsonObject
|
||||
)
|
||||
if(relation != null) {
|
||||
UserRelation.save1Mastodon(
|
||||
System.currentTimeMillis(),
|
||||
accessInfo.db_id,
|
||||
relation
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -836,11 +846,11 @@ object Action_User {
|
|||
// error
|
||||
val error = result.error
|
||||
if(error != null) {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast(true, result.error)
|
||||
return
|
||||
}
|
||||
|
||||
showToast(activity, false, R.string.operation_succeeded)
|
||||
activity.showToast(false, R.string.operation_succeeded)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ class TootApiClient(
|
|||
}
|
||||
|
||||
init {
|
||||
pref = Pref.pref(context)
|
||||
pref = context.pref()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -566,7 +566,7 @@ class TootApiClient(
|
|||
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
||||
|
||||
if(result.error != null) {
|
||||
showToast(context, false, result.error)
|
||||
context.showToast(false, result.error)
|
||||
return null
|
||||
}
|
||||
|
||||
|
@ -583,7 +583,7 @@ class TootApiClient(
|
|||
) {
|
||||
val error = result.error
|
||||
if(error != null) {
|
||||
showToast(context, false, error)
|
||||
context.showToast(false, error)
|
||||
return null
|
||||
}
|
||||
return null
|
||||
|
@ -593,7 +593,7 @@ class TootApiClient(
|
|||
|
||||
val jsonObject = result.jsonObject
|
||||
if(jsonObject == null) {
|
||||
showToast(context, false, result.error)
|
||||
context.showToast(false, result.error)
|
||||
return null
|
||||
}
|
||||
// {"token":"0ba88e2d-4b7d-4599-8d90-dc341a005637","url":"https://misskey.xyz/auth/0ba88e2d-4b7d-4599-8d90-dc341a005637"}
|
||||
|
@ -601,7 +601,7 @@ class TootApiClient(
|
|||
// ブラウザで開くURL
|
||||
val url = jsonObject.string("url")
|
||||
if(url?.isEmpty() != false) {
|
||||
showToast(context, false, "missing 'url' in auth session response.")
|
||||
context.showToast(false, "missing 'url' in auth session response.")
|
||||
return null
|
||||
}
|
||||
|
||||
|
@ -690,7 +690,7 @@ class TootApiClient(
|
|||
|
||||
val appSecret = jsonObject.string(KEY_MISSKEY_APP_SECRET)
|
||||
if(appSecret?.isEmpty() != false) {
|
||||
showToast(context, true, context.getString(R.string.cant_get_misskey_app_secret))
|
||||
context.showToast(true, context.getString(R.string.cant_get_misskey_app_secret))
|
||||
return null
|
||||
}
|
||||
// {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package jp.juggler.subwaytooter.api.entity
|
||||
|
||||
import jp.juggler.subwaytooter.Pref
|
||||
import jp.juggler.subwaytooter.api.TootParser
|
||||
import jp.juggler.subwaytooter.pref
|
||||
import jp.juggler.subwaytooter.util.DecodeOptions
|
||||
import jp.juggler.util.JsonObject
|
||||
import jp.juggler.util.filterNotEmpty
|
||||
|
@ -61,7 +61,7 @@ class TootCard(
|
|||
},
|
||||
image = src.media_attachments
|
||||
?.firstOrNull()
|
||||
?.urlForThumbnail(Pref.pref(parser.context))
|
||||
?.urlForThumbnail(parser.context.pref())
|
||||
?: src.account.avatar_static,
|
||||
type = "photo"
|
||||
)
|
||||
|
|
|
@ -30,36 +30,36 @@ object AccountPicker {
|
|||
activity : AppCompatActivity,
|
||||
bAllowPseudo : Boolean = false,
|
||||
bAllowMisskey : Boolean = true,
|
||||
bAllowMastodon: Boolean = true,
|
||||
bAllowMastodon : Boolean = true,
|
||||
bAuto : Boolean = false,
|
||||
message : String? = null,
|
||||
accountListArg : ArrayList<SavedAccount>? = null,
|
||||
dismiss_callback : DialogInterfaceCallback? = null,
|
||||
extra_callback : (LinearLayout,Int,Int)->Unit = {_,_,_->},
|
||||
extra_callback : (LinearLayout, Int, Int) -> Unit = { _, _, _ -> },
|
||||
callback : SavedAccountCallback
|
||||
) {
|
||||
var removedMisskey =0
|
||||
var removedPseudo =0
|
||||
var removedMisskey = 0
|
||||
var removedPseudo = 0
|
||||
var removeMastodon = 0
|
||||
val account_list : MutableList<SavedAccount> = accountListArg ?: {
|
||||
val l = SavedAccount.loadAccountList(activity).filter { a->
|
||||
val l = SavedAccount.loadAccountList(activity).filter { a ->
|
||||
var bOk = true
|
||||
|
||||
if( !bAllowMastodon && !a.isMisskey ){
|
||||
++removeMastodon
|
||||
bOk=false
|
||||
if(! bAllowMastodon && ! a.isMisskey) {
|
||||
++ removeMastodon
|
||||
bOk = false
|
||||
}
|
||||
|
||||
if( !bAllowMisskey && a.isMisskey ){
|
||||
++removedMisskey
|
||||
bOk=false
|
||||
if(! bAllowMisskey && a.isMisskey) {
|
||||
++ removedMisskey
|
||||
bOk = false
|
||||
}
|
||||
|
||||
if( !bAllowPseudo && a.isPseudo ){
|
||||
++removedPseudo
|
||||
bOk=false
|
||||
|
||||
if(! bAllowPseudo && a.isPseudo) {
|
||||
++ removedPseudo
|
||||
bOk = false
|
||||
}
|
||||
|
||||
|
||||
bOk
|
||||
}.toMutableList()
|
||||
SavedAccount.sort(l)
|
||||
|
@ -67,30 +67,30 @@ object AccountPicker {
|
|||
}()
|
||||
|
||||
if(account_list.isEmpty()) {
|
||||
|
||||
val sb=StringBuilder()
|
||||
|
||||
if( removedPseudo > 0 ){
|
||||
|
||||
val sb = StringBuilder()
|
||||
|
||||
if(removedPseudo > 0) {
|
||||
sb.append(activity.getString(R.string.not_available_for_pseudo_account))
|
||||
}
|
||||
|
||||
if( removedMisskey > 0 ){
|
||||
if(sb.isNotEmpty() ) sb.append('\n')
|
||||
|
||||
if(removedMisskey > 0) {
|
||||
if(sb.isNotEmpty()) sb.append('\n')
|
||||
sb.append(activity.getString(R.string.not_available_for_misskey_account))
|
||||
}
|
||||
if( removeMastodon > 0 ){
|
||||
if(sb.isNotEmpty() ) sb.append('\n')
|
||||
if(removeMastodon > 0) {
|
||||
if(sb.isNotEmpty()) sb.append('\n')
|
||||
sb.append(activity.getString(R.string.not_available_for_mastodon_account))
|
||||
}
|
||||
|
||||
if( sb.isEmpty() ){
|
||||
|
||||
if(sb.isEmpty()) {
|
||||
sb.append(activity.getString(R.string.account_empty))
|
||||
}
|
||||
|
||||
showToast(activity, false,sb.toString())
|
||||
activity.showToast(false, sb.toString())
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if(bAuto && account_list.size == 1) {
|
||||
callback(account_list[0])
|
||||
return
|
||||
|
@ -121,19 +121,22 @@ object AccountPicker {
|
|||
|
||||
val density = activity.resources.displayMetrics.density
|
||||
|
||||
val llAccounts :LinearLayout= viewRoot.findViewById(R.id.llAccounts)
|
||||
val llAccounts : LinearLayout = viewRoot.findViewById(R.id.llAccounts)
|
||||
val pad_se = (0.5f + 12f * density).toInt()
|
||||
val pad_tb = (0.5f + 6f * density).toInt()
|
||||
|
||||
for(a in account_list) {
|
||||
val lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
val lp = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
|
||||
val ac = AcctColor.load(a)
|
||||
|
||||
val b = Button(activity)
|
||||
|
||||
if(AcctColor.hasColorBackground(ac)) {
|
||||
b.background = getAdaptiveRippleDrawableRound(activity,ac.color_bg,ac.color_fg)
|
||||
b.background = getAdaptiveRippleDrawableRound(activity, ac.color_bg, ac.color_fg)
|
||||
} else {
|
||||
b.setBackgroundResource(R.drawable.btn_bg_transparent_round6dp)
|
||||
}
|
||||
|
@ -148,13 +151,13 @@ object AccountPicker {
|
|||
b.minHeight = (0.5f + 32f * density).toInt()
|
||||
|
||||
val sb = SpannableStringBuilder(ac.nickname)
|
||||
if( a.last_notification_error?.isNotEmpty() == true) {
|
||||
if(a.last_notification_error?.isNotEmpty() == true) {
|
||||
sb.append("\n")
|
||||
val start = sb.length
|
||||
sb.append(a.last_notification_error)
|
||||
val end = sb.length
|
||||
sb.setSpan(RelativeSizeSpan(0.7f), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}else if(a.last_subscription_error?.isNotEmpty() == true) {
|
||||
} else if(a.last_subscription_error?.isNotEmpty() == true) {
|
||||
sb.append("\n")
|
||||
val start = sb.length
|
||||
sb.append(a.last_subscription_error)
|
||||
|
@ -171,7 +174,7 @@ object AccountPicker {
|
|||
llAccounts.addView(b)
|
||||
}
|
||||
|
||||
extra_callback(llAccounts,pad_se, pad_tb)
|
||||
extra_callback(llAccounts, pad_se, pad_tb)
|
||||
|
||||
dialog.show()
|
||||
}
|
||||
|
|
|
@ -2,26 +2,23 @@ package jp.juggler.subwaytooter.dialog
|
|||
|
||||
import android.content.Context
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.util.EmptyCallback
|
||||
import java.util.*
|
||||
|
||||
class ActionsDialog {
|
||||
|
||||
private val action_list = ArrayList<Action>()
|
||||
|
||||
private class Action(val caption : CharSequence, val r : EmptyCallback)
|
||||
private class Action(val caption : CharSequence, val action : () -> Unit)
|
||||
|
||||
fun addAction(caption : CharSequence, r : EmptyCallback) : ActionsDialog {
|
||||
fun addAction(caption : CharSequence, action : () -> Unit) : ActionsDialog {
|
||||
|
||||
action_list.add(Action(caption, r))
|
||||
action_list.add(Action(caption, action))
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
fun show(context : Context, title : CharSequence? = null ) : ActionsDialog {
|
||||
fun show(context : Context, title : CharSequence? = null) : ActionsDialog {
|
||||
val caption_list = arrayOfNulls<CharSequence>(action_list.size)
|
||||
var i = 0
|
||||
val ie = caption_list.size
|
||||
|
@ -33,11 +30,11 @@ class ActionsDialog {
|
|||
.setNegativeButton(R.string.cancel, null)
|
||||
.setItems(caption_list) { _, which ->
|
||||
if(which >= 0 && which < action_list.size) {
|
||||
action_list[which].r()
|
||||
action_list[which].action()
|
||||
}
|
||||
}
|
||||
|
||||
if( title != null && title.isNotEmpty() ) b.setTitle(title)
|
||||
if(title != null && title.isNotEmpty()) b.setTitle(title)
|
||||
|
||||
b.show()
|
||||
|
||||
|
|
|
@ -11,14 +11,14 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import android.widget.*
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.app.Activity
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.util.CustomShare
|
||||
import jp.juggler.subwaytooter.util.cn
|
||||
import jp.juggler.util.*
|
||||
|
||||
class DlgAppPicker(
|
||||
val activity : AppCompatActivity,
|
||||
val activity : Activity,
|
||||
val intent : Intent,
|
||||
val autoSelect : Boolean = false,
|
||||
val filter : (ResolveInfo) -> Boolean = { true },
|
||||
|
@ -26,6 +26,7 @@ class DlgAppPicker(
|
|||
) {
|
||||
|
||||
companion object {
|
||||
|
||||
fun Char.isAlpha() = ('A' <= this && this <= 'Z') || ('a' <= this && this <= 'z')
|
||||
}
|
||||
|
||||
|
@ -63,7 +64,7 @@ class DlgAppPicker(
|
|||
val (label, icon) = CustomShare.getInfo(activity, CustomShare.CN_CLIPBOARD.cn())
|
||||
add(ListItem(icon, label.toString(), CustomShare.CN_CLIPBOARD))
|
||||
}
|
||||
sortWith{ a, b ->
|
||||
sortWith { a, b ->
|
||||
val a1 = a.text.firstOrNull() ?: '\u0000'
|
||||
val b1 = b.text.firstOrNull() ?: '\u0000'
|
||||
when {
|
||||
|
@ -99,10 +100,10 @@ class DlgAppPicker(
|
|||
// returns false if list is empty
|
||||
@SuppressLint("InflateParams")
|
||||
fun show() =
|
||||
if( list.isEmpty()){
|
||||
if(list.isEmpty()) {
|
||||
dialog?.dismissSafe()
|
||||
false
|
||||
}else {
|
||||
} else {
|
||||
dialog?.run {
|
||||
window?.setLayout(
|
||||
WindowManager.LayoutParams.MATCH_PARENT,
|
||||
|
@ -113,7 +114,6 @@ class DlgAppPicker(
|
|||
true
|
||||
}
|
||||
|
||||
|
||||
private inner class MyAdapter : BaseAdapter(), AdapterView.OnItemClickListener {
|
||||
|
||||
override fun getCount() : Int = list.size
|
||||
|
@ -142,6 +142,7 @@ class DlgAppPicker(
|
|||
}
|
||||
|
||||
private inner class MyViewHolder(viewRoot : View) {
|
||||
|
||||
val ivImage : ImageView = viewRoot.findViewById(R.id.ivImage)
|
||||
val tvText : TextView = viewRoot.findViewById(R.id.tvText)
|
||||
var item : ListItem? = null
|
||||
|
@ -155,7 +156,7 @@ class DlgAppPicker(
|
|||
activity,
|
||||
ivImage,
|
||||
R.drawable.ic_question,
|
||||
color = getAttributeColor(activity, R.attr.colorVectorDrawable),
|
||||
color = activity.getAttributeColor(R.attr.colorVectorDrawable),
|
||||
alphaMultiplier = 1f
|
||||
)
|
||||
}
|
||||
|
|
|
@ -9,12 +9,12 @@ import android.widget.CheckBox
|
|||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import jp.juggler.subwaytooter.App1
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.entity.Host
|
||||
import jp.juggler.subwaytooter.api.entity.TootInstance
|
||||
import jp.juggler.subwaytooter.util.DecodeOptions
|
||||
import jp.juggler.subwaytooter.util.LinkHelper
|
||||
import jp.juggler.subwaytooter.util.openCustomTab
|
||||
import jp.juggler.util.neatSpaces
|
||||
import jp.juggler.util.notBlank
|
||||
import jp.juggler.util.showToast
|
||||
|
@ -97,10 +97,10 @@ class DlgCreateAccount(
|
|||
override fun onClick(v : View?) {
|
||||
when(v?.id) {
|
||||
R.id.btnRules ->
|
||||
App1.openCustomTab(activity, "https://$instance/about/more")
|
||||
activity.openCustomTab("https://$instance/about/more")
|
||||
|
||||
R.id.btnTerms ->
|
||||
App1.openCustomTab(activity, "https://$instance/terms")
|
||||
activity.openCustomTab("https://$instance/terms")
|
||||
|
||||
R.id.btnCancel ->
|
||||
dialog.cancel()
|
||||
|
@ -112,16 +112,16 @@ class DlgCreateAccount(
|
|||
|
||||
when {
|
||||
username.isEmpty() ->
|
||||
showToast(activity, true, R.string.username_empty)
|
||||
activity.showToast(true, R.string.username_empty)
|
||||
|
||||
email.isEmpty() ->
|
||||
showToast(activity, true, R.string.email_empty)
|
||||
activity.showToast(true, R.string.email_empty)
|
||||
|
||||
password.isEmpty() ->
|
||||
showToast(activity, true, R.string.password_empty)
|
||||
activity.showToast(true, R.string.password_empty)
|
||||
|
||||
username.contains("/") || username.contains("@") ->
|
||||
showToast(activity, true, R.string.username_not_need_atmark)
|
||||
activity.showToast(true, R.string.username_not_need_atmark)
|
||||
|
||||
else -> onClickOk(
|
||||
dialog,
|
||||
|
|
|
@ -23,7 +23,8 @@ import kotlinx.coroutines.*
|
|||
class DlgDraftPicker : AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener,
|
||||
DialogInterface.OnDismissListener {
|
||||
|
||||
companion object{
|
||||
companion object {
|
||||
|
||||
private val log = LogCategory("DlgDraftPicker")
|
||||
}
|
||||
|
||||
|
@ -55,7 +56,7 @@ class DlgDraftPicker : AdapterView.OnItemClickListener, AdapterView.OnItemLongCl
|
|||
|
||||
val draft = getPostDraft(position)
|
||||
if(draft != null) {
|
||||
showToast(activity, false, R.string.draft_deleted)
|
||||
activity.showToast(false, R.string.draft_deleted)
|
||||
draft.delete()
|
||||
reload()
|
||||
return true
|
||||
|
@ -104,16 +105,16 @@ class DlgDraftPicker : AdapterView.OnItemClickListener, AdapterView.OnItemLongCl
|
|||
// cancel old task
|
||||
task?.cancel()
|
||||
|
||||
task = GlobalScope.launch(Dispatchers.Main){
|
||||
val cursor =try {
|
||||
task = GlobalScope.launch(Dispatchers.Main) {
|
||||
val cursor = try {
|
||||
withContext(Dispatchers.IO) {
|
||||
PostDraft.createCursor()
|
||||
} ?: error("cursor is null")
|
||||
}catch(ex:CancellationException) {
|
||||
} catch(ex : CancellationException) {
|
||||
return@launch
|
||||
}catch(ex:Throwable){
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(activity,ex, "failed to loading drafts.")
|
||||
activity.showToast(ex, "failed to loading drafts.")
|
||||
return@launch
|
||||
}
|
||||
|
||||
|
@ -136,6 +137,7 @@ class DlgDraftPicker : AdapterView.OnItemClickListener, AdapterView.OnItemLongCl
|
|||
}
|
||||
|
||||
private inner class MyViewHolder(view : View) {
|
||||
|
||||
val tvTime : TextView
|
||||
val tvText : TextView
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ class DlgFocusPoint(val activity : Activity, val attachment : TootAttachment) :
|
|||
View.OnClickListener {
|
||||
|
||||
companion object {
|
||||
|
||||
val log = LogCategory("DlgFocusPoint")
|
||||
}
|
||||
|
||||
|
@ -57,7 +58,7 @@ class DlgFocusPoint(val activity : Activity, val attachment : TootAttachment) :
|
|||
fun show() {
|
||||
val url = attachment.preview_url
|
||||
if(url == null) {
|
||||
showToast(activity, false, "missing image url")
|
||||
activity.showToast(false, "missing image url")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -65,7 +66,10 @@ class DlgFocusPoint(val activity : Activity, val attachment : TootAttachment) :
|
|||
|
||||
private val options = BitmapFactory.Options()
|
||||
|
||||
private fun decodeBitmap(data : ByteArray, pixel_max : Int) : Bitmap? {
|
||||
private fun decodeBitmap(
|
||||
data : ByteArray,
|
||||
@Suppress("SameParameterValue") pixel_max : Int
|
||||
) : Bitmap? {
|
||||
options.inJustDecodeBounds = true
|
||||
options.inScaled = false
|
||||
options.outWidth = 0
|
||||
|
@ -92,7 +96,7 @@ class DlgFocusPoint(val activity : Activity, val attachment : TootAttachment) :
|
|||
|
||||
override fun background(client : TootApiClient) : TootApiResult? {
|
||||
try {
|
||||
val(result,data) = client.getHttpBytes(url)
|
||||
val (result, data) = client.getHttpBytes(url)
|
||||
data ?: return result
|
||||
bitmap = decodeBitmap(data, 1024)
|
||||
if(bitmap == null) return TootApiResult("image decode failed.")
|
||||
|
@ -105,7 +109,7 @@ class DlgFocusPoint(val activity : Activity, val attachment : TootAttachment) :
|
|||
override fun handleResult(result : TootApiResult?) {
|
||||
val bitmap = this.bitmap
|
||||
if(bitmap == null) {
|
||||
showToast(activity, true, result?.error ?: "?")
|
||||
activity.showToast(true, result?.error ?: "?")
|
||||
dialog.dismissSafe()
|
||||
return
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ class DlgListMember(
|
|||
this.list_owner = a
|
||||
if(a == null) {
|
||||
btnListOwner.setText(R.string.not_selected)
|
||||
btnListOwner.setTextColor(getAttributeColor(activity, android.R.attr.textColorPrimary))
|
||||
btnListOwner.setTextColor(activity.getAttributeColor( android.R.attr.textColorPrimary))
|
||||
btnListOwner.setBackgroundResource(R.drawable.btn_bg_transparent_round6dp)
|
||||
//
|
||||
|
||||
|
@ -148,7 +148,7 @@ class DlgListMember(
|
|||
btnListOwner.setBackgroundResource(R.drawable.btn_bg_transparent_round6dp)
|
||||
}
|
||||
btnListOwner.textColor = ac.color_fg.notZero()
|
||||
?: getAttributeColor(activity, android.R.attr.textColorPrimary)
|
||||
?: activity.getAttributeColor( android.R.attr.textColorPrimary)
|
||||
}
|
||||
|
||||
loadLists()
|
||||
|
@ -175,7 +175,7 @@ class DlgListMember(
|
|||
val (r1, ar) = client.syncAccountByAcct(list_owner, target_user_full_acct)
|
||||
r1 ?: return null // cancelled.
|
||||
val local_who = ar?.get() // may null
|
||||
if(local_who == null) showToast(activity, true, r1.error)
|
||||
if(local_who == null) activity.showToast( true, r1.error)
|
||||
|
||||
this@DlgListMember.local_who = local_who
|
||||
|
||||
|
@ -241,7 +241,7 @@ class DlgListMember(
|
|||
|
||||
val error = result.error
|
||||
if(error?.isNotEmpty() == true) {
|
||||
showToast(activity, true, result.error)
|
||||
activity.showToast( true, result.error)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -268,14 +268,14 @@ class DlgListMember(
|
|||
callback = object : DlgTextInput.Callback {
|
||||
|
||||
override fun onEmptyError() {
|
||||
showToast(activity, false, R.string.list_name_empty)
|
||||
activity.showToast( false, R.string.list_name_empty)
|
||||
}
|
||||
|
||||
override fun onOK(dialog : Dialog, text : String) {
|
||||
val list_owner = this@DlgListMember.list_owner
|
||||
|
||||
if(list_owner == null) {
|
||||
showToast(activity, false, "list owner is not selected.")
|
||||
activity.showToast( false, "list owner is not selected.")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -376,14 +376,14 @@ class DlgListMember(
|
|||
|
||||
val list_owner = this@DlgListMember.list_owner
|
||||
if(list_owner == null) {
|
||||
showToast(activity, false, "list owner is not selected")
|
||||
activity.showToast( false, "list owner is not selected")
|
||||
revokeCheckedChanged(isChecked)
|
||||
return
|
||||
}
|
||||
|
||||
val local_who = this@DlgListMember.local_who
|
||||
if(local_who == null) {
|
||||
showToast(activity, false, "target user is not synchronized")
|
||||
activity.showToast( false, "target user is not synchronized")
|
||||
revokeCheckedChanged(isChecked)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -5,11 +5,9 @@ import android.app.Activity
|
|||
import android.app.Dialog
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.PictureDrawable
|
||||
import android.os.Build
|
||||
import android.util.SparseArray
|
||||
import android.view.*
|
||||
import android.widget.*
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import com.astuetz.PagerSlidingTabStrip
|
||||
import com.bumptech.glide.Glide
|
||||
|
@ -44,6 +42,7 @@ class EmojiPicker(
|
|||
|
||||
class SkinTone(val suffix_list : Array<out String>) {
|
||||
companion object {
|
||||
|
||||
fun create(vararg suffix_list : String) : SkinTone {
|
||||
return SkinTone(suffix_list)
|
||||
}
|
||||
|
@ -269,8 +268,7 @@ class EmojiPicker(
|
|||
|
||||
setTypeface(typeface, Typeface.BOLD)
|
||||
|
||||
textColor =
|
||||
getAttributeColor(this@EmojiPicker.activity, R.attr.colorContentText)
|
||||
textColor = this@EmojiPicker.activity.getAttributeColor(R.attr.colorContentText)
|
||||
textSize = 16f // SP単位
|
||||
|
||||
text = when(val name = it.key) {
|
||||
|
@ -542,7 +540,7 @@ class EmojiPicker(
|
|||
|
||||
val pref = App1.pref
|
||||
|
||||
if( Pref.bpEmojiPickerCloseOnSelected(pref))
|
||||
if(Pref.bpEmojiPickerCloseOnSelected(pref))
|
||||
dialog.dismissSafe()
|
||||
|
||||
// Recentをロード(他インスタンスの絵文字を含む)
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.net.IDN
|
|||
import java.util.*
|
||||
|
||||
object LoginForm {
|
||||
|
||||
private val log = LogCategory("LoginForm")
|
||||
|
||||
private class StringArray : ArrayList<String>()
|
||||
|
@ -107,10 +108,10 @@ object LoginForm {
|
|||
when {
|
||||
|
||||
instance.isEmpty() ->
|
||||
showToast(activity, true, R.string.instance_not_specified)
|
||||
activity.showToast(true, R.string.instance_not_specified)
|
||||
|
||||
instance.contains("/") || instance.contains("@") ->
|
||||
showToast(activity, true, R.string.instance_not_need_slash)
|
||||
activity.showToast(true, R.string.instance_not_need_slash)
|
||||
|
||||
else -> {
|
||||
val actionPos = spAction.selectedItemPosition
|
||||
|
@ -124,7 +125,7 @@ object LoginForm {
|
|||
}
|
||||
view.findViewById<View>(R.id.btnCancel).setOnClickListener { dialog.cancel() }
|
||||
|
||||
val instance_list = HashSet<String>().apply{
|
||||
val instance_list = HashSet<String>().apply {
|
||||
try {
|
||||
activity.resources.openRawResource(R.raw.server_list).use { inStream ->
|
||||
val br = BufferedReader(InputStreamReader(inStream, "UTF-8"))
|
||||
|
@ -133,8 +134,8 @@ object LoginForm {
|
|||
br.readLine()?.trim { it <= ' ' }?.toLowerCase(Locale.JAPAN) ?: break
|
||||
if(s.isEmpty()) continue
|
||||
add(s)
|
||||
add(IDN.toASCII(s,IDN.ALLOW_UNASSIGNED))
|
||||
add(IDN.toUnicode(s,IDN.ALLOW_UNASSIGNED))
|
||||
add(IDN.toASCII(s, IDN.ALLOW_UNASSIGNED))
|
||||
add(IDN.toUnicode(s, IDN.ALLOW_UNASSIGNED))
|
||||
}
|
||||
}
|
||||
} catch(ex : Throwable) {
|
||||
|
|
|
@ -23,35 +23,35 @@ object ReportForm {
|
|||
access_info : SavedAccount,
|
||||
who : TootAccount,
|
||||
status : TootStatus?,
|
||||
onClickOk : (dialog : Dialog, comment : String,forward:Boolean) -> Unit
|
||||
onClickOk : (dialog : Dialog, comment : String, forward : Boolean) -> Unit
|
||||
) {
|
||||
val view = activity.layoutInflater.inflate(R.layout.dlg_report_user, null, false)
|
||||
|
||||
val tvUser :TextView = view.findViewById(R.id.tvUser)
|
||||
val tvStatusCaption :TextView = view.findViewById(R.id.tvStatusCaption)
|
||||
val tvStatus :TextView = view.findViewById(R.id.tvStatus)
|
||||
val etComment :EditText = view.findViewById(R.id.etComment)
|
||||
val tvUser : TextView = view.findViewById(R.id.tvUser)
|
||||
val tvStatusCaption : TextView = view.findViewById(R.id.tvStatusCaption)
|
||||
val tvStatus : TextView = view.findViewById(R.id.tvStatus)
|
||||
val etComment : EditText = view.findViewById(R.id.etComment)
|
||||
|
||||
val cbForward : CheckBox = view.findViewById(R.id.cbForward)
|
||||
val tvForwardDesc:TextView = view.findViewById(R.id.tvForwardDesc)
|
||||
val canForward = !access_info.matchHost( who)
|
||||
val tvForwardDesc : TextView = view.findViewById(R.id.tvForwardDesc)
|
||||
val canForward = ! access_info.matchHost(who)
|
||||
|
||||
cbForward.isChecked = false
|
||||
if(!canForward){
|
||||
if(! canForward) {
|
||||
cbForward.visibility = View.GONE
|
||||
tvForwardDesc.visibility = View.GONE
|
||||
}else{
|
||||
} else {
|
||||
cbForward.visibility = View.VISIBLE
|
||||
tvForwardDesc.visibility = View.VISIBLE
|
||||
cbForward.text = activity.getString(R.string.report_forward_to,who.apDomain.pretty)
|
||||
cbForward.text = activity.getString(R.string.report_forward_to, who.apDomain.pretty)
|
||||
}
|
||||
|
||||
tvUser.text = who.acct.pretty
|
||||
|
||||
if( status == null){
|
||||
if(status == null) {
|
||||
tvStatusCaption.visibility = View.GONE
|
||||
tvStatus.visibility = View.GONE
|
||||
}else{
|
||||
} else {
|
||||
tvStatus.text = status.decoded_content
|
||||
}
|
||||
|
||||
|
@ -60,11 +60,11 @@ object ReportForm {
|
|||
view.findViewById<View>(R.id.btnOk).setOnClickListener(View.OnClickListener {
|
||||
val comment = etComment.text.toString().trim()
|
||||
if(comment.isEmpty()) {
|
||||
showToast(activity, true, R.string.comment_empty)
|
||||
activity.showToast(true, R.string.comment_empty)
|
||||
return@OnClickListener
|
||||
}
|
||||
|
||||
onClickOk(dialog, comment,cbForward.isChecked)
|
||||
onClickOk(dialog, comment, cbForward.isChecked)
|
||||
})
|
||||
view.findViewById<View>(R.id.btnCancel).setOnClickListener { dialog.cancel() }
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ class SavedAccount(
|
|||
val db_id : Long,
|
||||
acctArg : String,
|
||||
apiHostArg : String? = null,
|
||||
apDomainArg : String? = null,
|
||||
apDomainArg : String? = null,
|
||||
var token_info : JsonObject? = null,
|
||||
var loginAccount : TootAccount? = null, // 疑似アカウントではnull
|
||||
override val misskeyVersion : Int = 0
|
||||
|
@ -74,14 +74,13 @@ class SavedAccount(
|
|||
var last_subscription_error : String? = null
|
||||
var last_push_endpoint : String? = null
|
||||
|
||||
|
||||
init {
|
||||
val tmpAcct = Acct.parse(acctArg)
|
||||
this.username = tmpAcct.username
|
||||
if(username.isEmpty()) throw RuntimeException("missing username in acct")
|
||||
|
||||
val tmpApiHost = apiHostArg?.notEmpty()?.let{ Host.parse(it)}
|
||||
val tmpApDomain = apDomainArg?.notEmpty()?.let{ Host.parse(it)}
|
||||
|
||||
val tmpApiHost = apiHostArg?.notEmpty()?.let { Host.parse(it) }
|
||||
val tmpApDomain = apDomainArg?.notEmpty()?.let { Host.parse(it) }
|
||||
|
||||
this.apiHost = tmpApiHost ?: tmpApDomain ?: tmpAcct.host ?: error("missing apiHost")
|
||||
this.apDomain = tmpApDomain ?: tmpApiHost ?: tmpAcct.host ?: error("missing apDomain")
|
||||
|
@ -106,7 +105,7 @@ class SavedAccount(
|
|||
context,
|
||||
LinkHelper.create(
|
||||
apiHostArg = this@SavedAccount.apiHost,
|
||||
apDomainArg = this@SavedAccount.apDomain,
|
||||
apDomainArg = this@SavedAccount.apDomain,
|
||||
misskeyVersion = misskeyVersion
|
||||
)
|
||||
).account(jsonAccount)
|
||||
|
@ -292,20 +291,19 @@ class SavedAccount(
|
|||
return acct.host == null || acct.host == this.apDomain
|
||||
}
|
||||
|
||||
|
||||
// fun isRemoteUser(acct : String) : Boolean {
|
||||
// return ! isLocalUser(acct)
|
||||
// }
|
||||
|
||||
fun isMe(who : TootAccount?) : Boolean = isMe(who?.acct)
|
||||
// fun isMe(who_acct : String) : Boolean = isMe(Acct.parse(who_acct))
|
||||
|
||||
fun isMe(who_acct : Acct?):Boolean{
|
||||
who_acct?:return false
|
||||
if( who_acct.username != this.acct.username) return false
|
||||
// fun isMe(who_acct : String) : Boolean = isMe(Acct.parse(who_acct))
|
||||
|
||||
fun isMe(who_acct : Acct?) : Boolean {
|
||||
who_acct ?: return false
|
||||
if(who_acct.username != this.acct.username) return false
|
||||
return who_acct.host == null || who_acct.host == this.acct.host
|
||||
}
|
||||
|
||||
|
||||
fun supplyBaseUrl(url : String?) : String? {
|
||||
return when {
|
||||
url == null || url.isEmpty() -> return null
|
||||
|
@ -317,6 +315,7 @@ class SavedAccount(
|
|||
fun isNicoru(account : TootAccount?) : Boolean = account?.apiHost == Host.FRIENDS_NICO
|
||||
|
||||
companion object : TableCompanion {
|
||||
|
||||
private val log = LogCategory("SavedAccount")
|
||||
|
||||
const val table = "access_info"
|
||||
|
@ -470,7 +469,7 @@ class SavedAccount(
|
|||
|
||||
// スキーマ57から
|
||||
+ ",$COL_NOTIFICATION_POST integer default 1"
|
||||
|
||||
|
||||
+ ")"
|
||||
)
|
||||
db.execSQL("create index if not exists ${table}_user on ${table}(u)")
|
||||
|
@ -604,7 +603,7 @@ class SavedAccount(
|
|||
log.trace(ex)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(oldVersion < 33 && newVersion >= 33) {
|
||||
try {
|
||||
db.execSQL("alter table $table add column $COL_NOTIFICATION_REACTION integer default 1")
|
||||
|
@ -617,7 +616,7 @@ class SavedAccount(
|
|||
log.trace(ex)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(oldVersion < 38 && newVersion >= 38) {
|
||||
try {
|
||||
db.execSQL("alter table $table add column $COL_DEFAULT_SENSITIVE integer default 0")
|
||||
|
@ -716,7 +715,7 @@ class SavedAccount(
|
|||
fun insert(
|
||||
acct : String,
|
||||
host : String,
|
||||
domain:String?,
|
||||
domain : String?,
|
||||
account : JsonObject,
|
||||
token : JsonObject,
|
||||
misskeyVersion : Int = 0
|
||||
|
@ -725,7 +724,7 @@ class SavedAccount(
|
|||
val cv = ContentValues()
|
||||
cv.put(COL_USER, acct)
|
||||
cv.put(COL_HOST, host)
|
||||
cv.putOrNull(COL_DOMAIN,domain)
|
||||
cv.putOrNull(COL_DOMAIN, domain)
|
||||
cv.put(COL_ACCOUNT, account.toString())
|
||||
cv.put(COL_TOKEN, token.toString())
|
||||
cv.put(COL_MISSKEY_VERSION, misskeyVersion)
|
||||
|
@ -792,7 +791,7 @@ class SavedAccount(
|
|||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
log.e(ex, "loadAccountList failed.")
|
||||
showToast(context, true, ex.withCaption("(SubwayTooter) broken in-app database?"))
|
||||
context.showToast(true, ex.withCaption("(SubwayTooter) broken in-app database?"))
|
||||
}
|
||||
|
||||
return result
|
||||
|
@ -893,47 +892,47 @@ class SavedAccount(
|
|||
return 0L
|
||||
}
|
||||
|
||||
fun isNicoru(acct:Acct) : Boolean {
|
||||
fun isNicoru(acct : Acct) : Boolean {
|
||||
return acct.host == Host.FRIENDS_NICO
|
||||
}
|
||||
|
||||
// private fun charAtLower(src : CharSequence, pos : Int) : Char {
|
||||
// val c = src[pos]
|
||||
// return if(c >= 'a' && c <= 'z') c - ('a' - 'A') else c
|
||||
// }
|
||||
//
|
||||
// @Suppress("SameParameterValue")
|
||||
// private fun host_match(
|
||||
// a : CharSequence,
|
||||
// a_startArg : Int,
|
||||
// b : CharSequence,
|
||||
// b_startArg : Int
|
||||
// ) : Boolean {
|
||||
// var a_start = a_startArg
|
||||
// var b_start = b_startArg
|
||||
//
|
||||
// val a_end = a.length
|
||||
// val b_end = b.length
|
||||
//
|
||||
// var a_remain = a_end - a_start
|
||||
// val b_remain = b_end - b_start
|
||||
//
|
||||
// // 文字数が違う
|
||||
// if(a_remain != b_remain) return false
|
||||
//
|
||||
// // 文字数がゼロ
|
||||
// if(a_remain <= 0) return true
|
||||
//
|
||||
// // 末尾の文字が違う
|
||||
// if(charAtLower(a, a_end - 1) != charAtLower(b, b_end - 1)) return false
|
||||
//
|
||||
// // 先頭からチェック
|
||||
// while(a_remain -- > 0) {
|
||||
// if(charAtLower(a, a_start ++) != charAtLower(b, b_start ++)) return false
|
||||
// }
|
||||
//
|
||||
// return true
|
||||
// }
|
||||
// private fun charAtLower(src : CharSequence, pos : Int) : Char {
|
||||
// val c = src[pos]
|
||||
// return if(c >= 'a' && c <= 'z') c - ('a' - 'A') else c
|
||||
// }
|
||||
//
|
||||
// @Suppress("SameParameterValue")
|
||||
// private fun host_match(
|
||||
// a : CharSequence,
|
||||
// a_startArg : Int,
|
||||
// b : CharSequence,
|
||||
// b_startArg : Int
|
||||
// ) : Boolean {
|
||||
// var a_start = a_startArg
|
||||
// var b_start = b_startArg
|
||||
//
|
||||
// val a_end = a.length
|
||||
// val b_end = b.length
|
||||
//
|
||||
// var a_remain = a_end - a_start
|
||||
// val b_remain = b_end - b_start
|
||||
//
|
||||
// // 文字数が違う
|
||||
// if(a_remain != b_remain) return false
|
||||
//
|
||||
// // 文字数がゼロ
|
||||
// if(a_remain <= 0) return true
|
||||
//
|
||||
// // 末尾の文字が違う
|
||||
// if(charAtLower(a, a_end - 1) != charAtLower(b, b_end - 1)) return false
|
||||
//
|
||||
// // 先頭からチェック
|
||||
// while(a_remain -- > 0) {
|
||||
// if(charAtLower(a, a_start ++) != charAtLower(b, b_start ++)) return false
|
||||
// }
|
||||
//
|
||||
// return true
|
||||
// }
|
||||
|
||||
private val account_comparator = Comparator<SavedAccount> { a, b ->
|
||||
var i : Int
|
||||
|
@ -1065,7 +1064,7 @@ class SavedAccount(
|
|||
|
||||
fun updateNotificationError(text : String?) {
|
||||
this.last_notification_error = text
|
||||
if(db_id != INVALID_DB_ID){
|
||||
if(db_id != INVALID_DB_ID) {
|
||||
val cv = ContentValues()
|
||||
when(text) {
|
||||
null -> cv.putNull(COL_LAST_NOTIFICATION_ERROR)
|
||||
|
@ -1077,7 +1076,7 @@ class SavedAccount(
|
|||
|
||||
fun updateSubscriptionError(text : String?) {
|
||||
this.last_subscription_error = text
|
||||
if(db_id != INVALID_DB_ID){
|
||||
if(db_id != INVALID_DB_ID) {
|
||||
val cv = ContentValues()
|
||||
when(text) {
|
||||
null -> cv.putNull(COL_LAST_SUBSCRIPTION_ERROR)
|
||||
|
@ -1089,7 +1088,7 @@ class SavedAccount(
|
|||
|
||||
fun updateLastPushEndpoint(text : String?) {
|
||||
this.last_push_endpoint = text
|
||||
if(db_id != INVALID_DB_ID){
|
||||
if(db_id != INVALID_DB_ID) {
|
||||
val cv = ContentValues()
|
||||
when(text) {
|
||||
null -> cv.putNull(COL_LAST_PUSH_ENDPOINT)
|
||||
|
@ -1107,5 +1106,4 @@ class SavedAccount(
|
|||
|
||||
override fun hashCode() : Int = acct.hashCode()
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
package jp.juggler.subwaytooter.util
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.app.Activity
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import jp.juggler.subwaytooter.Pref
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.entity.TootAttachment
|
||||
import jp.juggler.subwaytooter.dialog.DlgAppPicker
|
||||
import jp.juggler.subwaytooter.pref
|
||||
import jp.juggler.util.*
|
||||
|
||||
private val log = LogCategory("AppOpener")
|
||||
|
||||
// returns true if activity is opened.
|
||||
// returns false if fallback required
|
||||
private fun Activity.startActivityExcludeMyApp(
|
||||
intent : Intent,
|
||||
startAnimationBundle : Bundle? = null
|
||||
) : Boolean {
|
||||
try {
|
||||
val pm = packageManager !!
|
||||
val myName = packageName
|
||||
|
||||
val filter : (ResolveInfo) -> Boolean = {
|
||||
it.activityInfo.packageName != myName &&
|
||||
it.activityInfo.exported &&
|
||||
- 1 == it.activityInfo.packageName.indexOf("com.huawei.android.internal")
|
||||
}
|
||||
|
||||
// resolveActivity がこのアプリ以外のActivityを返すなら、それがベストなんだろう
|
||||
// ただしAndroid M以降はMATCH_DEFAULT_ONLYだと「常時」が設定されてないとnullを返す
|
||||
val ri = pm.resolveActivity(
|
||||
intent,
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PackageManager.MATCH_ALL
|
||||
} else {
|
||||
PackageManager.MATCH_DEFAULT_ONLY
|
||||
}
|
||||
)?.takeIf(filter)
|
||||
|
||||
if(ri != null) {
|
||||
intent.setClassName(ri.activityInfo.packageName, ri.activityInfo.name)
|
||||
startActivity(intent, startAnimationBundle)
|
||||
return true
|
||||
}
|
||||
|
||||
return DlgAppPicker(
|
||||
this,
|
||||
intent,
|
||||
autoSelect = true,
|
||||
filter = filter
|
||||
) {
|
||||
try {
|
||||
intent.component = it.cn()
|
||||
startActivity(intent, startAnimationBundle)
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(ex, "can't open. ${intent.data}")
|
||||
}
|
||||
}.show()
|
||||
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(ex, "can't open. ${intent.data}")
|
||||
return true // fallback not required in this case
|
||||
}
|
||||
}
|
||||
|
||||
fun Activity.openBrowser(uri : Uri?) {
|
||||
if(uri != null) {
|
||||
val rv = startActivityExcludeMyApp(Intent(Intent.ACTION_VIEW, uri))
|
||||
if(! rv) showToast(true, "there is no app that can open $uri")
|
||||
}
|
||||
}
|
||||
|
||||
fun Activity.openBrowser(url : String?) = openBrowser(url.mayUri())
|
||||
|
||||
// ubway Tooterの「アプリ設定/挙動/リンクを開く際にCustom Tabsを使わない」をONにして
|
||||
// 投稿のコンテキストメニューの「トゥートへのアクション/Webページを開く」「ユーザへのアクション/Webページを開く」を使うと
|
||||
// 投げたインテントをST自身が受け取って「次のアカウントから開く」ダイアログが出て
|
||||
// 「Webページを開く」をまた押すと無限ループしてダイアログの影が徐々に濃くなりそのうち壊れる
|
||||
// これを避けるには、投稿やトゥートを開く際に bpDontUseCustomTabs がオンならST以外のアプリを列挙したアプリ選択ダイアログを出すしかない
|
||||
fun Activity.openCustomTabOrBrowser(url : String?) {
|
||||
url ?: return
|
||||
if(! Pref.bpDontUseCustomTabs(pref())) {
|
||||
openCustomTab(url)
|
||||
} else {
|
||||
openBrowser(url)
|
||||
}
|
||||
}
|
||||
|
||||
// Chrome Custom Tab を開く
|
||||
fun Activity.openCustomTab(url : String?) {
|
||||
url ?: return
|
||||
|
||||
if(url.isEmpty()) {
|
||||
showToast(false, "URL is empty string.")
|
||||
return
|
||||
}
|
||||
|
||||
val pref = pref()
|
||||
if(Pref.bpDontUseCustomTabs(pref)) {
|
||||
openCustomTabOrBrowser(url)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if(url.startsWith("http") && Pref.bpPriorChrome(pref)) {
|
||||
try {
|
||||
// 初回はChrome指定で試す
|
||||
val customTabsIntent = CustomTabsIntent.Builder()
|
||||
.setToolbarColor(getAttributeColor(R.attr.colorPrimary))
|
||||
.setShowTitle(true)
|
||||
.build()
|
||||
|
||||
val rv = startActivityExcludeMyApp(
|
||||
customTabsIntent.intent.also {
|
||||
it.component = ComponentName(
|
||||
"com.android.chrome",
|
||||
"com.google.android.apps.chrome.Main"
|
||||
)
|
||||
it.data = url.toUri()
|
||||
},
|
||||
customTabsIntent.startAnimationBundle
|
||||
)
|
||||
if(rv) return
|
||||
} catch(ex2 : Throwable) {
|
||||
log.e(ex2, "openChromeTab: missing chrome. retry to other application.")
|
||||
}
|
||||
}
|
||||
|
||||
// Chromeがないようなのでcomponent指定なしでリトライ
|
||||
val customTabsIntent = CustomTabsIntent.Builder()
|
||||
.setToolbarColor(getAttributeColor(R.attr.colorPrimary))
|
||||
.setShowTitle(true)
|
||||
.build()
|
||||
|
||||
val rv = startActivityExcludeMyApp(
|
||||
customTabsIntent.intent.also {
|
||||
it.data = url.toUri()
|
||||
},
|
||||
customTabsIntent.startAnimationBundle
|
||||
)
|
||||
if(! rv) {
|
||||
showToast(true, "the browser app is not installed.")
|
||||
}
|
||||
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
val scheme = url.mayUri()?.scheme ?: url
|
||||
showToast(true, "can't open browser app for %s", scheme)
|
||||
}
|
||||
}
|
||||
|
||||
fun Activity.openCustomTab(ta : TootAttachment) =
|
||||
openCustomTab(ta.getLargeUrl(pref()))
|
|
@ -31,18 +31,6 @@ abstract class AsyncActivity : AppCompatActivity(), CoroutineScope {
|
|||
(job + Dispatchers.Default).cancel()
|
||||
}
|
||||
|
||||
fun showToast(bLong : Boolean, fmt : String?, vararg args : Any) =
|
||||
showToast(this, bLong, fmt, *args)
|
||||
|
||||
fun showToast(ex : Throwable, fmt : String?, vararg args : Any) =
|
||||
showToast(this, ex, fmt, *args)
|
||||
|
||||
fun showToast(bLong : Boolean, string_id : Int, vararg args : Any) =
|
||||
showToast(this, bLong, string_id, *args)
|
||||
|
||||
fun showToast(ex : Throwable, string_id : Int, vararg args : Any) =
|
||||
showToast(this, ex, string_id, *args)
|
||||
|
||||
fun <T : Any?> runWithProgress(
|
||||
caption : String,
|
||||
doInBackground : suspend CoroutineScope.(ProgressDialogEx) -> T,
|
||||
|
@ -79,7 +67,7 @@ abstract class AsyncActivity : AppCompatActivity(), CoroutineScope {
|
|||
}
|
||||
if(result != null) afterProc(result)
|
||||
} catch(ex : Throwable) {
|
||||
showToast(this@AsyncActivity, ex, "$caption failed.")
|
||||
showToast(ex, "$caption failed.")
|
||||
} finally {
|
||||
progress.dismissSafe()
|
||||
try {
|
||||
|
|
|
@ -71,7 +71,7 @@ object CustomShare {
|
|||
label =
|
||||
"${context.getString(R.string.copy_to_clipboard)}(${context.getString(R.string.app_name)})"
|
||||
icon = ContextCompat.getDrawable(context, R.drawable.ic_copy)?.mutate()?.apply {
|
||||
setTint(getAttributeColor(context, R.attr.colorVectorDrawable))
|
||||
setTint(context.getAttributeColor(R.attr.colorVectorDrawable))
|
||||
setTintMode(PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
} else {
|
||||
|
@ -105,7 +105,7 @@ object CustomShare {
|
|||
// convert "pkgName/className" string to ComponentName object.
|
||||
val cn = getCustomShareComponentName(App1.pref, target)
|
||||
if(cn == null) {
|
||||
showToast(context, true, R.string.custom_share_app_not_found)
|
||||
context.showToast(true, R.string.custom_share_app_not_found)
|
||||
return
|
||||
}
|
||||
val cnStr = "${cn.packageName}/${cn.className}"
|
||||
|
@ -113,9 +113,9 @@ object CustomShare {
|
|||
try {
|
||||
val cm : ClipboardManager = systemService(context) !!
|
||||
cm.setPrimaryClip(ClipData.newPlainText("", text))
|
||||
showToast(context, false, R.string.copied_to_clipboard)
|
||||
context.showToast(false, R.string.copied_to_clipboard)
|
||||
} catch(ex : Throwable) {
|
||||
showToast(context, ex, "copy to clipboard failed.")
|
||||
context.showToast(ex, "copy to clipboard failed.")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -128,10 +128,10 @@ object CustomShare {
|
|||
context.startActivity(intent)
|
||||
} catch(ex : ActivityNotFoundException) {
|
||||
log.trace(ex)
|
||||
showToast(context, true, R.string.custom_share_app_not_found)
|
||||
context.showToast(true, R.string.custom_share_app_not_found)
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(context, ex, "invoke() failed.")
|
||||
context.showToast(ex, "invoke() failed.")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ object CustomShare {
|
|||
// convert "pkgName/className" string to ComponentName object.
|
||||
val cn = getCustomShareComponentName(App1.pref, target)
|
||||
if(cn == null) {
|
||||
showToast(context, true, R.string.custom_share_app_not_found)
|
||||
context.showToast(true, R.string.custom_share_app_not_found)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ object CustomShare {
|
|||
invoke(context, sv, target)
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(context, ex, "invoke() failed.")
|
||||
context.showToast(ex, "invoke() failed.")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import jp.juggler.subwaytooter.App1
|
|||
import jp.juggler.subwaytooter.Pref
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.entity.CustomEmoji
|
||||
import jp.juggler.subwaytooter.pref
|
||||
import jp.juggler.subwaytooter.span.EmojiImageSpan
|
||||
import jp.juggler.subwaytooter.span.HighlightSpan
|
||||
import jp.juggler.subwaytooter.span.NetworkEmojiSpan
|
||||
|
@ -356,7 +357,7 @@ object EmojiDecoder {
|
|||
|
||||
val useEmojioneShortcode = when(val context = options.context) {
|
||||
null -> false
|
||||
else -> Pref.bpEmojioneShortcode( Pref.pref(context))
|
||||
else -> Pref.bpEmojioneShortcode( context.pref())
|
||||
}
|
||||
|
||||
splitShortCode(s, callback = object : ShortCodeSplitterCallback {
|
||||
|
|
|
@ -14,7 +14,6 @@ import android.widget.LinearLayout
|
|||
import android.widget.PopupWindow
|
||||
import androidx.core.content.ContextCompat
|
||||
import jp.juggler.subwaytooter.App1
|
||||
import jp.juggler.subwaytooter.Pref
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.entity.Acct
|
||||
import jp.juggler.subwaytooter.view.MyEditText
|
||||
|
@ -47,7 +46,7 @@ internal class PopupAutoCompleteAcct(
|
|||
private val popup_width : Int
|
||||
val handler : Handler
|
||||
|
||||
private val pref : SharedPreferences = Pref.pref(activity)
|
||||
private val pref : SharedPreferences = App1.pref
|
||||
|
||||
private var popup_rows : Int = 0
|
||||
|
||||
|
@ -98,7 +97,7 @@ internal class PopupAutoCompleteAcct(
|
|||
run {
|
||||
val v = activity.layoutInflater
|
||||
.inflate(R.layout.lv_spinner_dropdown, llItems, false) as CheckedTextView
|
||||
v.setTextColor(getAttributeColor(activity, android.R.attr.textColorPrimary))
|
||||
v.setTextColor(activity.getAttributeColor(android.R.attr.textColorPrimary))
|
||||
v.setText(R.string.close)
|
||||
v.setOnClickListener { acct_popup.dismiss() }
|
||||
llItems.addView(v)
|
||||
|
@ -108,7 +107,7 @@ internal class PopupAutoCompleteAcct(
|
|||
if(picker_caption != null && picker_callback != null) {
|
||||
val v = activity.layoutInflater
|
||||
.inflate(R.layout.lv_spinner_dropdown, llItems, false) as CheckedTextView
|
||||
v.setTextColor(getAttributeColor(activity, android.R.attr.textColorPrimary))
|
||||
v.setTextColor(activity.getAttributeColor(android.R.attr.textColorPrimary))
|
||||
v.text = picker_caption
|
||||
v.setOnClickListener {
|
||||
acct_popup.dismiss()
|
||||
|
@ -126,7 +125,7 @@ internal class PopupAutoCompleteAcct(
|
|||
val acct = acct_list[i]
|
||||
val v = activity.layoutInflater
|
||||
.inflate(R.layout.lv_spinner_dropdown, llItems, false) as CheckedTextView
|
||||
v.setTextColor(getAttributeColor(activity, android.R.attr.textColorPrimary))
|
||||
v.setTextColor(activity.getAttributeColor(android.R.attr.textColorPrimary))
|
||||
v.text = acct
|
||||
if(acct is Spannable) {
|
||||
NetworkEmojiInvalidator(handler, v).register(acct)
|
||||
|
|
|
@ -38,6 +38,7 @@ class PostHelper(
|
|||
) {
|
||||
|
||||
companion object {
|
||||
|
||||
private val log = LogCategory("PostHelper")
|
||||
|
||||
private val reCharsNotEmoji = "[^0-9A-Za-z_-]".asciiPattern()
|
||||
|
@ -47,6 +48,7 @@ class PostHelper(
|
|||
}
|
||||
|
||||
interface PostCompleteCallback {
|
||||
|
||||
fun onPostComplete(target_account : SavedAccount, status : TootStatus)
|
||||
fun onScheduledPostComplete(target_account : SavedAccount)
|
||||
}
|
||||
|
@ -110,14 +112,14 @@ class PostHelper(
|
|||
val hasAttachment = attachment_list?.isNotEmpty() ?: false
|
||||
|
||||
if(! hasAttachment && content.isEmpty()) {
|
||||
showToast(activity, true, R.string.post_error_contents_empty)
|
||||
activity.showToast(true, R.string.post_error_contents_empty)
|
||||
return
|
||||
}
|
||||
|
||||
// nullはCWチェックなしを示す
|
||||
// nullじゃなくてカラならエラー
|
||||
if(spoiler_text != null && spoiler_text.isEmpty()) {
|
||||
showToast(activity, true, R.string.post_error_contents_warning_empty)
|
||||
activity.showToast(true, R.string.post_error_contents_warning_empty)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -134,19 +136,19 @@ class PostHelper(
|
|||
|
||||
if(item.isEmpty()) {
|
||||
if(n < 2) {
|
||||
showToast(activity, true, R.string.enquete_item_is_empty, n + 1)
|
||||
activity.showToast(true, R.string.enquete_item_is_empty, n + 1)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
val code_count = item.codePointCount(0, item.length)
|
||||
if(code_count > choice_max_chars) {
|
||||
val over = code_count - choice_max_chars
|
||||
showToast(activity, true, R.string.enquete_item_too_long, n + 1, over)
|
||||
activity.showToast(true, R.string.enquete_item_too_long, n + 1, over)
|
||||
return
|
||||
} else if(n > 0) {
|
||||
for(i in 0 until n) {
|
||||
if(item == enquete_items[i]) {
|
||||
showToast(activity, true, R.string.enquete_item_duplicate, n + 1)
|
||||
activity.showToast(true, R.string.enquete_item_duplicate, n + 1)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -278,7 +280,7 @@ class PostHelper(
|
|||
// 確認を終えたらボタン連打判定
|
||||
|
||||
if(last_post_task?.get()?.isActive == true) {
|
||||
showToast(activity, false, R.string.post_button_tapped_repeatly)
|
||||
activity.showToast(false, R.string.post_button_tapped_repeatly)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -286,371 +288,372 @@ class PostHelper(
|
|||
val delta = now - last_post_tapped
|
||||
last_post_tapped = now
|
||||
if(delta < 1000L) {
|
||||
showToast(activity, false, R.string.post_button_tapped_repeatly)
|
||||
activity.showToast(false, R.string.post_button_tapped_repeatly)
|
||||
return
|
||||
}
|
||||
|
||||
// 全ての確認を終えたらバックグラウンドでの処理を開始する
|
||||
last_post_task = WeakReference(TootTaskRunner(activity
|
||||
, progressSetupCallback = { progressDialog ->
|
||||
last_post_task =
|
||||
WeakReference(TootTaskRunner(activity, progressSetupCallback = { progressDialog ->
|
||||
progressDialog.setCanceledOnTouchOutside(false)
|
||||
}
|
||||
).run(account, object : TootTask {
|
||||
|
||||
var status : TootStatus? = null
|
||||
|
||||
var credential_tmp : TootAccount? = null
|
||||
|
||||
|
||||
|
||||
var scheduledStatusSucceeded = false
|
||||
|
||||
fun getCredential(client : TootApiClient,parser:TootParser) : TootApiResult? {
|
||||
val result = client.request("/api/v1/accounts/verify_credentials")
|
||||
credential_tmp = parser.account(result?.jsonObject)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun background(client : TootApiClient) : TootApiResult? {
|
||||
val parser = TootParser(activity, account)
|
||||
).run(account, object : TootTask {
|
||||
|
||||
var result : TootApiResult?
|
||||
var status : TootStatus? = null
|
||||
|
||||
// 元の投稿を削除する
|
||||
if(redraft_status_id != null) {
|
||||
result = if(account.isMisskey) {
|
||||
val params = account.putMisskeyApiToken(JsonObject()).apply {
|
||||
put("noteId", redraft_status_id)
|
||||
}
|
||||
client.request(
|
||||
"/api/notes/delete",
|
||||
params.toPostRequestBuilder()
|
||||
)
|
||||
} else {
|
||||
client.request(
|
||||
"/api/v1/statuses/$redraft_status_id",
|
||||
Request.Builder().delete()
|
||||
)
|
||||
|
||||
}
|
||||
log.d("delete redraft. result=$result")
|
||||
Thread.sleep(2000L)
|
||||
} else if(scheduledId != null) {
|
||||
val r1 = client.request(
|
||||
"/api/v1/scheduled_statuses/$scheduledId",
|
||||
Request.Builder().delete()
|
||||
)
|
||||
log.d("delete old scheduled status. result=$r1")
|
||||
Thread.sleep(2000L)
|
||||
}
|
||||
var credential_tmp : TootAccount? = null
|
||||
|
||||
var visibility_checked : TootVisibility? = visibility
|
||||
var scheduledStatusSucceeded = false
|
||||
|
||||
val (instance, ri) = TootInstance.get(client)
|
||||
instance ?: return ri
|
||||
|
||||
if(instance.instanceType == TootInstance.InstanceType.Pixelfed) {
|
||||
if(in_reply_to_id != null && attachment_list?.isNotEmpty() == true) {
|
||||
return TootApiResult(activity.getString(R.string.pixelfed_does_not_allow_reply_with_media))
|
||||
}
|
||||
if(in_reply_to_id == null && attachment_list?.isNotEmpty() != true) {
|
||||
return TootApiResult(activity.getString(R.string.pixelfed_does_not_allow_post_without_media))
|
||||
}
|
||||
}
|
||||
|
||||
if(visibility == TootVisibility.WebSetting) {
|
||||
visibility_checked =
|
||||
if(account.isMisskey || instance.versionGE(TootInstance.VERSION_1_6)) {
|
||||
null
|
||||
} else {
|
||||
val r2 = getCredential(client,parser)
|
||||
val credential_tmp = this.credential_tmp ?: return r2
|
||||
val privacy = credential_tmp.source?.privacy
|
||||
?: return TootApiResult(activity.getString(R.string.cant_get_web_setting_visibility))
|
||||
TootVisibility.parseMastodon(privacy)
|
||||
}
|
||||
}
|
||||
|
||||
val json = JsonObject()
|
||||
try {
|
||||
if(account.isMisskey) {
|
||||
account.putMisskeyApiToken(json)
|
||||
json["text"] = EmojiDecoder.decodeShortCode(
|
||||
content,
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
if(visibility_checked != null) {
|
||||
|
||||
if(visibility_checked == TootVisibility.DirectSpecified || visibility_checked == TootVisibility.DirectPrivate) {
|
||||
val userIds = JsonArray()
|
||||
|
||||
val m = TootAccount.reMisskeyMentionPost.matcher(content)
|
||||
while(m.find()) {
|
||||
val username = m.groupEx(1)
|
||||
val host = m.groupEx(2) // may null
|
||||
|
||||
result = client.request(
|
||||
"/api/users/show",
|
||||
account.putMisskeyApiToken().apply {
|
||||
if(username?.isNotEmpty() == true)
|
||||
put("username", username)
|
||||
if(host?.isNotEmpty() == true)
|
||||
put("host", host)
|
||||
}.toPostRequestBuilder()
|
||||
)
|
||||
val id = result?.jsonObject?.string("id")
|
||||
if(id?.isNotEmpty() == true) {
|
||||
userIds.add(id)
|
||||
}
|
||||
}
|
||||
json["visibility"] = when {
|
||||
userIds.isNotEmpty() -> {
|
||||
json["visibleUserIds"] = userIds
|
||||
"specified"
|
||||
}
|
||||
|
||||
account.misskeyVersion >= 11 -> "specified"
|
||||
else -> "private"
|
||||
}
|
||||
} else {
|
||||
val localVis = visibility_checked.strMisskey.replace(
|
||||
"^local-".toRegex(),
|
||||
""
|
||||
)
|
||||
if(localVis != visibility_checked.strMisskey) {
|
||||
json["localOnly"] = true
|
||||
json["visibility"] = localVis
|
||||
} else {
|
||||
json["visibility"] = visibility_checked.strMisskey
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(spoiler_text?.isNotEmpty() == true) {
|
||||
json["cw"] = EmojiDecoder.decodeShortCode(
|
||||
spoiler_text,
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
}
|
||||
|
||||
if(in_reply_to_id != null) {
|
||||
if(useQuoteToot) {
|
||||
json["renoteId"] = in_reply_to_id.toString()
|
||||
} else {
|
||||
json["replyId"] = in_reply_to_id.toString()
|
||||
}
|
||||
}
|
||||
|
||||
json["viaMobile"] = true
|
||||
|
||||
if(attachment_list != null) {
|
||||
val array = JsonArray()
|
||||
for(pa in attachment_list) {
|
||||
val a = pa.attachment ?: continue
|
||||
// Misskeyは画像の再利用に問題がないので redraftとバージョンのチェックは行わない
|
||||
array.add(a.id.toString())
|
||||
|
||||
// Misskeyの場合、NSFWするにはアップロード済みの画像を drive/files/update で更新する
|
||||
if(bNSFW) {
|
||||
val r = client.request(
|
||||
"/api/drive/files/update",
|
||||
account.putMisskeyApiToken().apply {
|
||||
put("fileId", a.id.toString())
|
||||
put("isSensitive", true)
|
||||
}
|
||||
.toPostRequestBuilder()
|
||||
)
|
||||
if(r == null || r.error != null) return r
|
||||
}
|
||||
}
|
||||
if(array.isNotEmpty()) json["mediaIds"] = array
|
||||
}
|
||||
|
||||
if(enquete_items?.isNotEmpty() == true) {
|
||||
val choices = JsonArray().apply {
|
||||
for(item in enquete_items) {
|
||||
val text = EmojiDecoder.decodeShortCode(
|
||||
item,
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
if(text.isEmpty()) continue
|
||||
add(text)
|
||||
}
|
||||
}
|
||||
if(choices.isNotEmpty()) {
|
||||
json["poll"] = jsonObject {
|
||||
put("choices", choices)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(scheduledAt != 0L) {
|
||||
return TootApiResult("misskey has no scheduled status API")
|
||||
}
|
||||
|
||||
} else {
|
||||
json["status"] = EmojiDecoder.decodeShortCode(
|
||||
content,
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
if(visibility_checked != null) {
|
||||
json["visibility"] = visibility_checked.strMastodon
|
||||
}
|
||||
json["sensitive"] = bNSFW
|
||||
json["spoiler_text"] = EmojiDecoder.decodeShortCode(
|
||||
spoiler_text ?: "",
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
|
||||
if(in_reply_to_id != null) {
|
||||
if(useQuoteToot) {
|
||||
json["quote_id"] = in_reply_to_id.toString()
|
||||
} else {
|
||||
json["in_reply_to_id"] = in_reply_to_id.toString()
|
||||
}
|
||||
}
|
||||
|
||||
if(attachment_list != null) {
|
||||
json["media_ids"] = jsonArray {
|
||||
for(pa in attachment_list) {
|
||||
val a = pa.attachment ?: continue
|
||||
if(a.redraft && ! instance.versionGE(TootInstance.VERSION_2_4_1)) continue
|
||||
add(a.id.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(enquete_items?.isNotEmpty() == true) {
|
||||
if(poll_type == TootPollsType.Mastodon) {
|
||||
json["poll"] = jsonObject {
|
||||
put("multiple", poll_multiple_choice)
|
||||
put("hide_totals", poll_hide_totals)
|
||||
put("expires_in", poll_expire_seconds)
|
||||
put("options",
|
||||
enquete_items.map {
|
||||
EmojiDecoder.decodeShortCode(
|
||||
it,
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
}
|
||||
.toJsonArray()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
json["isEnquete"] = true
|
||||
json["enquete_items"] = enquete_items.map {
|
||||
EmojiDecoder.decodeShortCode(
|
||||
it,
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
}.toJsonArray()
|
||||
}
|
||||
}
|
||||
|
||||
if(scheduledAt != 0L) {
|
||||
if(! instance.versionGE(TootInstance.VERSION_2_7_0_rc1)) {
|
||||
return TootApiResult(activity.getString(R.string.scheduled_status_requires_mastodon_2_7_0))
|
||||
}
|
||||
// UTCの日時を渡す
|
||||
val c = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"))
|
||||
c.timeInMillis = scheduledAt
|
||||
val sv = String.format(
|
||||
"%d-%02d-%02d %02d:%02d:%02d",
|
||||
c.get(Calendar.YEAR),
|
||||
c.get(Calendar.MONTH) + 1,
|
||||
c.get(Calendar.DAY_OF_MONTH),
|
||||
c.get(Calendar.HOUR_OF_DAY),
|
||||
c.get(Calendar.MINUTE),
|
||||
c.get(Calendar.SECOND)
|
||||
)
|
||||
json["scheduled_at"] = sv
|
||||
}
|
||||
|
||||
}
|
||||
} catch(ex : JsonException) {
|
||||
log.trace(ex)
|
||||
log.e(ex, "status encoding failed.")
|
||||
}
|
||||
|
||||
val body_string = json.toString()
|
||||
|
||||
val request_builder = body_string.toRequestBody(MEDIA_TYPE_JSON).toPost()
|
||||
|
||||
if(! Pref.bpDontDuplicationCheck(pref)) {
|
||||
val digest = (body_string + account.acct.ascii).digestSHA256Hex()
|
||||
request_builder.header("Idempotency-Key", digest)
|
||||
}
|
||||
|
||||
result = if(account.isMisskey) {
|
||||
// log.d("misskey json %s", body_string)
|
||||
client.request("/api/notes/create", request_builder)
|
||||
} else {
|
||||
client.request("/api/v1/statuses", request_builder)
|
||||
}
|
||||
|
||||
val jsonObject = result?.jsonObject
|
||||
|
||||
if(scheduledAt != 0L && jsonObject != null) {
|
||||
// {"id":"3","scheduled_at":"2019-01-06T07:08:00.000Z","media_attachments":[]}
|
||||
scheduledStatusSucceeded = true
|
||||
fun getCredential(
|
||||
client : TootApiClient,
|
||||
parser : TootParser
|
||||
) : TootApiResult? {
|
||||
val result = client.request("/api/v1/accounts/verify_credentials")
|
||||
credential_tmp = parser.account(result?.jsonObject)
|
||||
return result
|
||||
}
|
||||
|
||||
val status = parser.status(
|
||||
if(account.isMisskey) {
|
||||
result?.jsonObject?.jsonObject("createdNote") ?: result?.jsonObject
|
||||
} else {
|
||||
result?.jsonObject
|
||||
}
|
||||
)
|
||||
this.status = status
|
||||
if(status != null) {
|
||||
override fun background(client : TootApiClient) : TootApiResult? {
|
||||
val parser = TootParser(activity, account)
|
||||
|
||||
// タグを覚えておく
|
||||
val s = status.decoded_content
|
||||
val span_list = s.getSpans(0, s.length, MyClickableSpan::class.java)
|
||||
if(span_list != null) {
|
||||
val tag_list = ArrayList<String?>(span_list.size)
|
||||
for(span in span_list) {
|
||||
val start = s.getSpanStart(span)
|
||||
val end = s.getSpanEnd(span)
|
||||
val text = s.subSequence(start, end).toString()
|
||||
if(text.startsWith("#")) {
|
||||
tag_list.add(text.substring(1))
|
||||
var result : TootApiResult?
|
||||
|
||||
// 元の投稿を削除する
|
||||
if(redraft_status_id != null) {
|
||||
result = if(account.isMisskey) {
|
||||
val params = account.putMisskeyApiToken(JsonObject()).apply {
|
||||
put("noteId", redraft_status_id)
|
||||
}
|
||||
client.request(
|
||||
"/api/notes/delete",
|
||||
params.toPostRequestBuilder()
|
||||
)
|
||||
} else {
|
||||
client.request(
|
||||
"/api/v1/statuses/$redraft_status_id",
|
||||
Request.Builder().delete()
|
||||
)
|
||||
|
||||
}
|
||||
val count = tag_list.size
|
||||
if(count > 0) {
|
||||
TagSet.saveList(System.currentTimeMillis(), tag_list, 0, count)
|
||||
log.d("delete redraft. result=$result")
|
||||
Thread.sleep(2000L)
|
||||
} else if(scheduledId != null) {
|
||||
val r1 = client.request(
|
||||
"/api/v1/scheduled_statuses/$scheduledId",
|
||||
Request.Builder().delete()
|
||||
)
|
||||
log.d("delete old scheduled status. result=$r1")
|
||||
Thread.sleep(2000L)
|
||||
}
|
||||
|
||||
var visibility_checked : TootVisibility? = visibility
|
||||
|
||||
val (instance, ri) = TootInstance.get(client)
|
||||
instance ?: return ri
|
||||
|
||||
if(instance.instanceType == TootInstance.InstanceType.Pixelfed) {
|
||||
if(in_reply_to_id != null && attachment_list?.isNotEmpty() == true) {
|
||||
return TootApiResult(activity.getString(R.string.pixelfed_does_not_allow_reply_with_media))
|
||||
}
|
||||
if(in_reply_to_id == null && attachment_list?.isNotEmpty() != true) {
|
||||
return TootApiResult(activity.getString(R.string.pixelfed_does_not_allow_post_without_media))
|
||||
}
|
||||
}
|
||||
|
||||
if(visibility == TootVisibility.WebSetting) {
|
||||
visibility_checked =
|
||||
if(account.isMisskey || instance.versionGE(TootInstance.VERSION_1_6)) {
|
||||
null
|
||||
} else {
|
||||
val r2 = getCredential(client, parser)
|
||||
val credential_tmp = this.credential_tmp ?: return r2
|
||||
val privacy = credential_tmp.source?.privacy
|
||||
?: return TootApiResult(activity.getString(R.string.cant_get_web_setting_visibility))
|
||||
TootVisibility.parseMastodon(privacy)
|
||||
}
|
||||
}
|
||||
|
||||
val json = JsonObject()
|
||||
try {
|
||||
if(account.isMisskey) {
|
||||
account.putMisskeyApiToken(json)
|
||||
json["text"] = EmojiDecoder.decodeShortCode(
|
||||
content,
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
if(visibility_checked != null) {
|
||||
|
||||
if(visibility_checked == TootVisibility.DirectSpecified || visibility_checked == TootVisibility.DirectPrivate) {
|
||||
val userIds = JsonArray()
|
||||
|
||||
val m = TootAccount.reMisskeyMentionPost.matcher(content)
|
||||
while(m.find()) {
|
||||
val username = m.groupEx(1)
|
||||
val host = m.groupEx(2) // may null
|
||||
|
||||
result = client.request(
|
||||
"/api/users/show",
|
||||
account.putMisskeyApiToken().apply {
|
||||
if(username?.isNotEmpty() == true)
|
||||
put("username", username)
|
||||
if(host?.isNotEmpty() == true)
|
||||
put("host", host)
|
||||
}.toPostRequestBuilder()
|
||||
)
|
||||
val id = result?.jsonObject?.string("id")
|
||||
if(id?.isNotEmpty() == true) {
|
||||
userIds.add(id)
|
||||
}
|
||||
}
|
||||
json["visibility"] = when {
|
||||
userIds.isNotEmpty() -> {
|
||||
json["visibleUserIds"] = userIds
|
||||
"specified"
|
||||
}
|
||||
|
||||
account.misskeyVersion >= 11 -> "specified"
|
||||
else -> "private"
|
||||
}
|
||||
} else {
|
||||
val localVis = visibility_checked.strMisskey.replace(
|
||||
"^local-".toRegex(),
|
||||
""
|
||||
)
|
||||
if(localVis != visibility_checked.strMisskey) {
|
||||
json["localOnly"] = true
|
||||
json["visibility"] = localVis
|
||||
} else {
|
||||
json["visibility"] = visibility_checked.strMisskey
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(spoiler_text?.isNotEmpty() == true) {
|
||||
json["cw"] = EmojiDecoder.decodeShortCode(
|
||||
spoiler_text,
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
}
|
||||
|
||||
if(in_reply_to_id != null) {
|
||||
if(useQuoteToot) {
|
||||
json["renoteId"] = in_reply_to_id.toString()
|
||||
} else {
|
||||
json["replyId"] = in_reply_to_id.toString()
|
||||
}
|
||||
}
|
||||
|
||||
json["viaMobile"] = true
|
||||
|
||||
if(attachment_list != null) {
|
||||
val array = JsonArray()
|
||||
for(pa in attachment_list) {
|
||||
val a = pa.attachment ?: continue
|
||||
// Misskeyは画像の再利用に問題がないので redraftとバージョンのチェックは行わない
|
||||
array.add(a.id.toString())
|
||||
|
||||
// Misskeyの場合、NSFWするにはアップロード済みの画像を drive/files/update で更新する
|
||||
if(bNSFW) {
|
||||
val r = client.request(
|
||||
"/api/drive/files/update",
|
||||
account.putMisskeyApiToken().apply {
|
||||
put("fileId", a.id.toString())
|
||||
put("isSensitive", true)
|
||||
}
|
||||
.toPostRequestBuilder()
|
||||
)
|
||||
if(r == null || r.error != null) return r
|
||||
}
|
||||
}
|
||||
if(array.isNotEmpty()) json["mediaIds"] = array
|
||||
}
|
||||
|
||||
if(enquete_items?.isNotEmpty() == true) {
|
||||
val choices = JsonArray().apply {
|
||||
for(item in enquete_items) {
|
||||
val text = EmojiDecoder.decodeShortCode(
|
||||
item,
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
if(text.isEmpty()) continue
|
||||
add(text)
|
||||
}
|
||||
}
|
||||
if(choices.isNotEmpty()) {
|
||||
json["poll"] = jsonObject {
|
||||
put("choices", choices)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(scheduledAt != 0L) {
|
||||
return TootApiResult("misskey has no scheduled status API")
|
||||
}
|
||||
|
||||
} else {
|
||||
json["status"] = EmojiDecoder.decodeShortCode(
|
||||
content,
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
if(visibility_checked != null) {
|
||||
json["visibility"] = visibility_checked.strMastodon
|
||||
}
|
||||
json["sensitive"] = bNSFW
|
||||
json["spoiler_text"] = EmojiDecoder.decodeShortCode(
|
||||
spoiler_text ?: "",
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
|
||||
if(in_reply_to_id != null) {
|
||||
if(useQuoteToot) {
|
||||
json["quote_id"] = in_reply_to_id.toString()
|
||||
} else {
|
||||
json["in_reply_to_id"] = in_reply_to_id.toString()
|
||||
}
|
||||
}
|
||||
|
||||
if(attachment_list != null) {
|
||||
json["media_ids"] = jsonArray {
|
||||
for(pa in attachment_list) {
|
||||
val a = pa.attachment ?: continue
|
||||
if(a.redraft && ! instance.versionGE(TootInstance.VERSION_2_4_1)) continue
|
||||
add(a.id.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(enquete_items?.isNotEmpty() == true) {
|
||||
if(poll_type == TootPollsType.Mastodon) {
|
||||
json["poll"] = jsonObject {
|
||||
put("multiple", poll_multiple_choice)
|
||||
put("hide_totals", poll_hide_totals)
|
||||
put("expires_in", poll_expire_seconds)
|
||||
put("options",
|
||||
enquete_items.map {
|
||||
EmojiDecoder.decodeShortCode(
|
||||
it,
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
}
|
||||
.toJsonArray()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
json["isEnquete"] = true
|
||||
json["enquete_items"] = enquete_items.map {
|
||||
EmojiDecoder.decodeShortCode(
|
||||
it,
|
||||
emojiMapCustom = emojiMapCustom
|
||||
)
|
||||
}.toJsonArray()
|
||||
}
|
||||
}
|
||||
|
||||
if(scheduledAt != 0L) {
|
||||
if(! instance.versionGE(TootInstance.VERSION_2_7_0_rc1)) {
|
||||
return TootApiResult(activity.getString(R.string.scheduled_status_requires_mastodon_2_7_0))
|
||||
}
|
||||
// UTCの日時を渡す
|
||||
val c = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"))
|
||||
c.timeInMillis = scheduledAt
|
||||
val sv = String.format(
|
||||
"%d-%02d-%02d %02d:%02d:%02d",
|
||||
c.get(Calendar.YEAR),
|
||||
c.get(Calendar.MONTH) + 1,
|
||||
c.get(Calendar.DAY_OF_MONTH),
|
||||
c.get(Calendar.HOUR_OF_DAY),
|
||||
c.get(Calendar.MINUTE),
|
||||
c.get(Calendar.SECOND)
|
||||
)
|
||||
json["scheduled_at"] = sv
|
||||
}
|
||||
|
||||
}
|
||||
} catch(ex : JsonException) {
|
||||
log.trace(ex)
|
||||
log.e(ex, "status encoding failed.")
|
||||
}
|
||||
|
||||
val body_string = json.toString()
|
||||
|
||||
val request_builder = body_string.toRequestBody(MEDIA_TYPE_JSON).toPost()
|
||||
|
||||
if(! Pref.bpDontDuplicationCheck(pref)) {
|
||||
val digest = (body_string + account.acct.ascii).digestSHA256Hex()
|
||||
request_builder.header("Idempotency-Key", digest)
|
||||
}
|
||||
|
||||
result = if(account.isMisskey) {
|
||||
// log.d("misskey json %s", body_string)
|
||||
client.request("/api/notes/create", request_builder)
|
||||
} else {
|
||||
client.request("/api/v1/statuses", request_builder)
|
||||
}
|
||||
|
||||
val jsonObject = result?.jsonObject
|
||||
|
||||
if(scheduledAt != 0L && jsonObject != null) {
|
||||
// {"id":"3","scheduled_at":"2019-01-06T07:08:00.000Z","media_attachments":[]}
|
||||
scheduledStatusSucceeded = true
|
||||
return result
|
||||
}
|
||||
|
||||
val status = parser.status(
|
||||
if(account.isMisskey) {
|
||||
result?.jsonObject?.jsonObject("createdNote") ?: result?.jsonObject
|
||||
} else {
|
||||
result?.jsonObject
|
||||
}
|
||||
)
|
||||
this.status = status
|
||||
if(status != null) {
|
||||
|
||||
// タグを覚えておく
|
||||
val s = status.decoded_content
|
||||
val span_list = s.getSpans(0, s.length, MyClickableSpan::class.java)
|
||||
if(span_list != null) {
|
||||
val tag_list = ArrayList<String?>(span_list.size)
|
||||
for(span in span_list) {
|
||||
val start = s.getSpanStart(span)
|
||||
val end = s.getSpanEnd(span)
|
||||
val text = s.subSequence(start, end).toString()
|
||||
if(text.startsWith("#")) {
|
||||
tag_list.add(text.substring(1))
|
||||
}
|
||||
}
|
||||
val count = tag_list.size
|
||||
if(count > 0) {
|
||||
TagSet.saveList(System.currentTimeMillis(), tag_list, 0, count)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override fun handleResult(result : TootApiResult?) {
|
||||
result ?: return
|
||||
val status = this.status
|
||||
when {
|
||||
status != null -> {
|
||||
// 連投してIdempotency が同じだった場合もエラーにはならず、ここを通る
|
||||
callback.onPostComplete(account, status)
|
||||
return
|
||||
}
|
||||
|
||||
scheduledStatusSucceeded -> {
|
||||
callback.onScheduledPostComplete(account)
|
||||
return
|
||||
|
||||
override fun handleResult(result : TootApiResult?) {
|
||||
result ?: return
|
||||
val status = this.status
|
||||
when {
|
||||
status != null -> {
|
||||
// 連投してIdempotency が同じだった場合もエラーにはならず、ここを通る
|
||||
callback.onPostComplete(account, status)
|
||||
return
|
||||
}
|
||||
|
||||
scheduledStatusSucceeded -> {
|
||||
callback.onScheduledPostComplete(account)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
else -> activity.showToast(true, result.error)
|
||||
}
|
||||
|
||||
else -> showToast(activity, true, result.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -890,12 +893,7 @@ class PostHelper(
|
|||
sb.append(item.alias)
|
||||
sb.append(": → ")
|
||||
sb.setSpan(
|
||||
ForegroundColorSpan(
|
||||
getAttributeColor(
|
||||
activity,
|
||||
R.attr.colorTimeSmall
|
||||
)
|
||||
),
|
||||
ForegroundColorSpan(activity.getAttributeColor(R.attr.colorTimeSmall)),
|
||||
start,
|
||||
sb.length,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
|
@ -922,6 +920,7 @@ class PostHelper(
|
|||
}
|
||||
|
||||
interface Callback2 {
|
||||
|
||||
fun onTextUpdate()
|
||||
|
||||
fun canOpenPopup() : Boolean
|
||||
|
@ -1053,7 +1052,10 @@ class PostHelper(
|
|||
proc_text_changed.run()
|
||||
|
||||
// キーボードを再度表示する
|
||||
App1.getAppState(activity,"PostHelper/EmojiPicker/cb").handler.post { et.showKeyboard() }
|
||||
App1.getAppState(
|
||||
activity,
|
||||
"PostHelper/EmojiPicker/cb"
|
||||
).handler.post { et.showKeyboard() }
|
||||
|
||||
}.show()
|
||||
}
|
||||
|
@ -1091,7 +1093,7 @@ class PostHelper(
|
|||
|
||||
fun openFeaturedTagList(list : List<TootTag>?) {
|
||||
val ad = ActionsDialog()
|
||||
list?.forEach {tag->
|
||||
list?.forEach { tag ->
|
||||
ad.addAction("#${tag.name}") {
|
||||
val et = this.et ?: return@addAction
|
||||
|
||||
|
@ -1112,7 +1114,7 @@ class PostHelper(
|
|||
proc_text_changed.run()
|
||||
}
|
||||
}
|
||||
ad.addAction( activity.getString(R.string.input_sharp_itself)){
|
||||
ad.addAction(activity.getString(R.string.input_sharp_itself)) {
|
||||
val et = this.et ?: return@addAction
|
||||
|
||||
val src = et.text ?: ""
|
||||
|
@ -1124,7 +1126,7 @@ class PostHelper(
|
|||
sb.append(src.subSequence(0, start))
|
||||
if(! EmojiDecoder.canStartHashtag(sb, sb.length)) sb.append(' ')
|
||||
sb.append('#')
|
||||
|
||||
|
||||
val newSelection = sb.length
|
||||
if(end < src_length) sb.append(src.subSequence(end, src_length))
|
||||
et.text = sb
|
||||
|
|
|
@ -4,17 +4,12 @@ import android.content.DialogInterface
|
|||
import jp.juggler.subwaytooter.api.TootApiResult
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// callback (that returns Unit)
|
||||
|
||||
typealias EmptyCallback = ()->Unit
|
||||
|
||||
typealias TootApiResultCallback = (result : TootApiResult) -> Unit
|
||||
|
||||
|
||||
typealias SavedAccountCallback = (ai : SavedAccount) -> Unit
|
||||
|
||||
typealias DialogInterfaceCallback = (dialog: DialogInterface) -> Unit
|
||||
typealias DialogInterfaceCallback = (dialog : DialogInterface) -> Unit
|
||||
|
||||
typealias ProgressResponseBodyCallback = (bytesRead : Long, bytesTotal : Long) -> Unit
|
||||
|
||||
typealias ProgressResponseBodyCallback = (bytesRead : Long, bytesTotal : Long)->Unit
|
||||
val emptyCallback : () -> Unit = {}
|
|
@ -124,7 +124,7 @@ fun createResizedBitmap(
|
|||
var src_width = options.outWidth
|
||||
var src_height = options.outHeight
|
||||
if(src_width <= 0 || src_height <= 0) {
|
||||
showToast(context, false, "could not get image bounds.")
|
||||
context.showToast(false, "could not get image bounds.")
|
||||
return null
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,7 @@ fun createResizedBitmap(
|
|||
}
|
||||
|
||||
if(sourceBitmap == null) {
|
||||
showToast(context, false, "could not decode image.")
|
||||
context.showToast(false, "could not decode image.")
|
||||
return null
|
||||
}
|
||||
try {
|
||||
|
@ -234,7 +234,7 @@ fun createResizedBitmap(
|
|||
Bitmap.createBitmap(dstSizeInt.x, dstSizeInt.y, Bitmap.Config.ARGB_8888)
|
||||
try {
|
||||
return if(dst == null) {
|
||||
showToast(context, false, "bitmap creation failed.")
|
||||
context.showToast(false, "bitmap creation failed.")
|
||||
null
|
||||
} else {
|
||||
val canvas = Canvas(dst)
|
||||
|
|
|
@ -45,19 +45,19 @@ object ToastUtils {
|
|||
|
||||
}
|
||||
|
||||
fun showToast(context : Context, bLong : Boolean, fmt : String?, vararg args : Any) {
|
||||
fun Context.showToast(bLong : Boolean, fmt : String?, vararg args : Any) {
|
||||
val msg = if(fmt == null) "(null)" else if(args.isEmpty()) fmt else String.format(fmt, *args)
|
||||
ToastUtils.showToastImpl(context, bLong, msg)
|
||||
ToastUtils.showToastImpl(this, bLong, msg)
|
||||
}
|
||||
|
||||
fun showToast(context : Context, ex : Throwable, fmt : String?, vararg args : Any) {
|
||||
ToastUtils.showToastImpl(context, true, ex.withCaption(fmt, *args))
|
||||
fun Context.showToast(ex : Throwable, fmt : String?, vararg args : Any) {
|
||||
ToastUtils.showToastImpl(this, true, ex.withCaption(fmt, *args))
|
||||
}
|
||||
|
||||
fun showToast(context : Context, bLong : Boolean, string_id : Int, vararg args : Any) {
|
||||
ToastUtils.showToastImpl(context, bLong, context.getString(string_id, *args))
|
||||
fun Context.showToast(bLong : Boolean, string_id : Int, vararg args : Any) {
|
||||
ToastUtils.showToastImpl(this, bLong, getString(string_id, *args))
|
||||
}
|
||||
|
||||
fun showToast(context : Context, ex : Throwable, string_id : Int, vararg args : Any) {
|
||||
ToastUtils.showToastImpl(context, true, ex.withCaption(context.resources, string_id, *args))
|
||||
fun Context.showToast(ex : Throwable, string_id : Int, vararg args : Any) {
|
||||
ToastUtils.showToastImpl(this, true, ex.withCaption(resources, string_id, *args))
|
||||
}
|
||||
|
|
|
@ -37,8 +37,7 @@ fun Int.applyAlphaMultiplier(alphaMultiplier : Float? = null) : Int {
|
|||
}
|
||||
}
|
||||
|
||||
fun getAttributeColor(context : Context, attrId : Int) : Int {
|
||||
val theme = context.theme
|
||||
fun Context.getAttributeColor(attrId : Int) : Int {
|
||||
val a = theme.obtainStyledAttributes(intArrayOf(attrId))
|
||||
val color = a.getColor(0, Color.BLACK)
|
||||
a.recycle()
|
||||
|
@ -298,10 +297,10 @@ fun CharSequence.copyToClipboard(context : Context) {
|
|||
|
||||
clipboard.setPrimaryClip(clip)
|
||||
|
||||
showToast(context, false, R.string.copy_complete)
|
||||
context.showToast(false, R.string.copy_complete)
|
||||
} catch(ex : Throwable) {
|
||||
UiUtils.log.trace(ex)
|
||||
showToast(context, ex, "copy failed.")
|
||||
context.showToast(ex, "copy failed.")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -98,23 +98,20 @@ var CompoundButton.isCheckedNoAnime : Boolean
|
|||
jumpDrawablesToCurrentState()
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun mixColor(col1 : Int, col2 : Int) : Int = Color.rgb(
|
||||
(Color.red(col1) + Color.red(col2)) ushr 1,
|
||||
(Color.green(col1) + Color.green(col2)) ushr 1,
|
||||
(Color.blue(col1) + Color.blue(col2)) ushr 1
|
||||
)
|
||||
|
||||
fun setSwitchColor(
|
||||
activity : AppCompatActivity,
|
||||
fun Context.setSwitchColor(
|
||||
pref : SharedPreferences,
|
||||
root : View?
|
||||
) {
|
||||
val colorBg = getAttributeColor(activity, R.attr.colorWindowBackground)
|
||||
val colorBg = getAttributeColor(R.attr.colorWindowBackground)
|
||||
val colorOn = Pref.ipSwitchOnColor(pref)
|
||||
val colorOff = /* Pref.ipSwitchOffColor(pref).notZero() ?: */
|
||||
getAttributeColor(activity, android.R.attr.colorPrimary)
|
||||
getAttributeColor(android.R.attr.colorPrimary)
|
||||
|
||||
val colorDisabled = mixColor(colorBg, colorOff)
|
||||
|
||||
|
@ -157,7 +154,6 @@ fun setSwitchColor(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private fun rgbToLab(rgb : Int) : Triple<Float, Float, Float> {
|
||||
|
||||
fun Int.revGamma() : Float {
|
||||
|
@ -193,9 +189,9 @@ private fun rgbToLab(rgb : Int) : Triple<Float, Float, Float> {
|
|||
)
|
||||
}
|
||||
|
||||
fun setStatusBarColor(activity : Activity, forceDark : Boolean = false) {
|
||||
fun AppCompatActivity.setStatusBarColor(forceDark : Boolean = false) {
|
||||
|
||||
activity.window?.apply {
|
||||
window?.apply {
|
||||
|
||||
// 古い端末ではナビゲーションバーのアイコン色を設定できないため
|
||||
// メディアビューア画面ではステータスバーやナビゲーションバーの色を設定しない…
|
||||
|
@ -211,7 +207,7 @@ fun setStatusBarColor(activity : Activity, forceDark : Boolean = false) {
|
|||
var c = when {
|
||||
forceDark -> Color.BLACK
|
||||
else -> Pref.ipStatusBarColor(App1.pref).notZero()
|
||||
?: getAttributeColor(activity, R.attr.colorPrimaryDark)
|
||||
?: getAttributeColor(R.attr.colorPrimaryDark)
|
||||
}
|
||||
statusBarColor = c or Color.BLACK
|
||||
|
||||
|
|
Loading…
Reference in New Issue