fix user creation sequence. add resend confirm email dialog. (but api does not work)
This commit is contained in:
parent
3f71b87125
commit
970264bd3a
|
@ -1826,8 +1826,8 @@ class ActMain : AsyncActivity(), View.OnClickListener,
|
|||
|
||||
var ta: TootAccount? = null
|
||||
var sa: SavedAccount? = null
|
||||
var host: Host? = null
|
||||
var ti: TootInstance? = null
|
||||
var apiHost: Host? = null
|
||||
var apDomain: Host? = null
|
||||
|
||||
override suspend fun background(client: TootApiClient): TootApiResult? {
|
||||
|
||||
|
@ -1868,8 +1868,8 @@ class ActMain : AsyncActivity(), View.OnClickListener,
|
|||
val (ti, r2) = TootInstance.get(client)
|
||||
ti ?: return r2
|
||||
|
||||
this.ti = ti
|
||||
this.host = instance
|
||||
this.apiHost = instance
|
||||
this.apDomain = ti.uri?.let{ Host.parse(it)}
|
||||
|
||||
val parser = TootParser(
|
||||
this@ActMain,
|
||||
|
@ -1938,7 +1938,8 @@ class ActMain : AsyncActivity(), View.OnClickListener,
|
|||
|
||||
val instance = client.apiHost
|
||||
?: return TootApiResult("missing instance in callback url.")
|
||||
this.host = instance
|
||||
this.apiHost = instance
|
||||
|
||||
|
||||
|
||||
val parser = TootParser(
|
||||
|
@ -1955,24 +1956,26 @@ class ActMain : AsyncActivity(), View.OnClickListener,
|
|||
this.ta = parser.account(it.jsonObject)
|
||||
if( ta != null){
|
||||
val (ti, ri) = TootInstance.getEx(client, forceAccessToken = refToken.get())
|
||||
this.ti = ti ?: return ri
|
||||
ti ?: return ri
|
||||
this.apDomain = ti.uri?.let{ it2-> Host.parse(it2)}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun handleResult(result: TootApiResult?) {
|
||||
val host = this.host
|
||||
val apiHost = this.apiHost
|
||||
val apDomain = this.apDomain
|
||||
val ta = this.ta
|
||||
var sa = this.sa
|
||||
|
||||
if (ta != null && host?.isValid == true && sa == null) {
|
||||
val acct = Acct.parse(ta.username, host)
|
||||
if (ta != null && apiHost?.isValid == true && sa == null) {
|
||||
val acct = Acct.parse(ta.username, apDomain ?: apiHost )
|
||||
// アカウント追加時に、アプリ内に既にあるアカウントと同じものを登録していたかもしれない
|
||||
sa = SavedAccount.loadAccountByAcct(this@ActMain, acct.ascii)
|
||||
}
|
||||
|
||||
afterAccountVerify(result, ta, sa, ti, host)
|
||||
afterAccountVerify(result, ta, sa, apiHost, apDomain)
|
||||
}
|
||||
|
||||
})
|
||||
|
@ -1994,8 +1997,8 @@ class ActMain : AsyncActivity(), View.OnClickListener,
|
|||
result: TootApiResult?,
|
||||
ta: TootAccount?,
|
||||
sa: SavedAccount?,
|
||||
ti: TootInstance?,
|
||||
host: Host?
|
||||
apiHost: Host?,
|
||||
apDomain: Host?
|
||||
): Boolean {
|
||||
result ?: return false
|
||||
|
||||
|
@ -2041,20 +2044,14 @@ class ActMain : AsyncActivity(), View.OnClickListener,
|
|||
return true
|
||||
}
|
||||
|
||||
host != null -> {
|
||||
apiHost != null -> {
|
||||
// アカウント追加時
|
||||
val user = Acct.parse(ta.username, host)
|
||||
|
||||
val apDomain = ti?.uri
|
||||
if (apDomain == null) {
|
||||
showToast(false, "Can't get ActivityPub domain name.")
|
||||
return false
|
||||
}
|
||||
val user = Acct.parse(ta.username, apDomain ?: apiHost)
|
||||
|
||||
val row_id = SavedAccount.insert(
|
||||
acct = user.ascii,
|
||||
host = host.ascii,
|
||||
domain = apDomain,
|
||||
host = apiHost.ascii,
|
||||
domain = (apDomain ?: apiHost).ascii,
|
||||
account = jsonObject,
|
||||
token = token_info,
|
||||
misskeyVersion = TootInstance.parseMisskeyVersion(token_info)
|
||||
|
@ -2120,12 +2117,17 @@ class ActMain : AsyncActivity(), View.OnClickListener,
|
|||
TootTaskRunner(this@ActMain).run(apiHost, object : TootTask {
|
||||
|
||||
var ta: TootAccount? = null
|
||||
var ti: TootInstance? = null
|
||||
var apDomain : Host? = null
|
||||
|
||||
override suspend fun background(client: TootApiClient): TootApiResult? {
|
||||
|
||||
val (ti,ri) = TootInstance.getEx(client,forceAccessToken = access_token)
|
||||
this.ti = ti ?: return ri
|
||||
ti ?: return ri
|
||||
|
||||
val apDomain = ti.uri?.let { Host.parse(it) }
|
||||
?: return TootApiResult("missing uri in Instance Information")
|
||||
|
||||
this.apDomain = apDomain
|
||||
|
||||
val misskeyVersion = ti.misskeyVersion
|
||||
|
||||
|
@ -2134,8 +2136,8 @@ class ActMain : AsyncActivity(), View.OnClickListener,
|
|||
this.ta = TootParser(
|
||||
this@ActMain,
|
||||
LinkHelper.create(
|
||||
apiHost,
|
||||
apDomainArg = ti.uri?.let { Host.parse(it) },
|
||||
apiHostArg = apiHost,
|
||||
apDomainArg = apDomain,
|
||||
misskeyVersion = misskeyVersion
|
||||
)
|
||||
).account(result?.jsonObject)
|
||||
|
@ -2144,7 +2146,7 @@ class ActMain : AsyncActivity(), View.OnClickListener,
|
|||
}
|
||||
|
||||
override suspend fun handleResult(result: TootApiResult?) {
|
||||
if (afterAccountVerify(result, ta, sa, ti, apiHost)) {
|
||||
if (afterAccountVerify(result, ta, sa, apiHost, apDomain)) {
|
||||
dialog_host?.dismissSafe()
|
||||
dialog_token?.dismissSafe()
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.google.android.flexbox.JustifyContent
|
|||
import com.omadahealth.github.swipyrefreshlayout.library.SwipyRefreshLayout
|
||||
import com.omadahealth.github.swipyrefreshlayout.library.SwipyRefreshLayoutDirection
|
||||
import jp.juggler.emoji.UnicodeEmoji
|
||||
import jp.juggler.subwaytooter.action.Action_Account
|
||||
import jp.juggler.subwaytooter.action.Action_List
|
||||
import jp.juggler.subwaytooter.action.Action_Notification
|
||||
import jp.juggler.subwaytooter.api.TootApiClient
|
||||
|
@ -87,7 +88,10 @@ class ColumnViewHolder(
|
|||
private var status_adapter: ItemListAdapter? = null
|
||||
private var page_idx: Int = 0
|
||||
|
||||
private lateinit var llLoading: View
|
||||
private lateinit var btnConfirmMail: Button
|
||||
private lateinit var tvLoading: TextView
|
||||
|
||||
lateinit var listView: RecyclerView
|
||||
lateinit var refreshLayout: SwipyRefreshLayout
|
||||
|
||||
|
@ -297,7 +301,7 @@ class ColumnViewHolder(
|
|||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun initLoadingTextView() {
|
||||
tvLoading.setOnTouchListener(ErrorFlickListener(activity))
|
||||
llLoading.setOnTouchListener(ErrorFlickListener(activity))
|
||||
}
|
||||
|
||||
val viewRoot: View = inflate(activity, parent)
|
||||
|
@ -354,6 +358,7 @@ class ColumnViewHolder(
|
|||
btnColumnClose.setOnClickListener(this)
|
||||
btnColumnClose.setOnLongClickListener(this)
|
||||
btnDeleteNotification.setOnClickListener(this)
|
||||
btnConfirmMail.setOnClickListener(this)
|
||||
|
||||
btnColor.setOnClickListener(this)
|
||||
btnLanguageFilter.setOnClickListener(this)
|
||||
|
@ -782,7 +787,13 @@ class ColumnViewHolder(
|
|||
)
|
||||
}
|
||||
val streamStatus = column.getStreamingStatus()
|
||||
log.d("procShowColumnStatus: streamStatus=${streamStatus}, column=${column.access_info.acct}/${column.getColumnName(true)}")
|
||||
log.d(
|
||||
"procShowColumnStatus: streamStatus=${streamStatus}, column=${column.access_info.acct}/${
|
||||
column.getColumnName(
|
||||
true
|
||||
)
|
||||
}"
|
||||
)
|
||||
|
||||
when (streamStatus) {
|
||||
StreamStatus.Missing, StreamStatus.Closed -> {
|
||||
|
@ -1181,6 +1192,11 @@ class ColumnViewHolder(
|
|||
activity.app_state.saveColumnList()
|
||||
showAnnouncements()
|
||||
}
|
||||
|
||||
btnConfirmMail -> {
|
||||
Action_Account.resendConfirmMail(activity, column.access_info)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1198,12 +1214,13 @@ class ColumnViewHolder(
|
|||
|
||||
private fun showError(message: String) {
|
||||
hideRefreshError()
|
||||
tvLoading.visibility = View.VISIBLE
|
||||
tvLoading.text = message
|
||||
|
||||
refreshLayout.isRefreshing = false
|
||||
refreshLayout.visibility = View.GONE
|
||||
|
||||
llLoading.visibility = View.VISIBLE
|
||||
tvLoading.text = message
|
||||
btnConfirmMail.vg(column?.access_info?.isConfirmed == false)
|
||||
}
|
||||
|
||||
private fun showColumnCloseButton() {
|
||||
|
@ -1300,7 +1317,7 @@ class ColumnViewHolder(
|
|||
return
|
||||
}
|
||||
|
||||
tvLoading.visibility = View.GONE
|
||||
llLoading.visibility = View.GONE
|
||||
|
||||
refreshLayout.visibility = View.VISIBLE
|
||||
|
||||
|
@ -2353,9 +2370,27 @@ class ColumnViewHolder(
|
|||
|
||||
}.lparams(matchParent, matchParent)
|
||||
|
||||
tvLoading = textView {
|
||||
llLoading = verticalLayout {
|
||||
lparams(matchParent, matchParent)
|
||||
|
||||
isBaselineAligned = false
|
||||
|
||||
gravity = Gravity.CENTER
|
||||
}.lparams(matchParent, matchParent)
|
||||
|
||||
tvLoading = textView {
|
||||
gravity = Gravity.CENTER
|
||||
}.lparams(matchParent, wrapContent)
|
||||
|
||||
btnConfirmMail = button {
|
||||
text = activity.getString(R.string.resend_confirm_mail)
|
||||
background = ContextCompat.getDrawable(
|
||||
activity,
|
||||
R.drawable.btn_bg_transparent_round6dp
|
||||
)
|
||||
}.lparams(matchParent, wrapContent) {
|
||||
topMargin = dip(8)
|
||||
}
|
||||
}
|
||||
|
||||
refreshLayout = swipyRefreshLayout {
|
||||
lparams(matchParent, matchParent)
|
||||
|
@ -2744,7 +2779,7 @@ class ColumnViewHolder(
|
|||
if (sample == null) {
|
||||
EmojiPicker(activity, column.access_info, closeOnSelected = true) { result ->
|
||||
val emoji = result.emoji
|
||||
val code = when(emoji){
|
||||
val code = when (emoji) {
|
||||
is UnicodeEmoji -> emoji.unifiedCode
|
||||
is CustomEmoji -> emoji.shortcode
|
||||
else -> error("unknown emoji type")
|
||||
|
|
|
@ -3,13 +3,11 @@ package jp.juggler.subwaytooter.action
|
|||
import android.app.Dialog
|
||||
import android.os.Build
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import jp.juggler.subwaytooter.*
|
||||
import jp.juggler.subwaytooter.api.*
|
||||
import jp.juggler.subwaytooter.api.entity.*
|
||||
import jp.juggler.subwaytooter.dialog.AccountPicker
|
||||
import jp.juggler.subwaytooter.dialog.DlgCreateAccount
|
||||
import jp.juggler.subwaytooter.dialog.DlgTextInput
|
||||
import jp.juggler.subwaytooter.dialog.LoginForm
|
||||
import jp.juggler.subwaytooter.dialog.*
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.table.UserRelation
|
||||
import jp.juggler.subwaytooter.util.LinkHelper
|
||||
|
@ -17,318 +15,357 @@ import jp.juggler.subwaytooter.util.openBrowser
|
|||
import jp.juggler.util.*
|
||||
|
||||
object Action_Account {
|
||||
|
||||
@Suppress("unused")
|
||||
private val log = LogCategory("Action_Account")
|
||||
|
||||
// アカウントの追加
|
||||
fun add(activity : ActMain) {
|
||||
|
||||
LoginForm.showLoginForm(
|
||||
activity,
|
||||
null
|
||||
) { dialog, instance, action ->
|
||||
TootTaskRunner(activity).run(instance, object : TootTask {
|
||||
|
||||
override suspend fun background(client : TootApiClient) : TootApiResult? {
|
||||
return when(action) {
|
||||
|
||||
LoginForm.Action.Existing ->
|
||||
client.authentication1(Pref.spClientName(activity))
|
||||
|
||||
LoginForm.Action.Create ->
|
||||
client.createUser1(Pref.spClientName(activity))
|
||||
|
||||
LoginForm.Action.Pseudo,
|
||||
LoginForm.Action.Token -> {
|
||||
val (ti, ri) = TootInstance.get(client)
|
||||
if(ti != null) ri?.data = ti
|
||||
ri
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun handleResult(result : TootApiResult?) {
|
||||
|
||||
result ?: return // cancelled.
|
||||
|
||||
val data = result.data
|
||||
if(result.error == null && data != null) {
|
||||
when(action) {
|
||||
LoginForm.Action.Existing -> if(data is String) {
|
||||
// ブラウザ用URLが生成された
|
||||
activity.openBrowser(data.toUri())
|
||||
dialog.dismissSafe()
|
||||
return
|
||||
}
|
||||
|
||||
LoginForm.Action.Create -> if(data is JsonObject) {
|
||||
// インスタンスを確認できた
|
||||
createAccount(
|
||||
activity,
|
||||
instance,
|
||||
data,
|
||||
dialog
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
LoginForm.Action.Pseudo -> if(data is TootInstance) {
|
||||
addPseudoAccount(
|
||||
activity,
|
||||
instance,
|
||||
instanceInfo = data
|
||||
) { a ->
|
||||
activity.showToast(false, R.string.server_confirmed)
|
||||
val pos = activity.app_state.columnCount
|
||||
activity.addColumn(pos, a, ColumnType.LOCAL)
|
||||
dialog.dismissSafe()
|
||||
}
|
||||
}
|
||||
|
||||
LoginForm.Action.Token -> if(data is TootInstance) {
|
||||
DlgTextInput.show(
|
||||
activity,
|
||||
activity.getString(R.string.access_token_or_api_token),
|
||||
null,
|
||||
callback = object : DlgTextInput.Callback {
|
||||
|
||||
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
||||
override fun onOK(
|
||||
dialog_token : Dialog,
|
||||
text : String
|
||||
) {
|
||||
|
||||
// dialog引数が二つあるのに注意
|
||||
activity.checkAccessToken(
|
||||
dialog,
|
||||
dialog_token,
|
||||
instance,
|
||||
text,
|
||||
null
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
override fun onEmptyError() {
|
||||
activity.showToast(true, R.string.token_not_specified)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val errorText = result.error ?: "(no error information)"
|
||||
if(errorText.contains("SSLHandshakeException")
|
||||
&& (Build.VERSION.RELEASE.startsWith("7.0")
|
||||
|| Build.VERSION.RELEASE.startsWith("7.1")
|
||||
&& ! Build.VERSION.RELEASE.startsWith("7.1.")
|
||||
)
|
||||
) {
|
||||
AlertDialog.Builder(activity)
|
||||
.setMessage(errorText + "\n\n" + activity.getString(R.string.ssl_bug_7_0))
|
||||
.setNeutralButton(R.string.close, null)
|
||||
.show()
|
||||
} else {
|
||||
activity.showToast(true, "$errorText ${result.requestInfo}".trim())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun createAccount(
|
||||
activity : ActMain,
|
||||
instance : Host,
|
||||
client_info : JsonObject,
|
||||
dialog_host : Dialog
|
||||
) {
|
||||
DlgCreateAccount(
|
||||
activity,
|
||||
instance
|
||||
) { dialog_create, username, email, password, agreement, reason ->
|
||||
// dialog引数が二つあるのに注意
|
||||
TootTaskRunner(activity).run(instance, object : TootTask {
|
||||
|
||||
var ta : TootAccount? = null
|
||||
var ti : TootInstance? = null
|
||||
|
||||
override suspend fun background(client : TootApiClient) : TootApiResult? {
|
||||
val r1 = client.createUser2Mastodon(
|
||||
client_info,
|
||||
username,
|
||||
email,
|
||||
password,
|
||||
agreement,
|
||||
reason
|
||||
)
|
||||
val ti = r1?.jsonObject ?: return r1
|
||||
|
||||
val misskeyVersion = TootInstance.parseMisskeyVersion(ti)
|
||||
|
||||
val parser = TootParser(
|
||||
activity,
|
||||
linkHelper = LinkHelper.create(instance, misskeyVersion = misskeyVersion)
|
||||
)
|
||||
|
||||
this.ti = TootInstance(parser, ti)
|
||||
|
||||
val access_token = ti.string("access_token")
|
||||
?: return TootApiResult("can't get user access token")
|
||||
|
||||
val r2 = client.getUserCredential(access_token, misskeyVersion = misskeyVersion)
|
||||
this.ta = parser.account(r2?.jsonObject)
|
||||
if(this.ta != null) return r2
|
||||
|
||||
val jsonObject = jsonObject {
|
||||
put("id", EntityId.CONFIRMING.toString())
|
||||
put("username", username)
|
||||
put("acct", username)
|
||||
put("acct", username)
|
||||
put("url", "https://$instance/@$username")
|
||||
}
|
||||
|
||||
this.ta = parser.account(jsonObject)
|
||||
r1.data = jsonObject
|
||||
r1.tokenInfo = ti
|
||||
return r1
|
||||
}
|
||||
|
||||
override suspend fun handleResult(result : TootApiResult?) {
|
||||
val sa : SavedAccount? = null
|
||||
if(activity.afterAccountVerify(result, ta, sa, ti, instance)) {
|
||||
dialog_host.dismissSafe()
|
||||
dialog_create.dismissSafe()
|
||||
}
|
||||
}
|
||||
})
|
||||
}.show()
|
||||
}
|
||||
|
||||
// アカウント設定
|
||||
fun setting(activity : ActMain) {
|
||||
AccountPicker.pick(
|
||||
activity,
|
||||
bAllowPseudo = true,
|
||||
bAuto = true,
|
||||
message = activity.getString(R.string.account_picker_open_setting)
|
||||
) { ai -> ActAccountSetting.open(activity, ai, ActMain.REQUEST_CODE_ACCOUNT_SETTING) }
|
||||
}
|
||||
|
||||
// アカウントを選んでタイムラインカラムを追加
|
||||
fun timeline(
|
||||
activity : ActMain,
|
||||
pos : Int,
|
||||
type : ColumnType,
|
||||
args : Array<out Any> = emptyArray()
|
||||
) {
|
||||
|
||||
AccountPicker.pick(
|
||||
activity,
|
||||
bAllowPseudo = type.bAllowPseudo,
|
||||
bAllowMisskey = type.bAllowMisskey,
|
||||
bAllowMastodon = type.bAllowMastodon,
|
||||
bAuto = true,
|
||||
message = activity.getString(
|
||||
R.string.account_picker_add_timeline_of,
|
||||
type.name1(activity)
|
||||
)
|
||||
) { ai ->
|
||||
when(type) {
|
||||
|
||||
ColumnType.PROFILE -> {
|
||||
val id = ai.loginAccount?.id
|
||||
if(id != null) activity.addColumn(pos, ai, type, id)
|
||||
}
|
||||
|
||||
ColumnType.PROFILE_DIRECTORY ->
|
||||
activity.addColumn(pos, ai, type, ai.apiHost)
|
||||
|
||||
else -> activity.addColumn(pos, ai, type, *args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 投稿画面を開く。初期テキストを指定する
|
||||
fun openPost(
|
||||
activity : ActMain,
|
||||
initial_text : String? = activity.quickTootText
|
||||
) {
|
||||
activity.post_helper.closeAcctPopup()
|
||||
|
||||
val db_id = activity.currentPostTarget?.db_id ?: - 1L
|
||||
if(db_id != - 1L) {
|
||||
ActPost.open(activity, ActMain.REQUEST_CODE_POST, db_id, initial_text = initial_text)
|
||||
} else {
|
||||
AccountPicker.pick(
|
||||
activity,
|
||||
bAllowPseudo = false,
|
||||
bAuto = true,
|
||||
message = activity.getString(R.string.account_picker_toot)
|
||||
) { ai ->
|
||||
ActPost.open(
|
||||
activity,
|
||||
ActMain.REQUEST_CODE_POST,
|
||||
ai.db_id,
|
||||
initial_text = initial_text
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun endorse(
|
||||
activity : ActMain,
|
||||
access_info : SavedAccount,
|
||||
who : TootAccount,
|
||||
bSet : Boolean
|
||||
) {
|
||||
if(access_info.isMisskey) {
|
||||
activity.showToast(false, "This feature is not provided on Misskey account.")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
TootTaskRunner(activity).run(access_info, object : TootTask {
|
||||
|
||||
var relation : UserRelation? = null
|
||||
|
||||
override suspend fun background(client : TootApiClient) : TootApiResult? {
|
||||
val result = client.request(
|
||||
"/api/v1/accounts/${who.id}/" + when(bSet) {
|
||||
true -> "pin"
|
||||
false -> "unpin"
|
||||
},
|
||||
"".toFormRequestBody().toPost()
|
||||
)
|
||||
val jsonObject = result?.jsonObject
|
||||
if(jsonObject != null) {
|
||||
val tr = parseItem(
|
||||
::TootRelationShip,
|
||||
TootParser(client.context, access_info),
|
||||
jsonObject
|
||||
)
|
||||
if(tr != null) {
|
||||
this.relation = saveUserRelation(access_info, tr)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override suspend fun handleResult(result : TootApiResult?) {
|
||||
result ?: return
|
||||
|
||||
if(result.error != null) {
|
||||
activity.showToast(true, result.error)
|
||||
} else {
|
||||
activity.showToast(
|
||||
false, when(bSet) {
|
||||
true -> R.string.endorse_succeeded
|
||||
else -> R.string.remove_endorse_succeeded
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
private val log = LogCategory("Action_Account")
|
||||
|
||||
// アカウントの追加
|
||||
fun add(activity: ActMain) {
|
||||
|
||||
LoginForm.showLoginForm(
|
||||
activity,
|
||||
null
|
||||
) { dialog, instance, action ->
|
||||
TootTaskRunner(activity).run(instance, object : TootTask {
|
||||
|
||||
override suspend fun background(client: TootApiClient): TootApiResult? {
|
||||
return when (action) {
|
||||
|
||||
LoginForm.Action.Existing ->
|
||||
client.authentication1(Pref.spClientName(activity))
|
||||
|
||||
LoginForm.Action.Create ->
|
||||
client.createUser1(Pref.spClientName(activity))
|
||||
|
||||
LoginForm.Action.Pseudo,
|
||||
LoginForm.Action.Token -> {
|
||||
val (ti, ri) = TootInstance.get(client)
|
||||
if (ti != null) ri?.data = ti
|
||||
ri
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun handleResult(result: TootApiResult?) {
|
||||
|
||||
result ?: return // cancelled.
|
||||
|
||||
val data = result.data
|
||||
if (result.error == null && data != null) {
|
||||
when (action) {
|
||||
LoginForm.Action.Existing -> if (data is String) {
|
||||
// ブラウザ用URLが生成された
|
||||
activity.openBrowser(data.toUri())
|
||||
dialog.dismissSafe()
|
||||
return
|
||||
}
|
||||
|
||||
LoginForm.Action.Create -> if (data is JsonObject) {
|
||||
// インスタンスを確認できた
|
||||
createAccount(
|
||||
activity,
|
||||
instance,
|
||||
data,
|
||||
dialog
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
LoginForm.Action.Pseudo -> if (data is TootInstance) {
|
||||
addPseudoAccount(
|
||||
activity,
|
||||
instance,
|
||||
instanceInfo = data
|
||||
) { a ->
|
||||
activity.showToast(false, R.string.server_confirmed)
|
||||
val pos = activity.app_state.columnCount
|
||||
activity.addColumn(pos, a, ColumnType.LOCAL)
|
||||
dialog.dismissSafe()
|
||||
}
|
||||
}
|
||||
|
||||
LoginForm.Action.Token -> if (data is TootInstance) {
|
||||
DlgTextInput.show(
|
||||
activity,
|
||||
activity.getString(R.string.access_token_or_api_token),
|
||||
null,
|
||||
callback = object : DlgTextInput.Callback {
|
||||
|
||||
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
||||
override fun onOK(
|
||||
dialog_token: Dialog,
|
||||
text: String
|
||||
) {
|
||||
|
||||
// dialog引数が二つあるのに注意
|
||||
activity.checkAccessToken(
|
||||
dialog,
|
||||
dialog_token,
|
||||
instance,
|
||||
text,
|
||||
null
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
override fun onEmptyError() {
|
||||
activity.showToast(true, R.string.token_not_specified)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val errorText = result.error ?: "(no error information)"
|
||||
if (errorText.contains("SSLHandshakeException")
|
||||
&& (Build.VERSION.RELEASE.startsWith("7.0")
|
||||
|| Build.VERSION.RELEASE.startsWith("7.1")
|
||||
&& !Build.VERSION.RELEASE.startsWith("7.1.")
|
||||
)
|
||||
) {
|
||||
AlertDialog.Builder(activity)
|
||||
.setMessage(errorText + "\n\n" + activity.getString(R.string.ssl_bug_7_0))
|
||||
.setNeutralButton(R.string.close, null)
|
||||
.show()
|
||||
} else {
|
||||
activity.showToast(true, "$errorText ${result.requestInfo}".trim())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun createAccount(
|
||||
activity: ActMain,
|
||||
apiHost: Host,
|
||||
client_info: JsonObject,
|
||||
dialog_host: Dialog
|
||||
) {
|
||||
DlgCreateAccount(
|
||||
activity,
|
||||
apiHost
|
||||
) { dialog_create, username, email, password, agreement, reason ->
|
||||
// dialog引数が二つあるのに注意
|
||||
TootTaskRunner(activity).run(apiHost, object : TootTask {
|
||||
|
||||
var ta: TootAccount? = null
|
||||
var apDomain: Host? = null
|
||||
|
||||
override suspend fun background(client: TootApiClient): TootApiResult? {
|
||||
val r1 = client.createUser2Mastodon(
|
||||
client_info,
|
||||
username,
|
||||
email,
|
||||
password,
|
||||
agreement,
|
||||
reason
|
||||
)
|
||||
val tokenJson = r1?.jsonObject ?: return r1
|
||||
val misskeyVersion = TootInstance.parseMisskeyVersion(tokenJson)
|
||||
val parser = TootParser(
|
||||
activity,
|
||||
linkHelper = LinkHelper.create(apiHost, misskeyVersion = misskeyVersion)
|
||||
)
|
||||
|
||||
// ここだけMastodon専用
|
||||
val access_token = tokenJson.string("access_token")
|
||||
?: return TootApiResult("can't get user access token")
|
||||
|
||||
client.apiHost = apiHost
|
||||
val (ti, ri) = TootInstance.getEx(client, forceAccessToken = access_token)
|
||||
ti ?: return ri
|
||||
this.apDomain = ti.uri?.let { Host.parse(it) }
|
||||
|
||||
val r2 = client.getUserCredential(access_token, misskeyVersion = misskeyVersion)
|
||||
this.ta = parser.account(r2?.jsonObject)
|
||||
if (this.ta != null) return r2
|
||||
|
||||
val jsonObject = jsonObject {
|
||||
put("id", EntityId.CONFIRMING.toString())
|
||||
put("username", username)
|
||||
put("acct", username)
|
||||
put("url", "https://$apiHost/@$username")
|
||||
}
|
||||
|
||||
this.ta = parser.account(jsonObject)
|
||||
r1.data = jsonObject
|
||||
r1.tokenInfo = tokenJson
|
||||
return r1
|
||||
}
|
||||
|
||||
override suspend fun handleResult(result: TootApiResult?) {
|
||||
val sa: SavedAccount? = null
|
||||
if (activity.afterAccountVerify(result, ta, sa, apiHost, apDomain)) {
|
||||
dialog_host.dismissSafe()
|
||||
dialog_create.dismissSafe()
|
||||
}
|
||||
}
|
||||
})
|
||||
}.show()
|
||||
}
|
||||
|
||||
// アカウント設定
|
||||
fun setting(activity: ActMain) {
|
||||
AccountPicker.pick(
|
||||
activity,
|
||||
bAllowPseudo = true,
|
||||
bAuto = true,
|
||||
message = activity.getString(R.string.account_picker_open_setting)
|
||||
) { ai -> ActAccountSetting.open(activity, ai, ActMain.REQUEST_CODE_ACCOUNT_SETTING) }
|
||||
}
|
||||
|
||||
// アカウントを選んでタイムラインカラムを追加
|
||||
fun timeline(
|
||||
activity: ActMain,
|
||||
pos: Int,
|
||||
type: ColumnType,
|
||||
args: Array<out Any> = emptyArray()
|
||||
) {
|
||||
|
||||
AccountPicker.pick(
|
||||
activity,
|
||||
bAllowPseudo = type.bAllowPseudo,
|
||||
bAllowMisskey = type.bAllowMisskey,
|
||||
bAllowMastodon = type.bAllowMastodon,
|
||||
bAuto = true,
|
||||
message = activity.getString(
|
||||
R.string.account_picker_add_timeline_of,
|
||||
type.name1(activity)
|
||||
)
|
||||
) { ai ->
|
||||
when (type) {
|
||||
|
||||
ColumnType.PROFILE -> {
|
||||
val id = ai.loginAccount?.id
|
||||
if (id != null) activity.addColumn(pos, ai, type, id)
|
||||
}
|
||||
|
||||
ColumnType.PROFILE_DIRECTORY ->
|
||||
activity.addColumn(pos, ai, type, ai.apiHost)
|
||||
|
||||
else -> activity.addColumn(pos, ai, type, *args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 投稿画面を開く。初期テキストを指定する
|
||||
fun openPost(
|
||||
activity: ActMain,
|
||||
initial_text: String? = activity.quickTootText
|
||||
) {
|
||||
activity.post_helper.closeAcctPopup()
|
||||
|
||||
val db_id = activity.currentPostTarget?.db_id ?: -1L
|
||||
if (db_id != -1L) {
|
||||
ActPost.open(activity, ActMain.REQUEST_CODE_POST, db_id, initial_text = initial_text)
|
||||
} else {
|
||||
AccountPicker.pick(
|
||||
activity,
|
||||
bAllowPseudo = false,
|
||||
bAuto = true,
|
||||
message = activity.getString(R.string.account_picker_toot)
|
||||
) { ai ->
|
||||
ActPost.open(
|
||||
activity,
|
||||
ActMain.REQUEST_CODE_POST,
|
||||
ai.db_id,
|
||||
initial_text = initial_text
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun endorse(
|
||||
activity: ActMain,
|
||||
access_info: SavedAccount,
|
||||
who: TootAccount,
|
||||
bSet: Boolean
|
||||
) {
|
||||
if (access_info.isMisskey) {
|
||||
activity.showToast(false, "This feature is not provided on Misskey account.")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
TootTaskRunner(activity).run(access_info, object : TootTask {
|
||||
|
||||
var relation: UserRelation? = null
|
||||
|
||||
override suspend fun background(client: TootApiClient): TootApiResult? {
|
||||
val result = client.request(
|
||||
"/api/v1/accounts/${who.id}/" + when (bSet) {
|
||||
true -> "pin"
|
||||
false -> "unpin"
|
||||
},
|
||||
"".toFormRequestBody().toPost()
|
||||
)
|
||||
val jsonObject = result?.jsonObject
|
||||
if (jsonObject != null) {
|
||||
val tr = parseItem(
|
||||
::TootRelationShip,
|
||||
TootParser(client.context, access_info),
|
||||
jsonObject
|
||||
)
|
||||
if (tr != null) {
|
||||
this.relation = saveUserRelation(access_info, tr)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override suspend fun handleResult(result: TootApiResult?) {
|
||||
result ?: return
|
||||
|
||||
if (result.error != null) {
|
||||
activity.showToast(true, result.error)
|
||||
} else {
|
||||
activity.showToast(
|
||||
false, when (bSet) {
|
||||
true -> R.string.endorse_succeeded
|
||||
else -> R.string.remove_endorse_succeeded
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private val mailRegex =
|
||||
"""\A[a-z0-9_+&*-]+(?:\.[a-z0-9_+&*-]+)*@(?:[a-z0-9-]+\.)+[a-z]{2,12}\z""".toRegex(
|
||||
RegexOption.IGNORE_CASE
|
||||
)
|
||||
|
||||
fun resendConfirmMail(activity: AppCompatActivity, accessInfo: SavedAccount) {
|
||||
DlgConfirmMail(
|
||||
activity,
|
||||
accessInfo
|
||||
) { email ->
|
||||
TootTaskRunner(activity).run(accessInfo, object : TootTask {
|
||||
override suspend fun background(client: TootApiClient): TootApiResult? {
|
||||
email?.let {
|
||||
if (!mailRegex.matches(it))
|
||||
return TootApiResult("email address is not valid.")
|
||||
}
|
||||
|
||||
return client.request(
|
||||
"/api/v1/emails/confirmations",
|
||||
ArrayList<String>().apply {
|
||||
if (email != null) add("email=${email.encodePercent()}")
|
||||
}.joinToString("&").toFormRequestBody().toPost()
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun handleResult(result: TootApiResult?) {
|
||||
result ?: return // cancelled.
|
||||
when (val error = result.error) {
|
||||
null ->
|
||||
activity.showToast(true, R.string.resend_confirm_mail_requested)
|
||||
else ->
|
||||
activity.showToast(true, error)
|
||||
}
|
||||
}
|
||||
})
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -475,7 +475,7 @@ class TootInstance(parser: TootParser, src: JsonObject) {
|
|||
TootParser(
|
||||
client.context,
|
||||
linkHelper = linkHelper ?: LinkHelper.create(
|
||||
hostArg!!,
|
||||
(hostArg ?: client.apiHost)!!,
|
||||
misskeyVersion = parseMisskeyVersion(json)
|
||||
)
|
||||
),
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
package jp.juggler.subwaytooter.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.widget.Button
|
||||
import android.widget.CheckBox
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
|
||||
class DlgConfirmMail(
|
||||
val activity: AppCompatActivity,
|
||||
val accessInfo: SavedAccount,
|
||||
val onClickOk: (email: String?) -> Unit
|
||||
) : View.OnClickListener {
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
private val viewRoot = activity.layoutInflater
|
||||
.inflate(R.layout.dlg_confirm_mail, null, false)
|
||||
|
||||
private val cbUpdateMailAddress: CheckBox = viewRoot.findViewById(R.id.cbUpdateMailAddress)
|
||||
private val etEmail: EditText = viewRoot.findViewById(R.id.etEmail)
|
||||
|
||||
private val dialog = Dialog(activity)
|
||||
|
||||
init {
|
||||
viewRoot.findViewById<TextView>(R.id.tvUserName).text = accessInfo.acct.pretty
|
||||
|
||||
viewRoot.findViewById<TextView>(R.id.tvInstance).text =
|
||||
if (accessInfo.apiHost != accessInfo.apDomain) {
|
||||
"${accessInfo.apiHost.pretty} (${accessInfo.apDomain.pretty})"
|
||||
} else {
|
||||
accessInfo.apiHost.pretty
|
||||
}
|
||||
|
||||
cbUpdateMailAddress.setOnCheckedChangeListener { _, isChecked ->
|
||||
etEmail.isEnabled = isChecked
|
||||
}
|
||||
|
||||
arrayOf(
|
||||
R.id.btnCancel,
|
||||
R.id.btnOk
|
||||
).forEach {
|
||||
viewRoot.findViewById<Button>(it)?.setOnClickListener(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun show() {
|
||||
dialog.setContentView(viewRoot)
|
||||
|
||||
dialog.window?.setLayout(
|
||||
WindowManager.LayoutParams.MATCH_PARENT,
|
||||
WindowManager.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
when (v?.id) {
|
||||
R.id.btnCancel ->
|
||||
dialog.cancel()
|
||||
|
||||
R.id.btnOk ->
|
||||
onClickOk(
|
||||
if (cbUpdateMailAddress.isChecked) etEmail.text.toString().trim() else null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,180 +1,174 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UnusedAttribute"
|
||||
>
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/instance"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvInstance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/description"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/user_name"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etUserName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:hint="@string/user_name_hint"
|
||||
android:inputType="text"
|
||||
android:importantForAutofill="no"
|
||||
tools:ignore="UnusedAttribute"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/email"
|
||||
/>
|
||||
<EditText
|
||||
android:id="@+id/etEmail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:hint="@string/email_hint"
|
||||
android:inputType="text"
|
||||
android:importantForAutofill="no"
|
||||
tools:ignore="TextFields"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/password"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etPassword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:inputType="textPassword"
|
||||
android:importantForAutofill="no"
|
||||
android:hint="@string/password_hint"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/reason_create_account"
|
||||
android:id="@+id/tvReasonCaption"
|
||||
android:labelFor="@+id/etReason"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etReason"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:inputType="text"
|
||||
android:importantForAutofill="no"
|
||||
/>
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnRules"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/instance_rules"
|
||||
android:textAllCaps="false"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/btnTerms"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/privacy_policy"
|
||||
android:textAllCaps="false"
|
||||
/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbAgreement"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/agree_terms"
|
||||
/>
|
||||
<LinearLayout
|
||||
style="?android:attr/buttonBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/instance" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvInstance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/description" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/user_name" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etUserName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:hint="@string/user_name_hint"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="text"
|
||||
tools:ignore="UnusedAttribute" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/email" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etEmail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:hint="@string/email_hint"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="text"
|
||||
tools:ignore="TextFields" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/password" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etPassword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:hint="@string/password_hint"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="textPassword" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvReasonCaption"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:labelFor="@+id/etReason"
|
||||
android:text="@string/reason_create_account" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etReason"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="text" />
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnCancel"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:id="@+id/btnRules"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/cancel"
|
||||
/>
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/instance_rules"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnOk"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:id="@+id/btnTerms"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/ok"
|
||||
/>
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/privacy_policy"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbAgreement"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/agree_terms" />
|
||||
|
||||
<LinearLayout
|
||||
style="?android:attr/buttonBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnCancel"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnOk"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/ok" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/instance" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvInstance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/user_name" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvUserName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:hint="@string/user_name_hint"
|
||||
android:importantForAutofill="no"
|
||||
tools:ignore="UnusedAttribute" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbUpdateMailAddress"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/update_mail_address" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/email" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etEmail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:enabled="false"
|
||||
android:hint="@string/email_hint"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="text"
|
||||
tools:ignore="TextFields" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
style="?android:attr/buttonBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnCancel"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnOk"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/ok" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/confirm_mail_description" />
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
|
@ -1073,5 +1073,9 @@
|
|||
<string name="server_has_no_support_of_visibility">公開範囲\'%1$s\'はこのサーバで使えません</string>
|
||||
<string name="in_app_unicode_emoji">アプリ内蔵のUnicode絵文字を使う(アプリ再起動が必要)</string>
|
||||
<string name="emoji_category_composite_tones">複合トーン</string>
|
||||
<string name="resend_confirm_mail">確認メールの再送…</string>
|
||||
<string name="update_mail_address">登録メールアドレスを変更する</string>
|
||||
<string name="resend_confirm_mail_requested">確認メールの再送を要求しました。</string>
|
||||
<string name="confirm_mail_description">確認メールの再送を要求した後の手順:\n- あなたのメーラーで新着メールが届くのを確認する。\n- メール中の確認リンクを開く。\n- このダイアログを閉じてカラムをリロードする。</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -1087,4 +1087,8 @@
|
|||
<string name="show_emoji_picker_other_category">Show emoji picker other category</string>
|
||||
<string name="in_app_unicode_emoji">use in-app Unicode Emoji (app restart required)</string>
|
||||
<string name="emoji_category_composite_tones">Composite Tones</string>
|
||||
<string name="resend_confirm_mail">Resend confirm mail…</string>
|
||||
<string name="update_mail_address">Update e-mail address</string>
|
||||
<string name="resend_confirm_mail_requested">Resending confirm E-mail was requested.</string>
|
||||
<string name="confirm_mail_description">After requesting resending confirm E-mail,\n- please check the mail on your mailer.\n- open confirm link in the mail.\n- close this dialog and reload column.</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue