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