kopia lustrzana https://github.com/vitorpamplona/amethyst
Support for video uploads.
rodzic
cb20e14822
commit
dd9ea5f27e
|
@ -1,8 +1,11 @@
|
|||
package com.vitorpamplona.amethyst.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build.VERSION.SDK_INT
|
||||
import android.os.Bundle
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Surface
|
||||
|
@ -94,3 +97,13 @@ class MainActivity : FragmentActivity() {
|
|||
ServiceManager.cleanUp()
|
||||
}
|
||||
}
|
||||
|
||||
class GetMediaActivityResultContract : ActivityResultContracts.GetContent() {
|
||||
|
||||
override fun createIntent(context: Context, input: String): Intent {
|
||||
return super.createIntent(context, input).apply {
|
||||
// Force only images and videos to be selectable
|
||||
putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,13 +19,16 @@ object ImageUploader {
|
|||
onError: (Throwable) -> Unit
|
||||
) {
|
||||
val contentType = contentResolver.getType(uri)
|
||||
val category = contentType?.toMediaType()?.toString()?.split("/")?.get(0) ?: "image"
|
||||
|
||||
val url = if (category == "image") "https://api.imgur.com/3/image" else "https://api.imgur.com/3/upload"
|
||||
|
||||
val client = OkHttpClient.Builder().build()
|
||||
|
||||
val requestBody: RequestBody = MultipartBody.Builder()
|
||||
.setType(MultipartBody.FORM)
|
||||
.addFormDataPart(
|
||||
"image",
|
||||
category,
|
||||
"${UUID.randomUUID()}",
|
||||
object : RequestBody() {
|
||||
override fun contentType(): MediaType? =
|
||||
|
@ -46,7 +49,7 @@ object ImageUploader {
|
|||
val request: Request = Request.Builder()
|
||||
.header("Authorization", "Client-ID e6aea87296f3f96")
|
||||
.header("User-Agent", "Amethyst/${BuildConfig.VERSION_NAME}")
|
||||
.url("https://api.imgur.com/3/image")
|
||||
.url(url)
|
||||
.post(requestBody)
|
||||
.build()
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ import com.vitorpamplona.amethyst.service.model.TextNoteEvent
|
|||
import com.vitorpamplona.amethyst.service.nip19.Nip19
|
||||
import com.vitorpamplona.amethyst.ui.components.isValidURL
|
||||
import com.vitorpamplona.amethyst.ui.components.noProtocolUrlValidator
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
@ -140,12 +142,16 @@ class NewPostViewModel : ViewModel() {
|
|||
onSuccess = { imageUrl ->
|
||||
isUploadingImage = false
|
||||
message = TextFieldValue(message.text + "\n\n" + imageUrl)
|
||||
urlPreview = findUrlInMessage()
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
delay(2000)
|
||||
urlPreview = findUrlInMessage()
|
||||
}
|
||||
},
|
||||
onError = {
|
||||
isUploadingImage = false
|
||||
viewModelScope.launch {
|
||||
imageUploadingError.emit("Failed to upload the image")
|
||||
imageUploadingError.emit("Failed to upload the image / video")
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.vitorpamplona.amethyst.ui.actions
|
|||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
import androidx.compose.animation.core.animateFloat
|
||||
import androidx.compose.animation.core.infiniteRepeatable
|
||||
|
@ -28,6 +27,7 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
|||
import com.google.accompanist.permissions.isGranted
|
||||
import com.google.accompanist.permissions.rememberPermissionState
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.GetMediaActivityResultContract
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
@OptIn(ExperimentalPermissionsApi::class)
|
||||
|
@ -150,7 +150,7 @@ fun GallerySelect(
|
|||
) {
|
||||
var hasLaunched by remember { mutableStateOf(AtomicBoolean(false)) }
|
||||
val launcher = rememberLauncherForActivityResult(
|
||||
contract = ActivityResultContracts.GetContent(),
|
||||
contract = GetMediaActivityResultContract(),
|
||||
onResult = { uri: Uri? ->
|
||||
onImageUri(uri)
|
||||
hasLaunched.set(false)
|
||||
|
@ -161,7 +161,7 @@ fun GallerySelect(
|
|||
fun LaunchGallery() {
|
||||
SideEffect {
|
||||
if (!hasLaunched.getAndSet(true)) {
|
||||
launcher.launch("image/*")
|
||||
launcher.launch("*/*")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue