外部アプリからシェアした際に送信先インスタンスのサーバ情報をまだキャッシュできていない場合に対応
This commit is contained in:
parent
f7d079eef1
commit
7d3715d8b9
|
@ -22,6 +22,7 @@ import jp.juggler.subwaytooter.actpost.CompletionHelper
|
||||||
import jp.juggler.subwaytooter.actpost.FeaturedTagCache
|
import jp.juggler.subwaytooter.actpost.FeaturedTagCache
|
||||||
import jp.juggler.subwaytooter.actpost.addAttachment
|
import jp.juggler.subwaytooter.actpost.addAttachment
|
||||||
import jp.juggler.subwaytooter.actpost.applyMushroomText
|
import jp.juggler.subwaytooter.actpost.applyMushroomText
|
||||||
|
import jp.juggler.subwaytooter.actpost.launchAddAttachmentChannelReader
|
||||||
import jp.juggler.subwaytooter.actpost.onPickCustomThumbnailImpl
|
import jp.juggler.subwaytooter.actpost.onPickCustomThumbnailImpl
|
||||||
import jp.juggler.subwaytooter.actpost.onPostAttachmentCompleteImpl
|
import jp.juggler.subwaytooter.actpost.onPostAttachmentCompleteImpl
|
||||||
import jp.juggler.subwaytooter.actpost.openAttachment
|
import jp.juggler.subwaytooter.actpost.openAttachment
|
||||||
|
@ -197,6 +198,13 @@ class ActPost : AppCompatActivity(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AddAttachmentChannelItem(
|
||||||
|
val uri: Uri,
|
||||||
|
val mimeTypeArg: String?,
|
||||||
|
)
|
||||||
|
|
||||||
|
val addAttachmentChannel = Channel<AddAttachmentChannelItem>(capacity = Channel.BUFFERED)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
@ -220,6 +228,8 @@ class ActPost : AppCompatActivity(),
|
||||||
|
|
||||||
progressChannel = Channel(capacity = Channel.CONFLATED)
|
progressChannel = Channel(capacity = Channel.CONFLATED)
|
||||||
|
|
||||||
|
launchAddAttachmentChannelReader()
|
||||||
|
|
||||||
initUI()
|
initUI()
|
||||||
|
|
||||||
// 進捗表示チャネルの回収コルーチン
|
// 進捗表示チャネルの回収コルーチン
|
||||||
|
@ -255,6 +265,7 @@ class ActPost : AppCompatActivity(),
|
||||||
}
|
}
|
||||||
completionHelper.onDestroy()
|
completionHelper.onDestroy()
|
||||||
attachmentUploader.onActivityDestroy()
|
attachmentUploader.onActivityDestroy()
|
||||||
|
addAttachmentChannel.close()
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ import androidx.appcompat.app.AlertDialog
|
||||||
import jp.juggler.subwaytooter.ActPost
|
import jp.juggler.subwaytooter.ActPost
|
||||||
import jp.juggler.subwaytooter.R
|
import jp.juggler.subwaytooter.R
|
||||||
import jp.juggler.subwaytooter.api.ApiTask
|
import jp.juggler.subwaytooter.api.ApiTask
|
||||||
|
import jp.juggler.subwaytooter.api.TootApiCallback
|
||||||
|
import jp.juggler.subwaytooter.api.TootApiClient
|
||||||
import jp.juggler.subwaytooter.api.TootApiResult
|
import jp.juggler.subwaytooter.api.TootApiResult
|
||||||
import jp.juggler.subwaytooter.api.entity.InstanceType
|
import jp.juggler.subwaytooter.api.entity.InstanceType
|
||||||
import jp.juggler.subwaytooter.api.entity.ServiceType
|
import jp.juggler.subwaytooter.api.entity.ServiceType
|
||||||
|
@ -44,6 +46,9 @@ import jp.juggler.util.log.withCaption
|
||||||
import jp.juggler.util.network.toPutRequestBuilder
|
import jp.juggler.util.network.toPutRequestBuilder
|
||||||
import jp.juggler.util.ui.isLiveActivity
|
import jp.juggler.util.ui.isLiveActivity
|
||||||
import jp.juggler.util.ui.vg
|
import jp.juggler.util.ui.vg
|
||||||
|
import kotlinx.coroutines.CancellationException
|
||||||
|
import kotlinx.coroutines.channels.ClosedReceiveChannelException
|
||||||
|
import java.nio.channels.ClosedChannelException
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
private val log = LogCategory("ActPostAttachment")
|
private val log = LogCategory("ActPostAttachment")
|
||||||
|
@ -126,34 +131,77 @@ fun ActPost.openAttachment() {
|
||||||
fun ActPost.addAttachment(
|
fun ActPost.addAttachment(
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
mimeTypeArg: String? = null,
|
mimeTypeArg: String? = null,
|
||||||
// onUploadEnd: () -> Unit = {},
|
|
||||||
) {
|
) {
|
||||||
|
val item = ActPost.AddAttachmentChannelItem(uri = uri, mimeTypeArg = mimeTypeArg)
|
||||||
|
for (nTry in 1..10) {
|
||||||
|
try {
|
||||||
|
val channelResult = addAttachmentChannel.trySend(item)
|
||||||
|
when {
|
||||||
|
channelResult.isSuccess -> return
|
||||||
|
channelResult.isClosed -> return
|
||||||
|
channelResult.isFailure -> continue
|
||||||
|
}
|
||||||
|
} catch (ex: Throwable) {
|
||||||
|
log.e(ex, "addAttachmentChannel.trySend failed.")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun ActPost.getInstance(): TootInstance {
|
||||||
|
val client = TootApiClient(
|
||||||
|
context = applicationContext,
|
||||||
|
callback = object : TootApiCallback {
|
||||||
|
override suspend fun isApiCancelled() = isFinishing || isDestroyed
|
||||||
|
}
|
||||||
|
).apply {
|
||||||
|
this.account = this@getInstance.account
|
||||||
|
}
|
||||||
|
val (instance, ri) = TootInstance.get(client = client)
|
||||||
|
if (instance != null) return instance
|
||||||
|
when (ri) {
|
||||||
|
null -> throw CancellationException()
|
||||||
|
else -> error("missing instance information. ${ri.error}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun ActPost.addAttachmentSuspend(
|
||||||
|
uri: Uri,
|
||||||
|
mimeTypeArg: String? = null,
|
||||||
|
) {
|
||||||
|
val actPost = this
|
||||||
val account = this.account
|
val account = this.account
|
||||||
if (account == null) {
|
|
||||||
dialogOrToast(R.string.account_select_please)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val instance = TootInstance.getCached(account)
|
|
||||||
if (instance == null) {
|
|
||||||
dialogOrToast("missing instance imformation.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val mimeType = uri.resolveMimeType(mimeTypeArg, this)
|
val mimeType = uri.resolveMimeType(mimeTypeArg, this)
|
||||||
?.notEmpty()
|
?.notEmpty()
|
||||||
|
|
||||||
val isReply = states.inReplyToId != null
|
val isReply = states.inReplyToId != null
|
||||||
|
|
||||||
when {
|
when {
|
||||||
|
actPost.isFinishing || actPost.isDestroyed -> {
|
||||||
|
dialogOrToast("actPost is finishing or destroyed.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
attachmentList.size >= 4 -> {
|
attachmentList.size >= 4 -> {
|
||||||
dialogOrToast(R.string.attachment_too_many)
|
dialogOrToast(R.string.attachment_too_many)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
account == null -> {
|
||||||
|
dialogOrToast(R.string.account_select_please)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
mimeType == null -> {
|
mimeType == null -> {
|
||||||
dialogOrToast(R.string.mime_type_missing)
|
dialogOrToast(R.string.mime_type_missing)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val instance = getInstance()
|
||||||
|
|
||||||
|
when {
|
||||||
instance.instanceType == InstanceType.Pixelfed && isReply -> {
|
instance.instanceType == InstanceType.Pixelfed && isReply -> {
|
||||||
AttachmentUploader.log.e("pixelfed_does_not_allow_reply_with_media")
|
AttachmentUploader.log.e("pixelfed_does_not_allow_reply_with_media")
|
||||||
dialogOrToast(R.string.pixelfed_does_not_allow_reply_with_media)
|
dialogOrToast(R.string.pixelfed_does_not_allow_reply_with_media)
|
||||||
|
@ -169,10 +217,10 @@ fun ActPost.addAttachment(
|
||||||
attachmentUploader.addRequest(
|
attachmentUploader.addRequest(
|
||||||
AttachmentRequest(
|
AttachmentRequest(
|
||||||
context = applicationContext,
|
context = applicationContext,
|
||||||
account = account,
|
account = account!!,
|
||||||
pa = pa,
|
pa = pa,
|
||||||
uri = uri,
|
uri = uri,
|
||||||
mimeType = mimeType,
|
mimeType = mimeType!!,
|
||||||
instance = instance,
|
instance = instance,
|
||||||
mediaConfig = mediaConfig,
|
mediaConfig = mediaConfig,
|
||||||
serverMaxSqPixel = mediaConfig?.int("image_matrix_limit")?.takeIf { it > 0 },
|
serverMaxSqPixel = mediaConfig?.int("image_matrix_limit")?.takeIf { it > 0 },
|
||||||
|
@ -194,6 +242,32 @@ fun ActPost.addAttachment(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun ActPost.launchAddAttachmentChannelReader() {
|
||||||
|
launchMain {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
val item = addAttachmentChannel.receive()
|
||||||
|
addAttachmentSuspend(item.uri, item.mimeTypeArg)
|
||||||
|
} catch (ex: Throwable) {
|
||||||
|
when (ex) {
|
||||||
|
is CancellationException -> {
|
||||||
|
log.i("launchAddAttachmentChannelReader: cancelled.")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
is ClosedChannelException, is ClosedReceiveChannelException -> {
|
||||||
|
log.i("launchAddAttachmentChannelReader: channel closed.")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
else ->
|
||||||
|
log.e(ex,"launchAddAttachmentChannelReader: addAttachmentSuspend raise error. retry…")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun ActPost.onPostAttachmentCompleteImpl(pa: PostAttachment) {
|
fun ActPost.onPostAttachmentCompleteImpl(pa: PostAttachment) {
|
||||||
// この添付メディアはリストにない
|
// この添付メディアはリストにない
|
||||||
if (!attachmentList.contains(pa)) {
|
if (!attachmentList.contains(pa)) {
|
||||||
|
|
Loading…
Reference in New Issue