Add support for uploading audio attachments (#1630)
* Add support for audio attachments. Partially addresses #1337 * Register Tusky as a target for audio sharing * Use icon with textColorTertiary for audio preview
This commit is contained in:
parent
a7c1345085
commit
9dccd06a06
|
@ -89,6 +89,13 @@
|
|||
|
||||
<data android:mimeType="video/*" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="audio/*" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.service.chooser.chooser_target_service"
|
||||
|
|
|
@ -176,7 +176,7 @@ class ComposeActivity : BaseActivity(),
|
|||
* instance state will be re-queued. */
|
||||
val type = intent.type
|
||||
if (type != null) {
|
||||
if (type.startsWith("image/") || type.startsWith("video/")) {
|
||||
if (type.startsWith("image/") || type.startsWith("video/") || type.startsWith("audio/")) {
|
||||
val uriList = ArrayList<Uri>()
|
||||
if (intent.action != null) {
|
||||
when (intent.action) {
|
||||
|
@ -323,7 +323,7 @@ class ComposeActivity : BaseActivity(),
|
|||
combineOptionalLiveData(viewModel.media, viewModel.poll) { media, poll ->
|
||||
val active = poll == null
|
||||
&& media!!.size != 4
|
||||
&& media.firstOrNull()?.type != QueuedMedia.Type.VIDEO
|
||||
&& (media.isEmpty() || media.first().type == QueuedMedia.Type.IMAGE)
|
||||
enableButton(composeAddMediaButton, active, active)
|
||||
enablePollButton(media.isNullOrEmpty())
|
||||
}.subscribe()
|
||||
|
@ -813,7 +813,7 @@ class ComposeActivity : BaseActivity(),
|
|||
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
|
||||
val mimeTypes = arrayOf("image/*", "video/*")
|
||||
val mimeTypes = arrayOf("image/*", "video/*", "audio/*")
|
||||
intent.type = "*/*"
|
||||
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
|
||||
startActivityForResult(intent, MEDIA_PICK_RESULT)
|
||||
|
@ -856,6 +856,9 @@ class ComposeActivity : BaseActivity(),
|
|||
is VideoSizeException -> {
|
||||
R.string.error_video_upload_size
|
||||
}
|
||||
is AudioSizeException -> {
|
||||
R.string.error_audio_upload_size
|
||||
}
|
||||
is VideoOrImageException -> {
|
||||
R.string.error_media_upload_image_or_video
|
||||
}
|
||||
|
@ -980,7 +983,7 @@ class ComposeActivity : BaseActivity(),
|
|||
val description: String? = null
|
||||
) {
|
||||
enum class Type {
|
||||
IMAGE, VIDEO;
|
||||
IMAGE, VIDEO, AUDIO;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1036,7 +1039,7 @@ class ComposeActivity : BaseActivity(),
|
|||
|
||||
@JvmStatic
|
||||
fun canHandleMimeType(mimeType: String?): Boolean {
|
||||
return mimeType != null && (mimeType.startsWith("image/") || mimeType.startsWith("video/") || mimeType == "text/plain")
|
||||
return mimeType != null && (mimeType.startsWith("image/") || mimeType.startsWith("video/") || mimeType.startsWith("audio/") || mimeType == "text/plain")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ class ComposeViewModel
|
|||
mediaUploader.prepareMedia(uri)
|
||||
.map { (type, uri, size) ->
|
||||
val mediaItems = media.value!!
|
||||
if (type == QueuedMedia.Type.VIDEO
|
||||
if (type != QueuedMedia.Type.IMAGE
|
||||
&& mediaItems.isNotEmpty()
|
||||
&& mediaItems[0].type == QueuedMedia.Type.IMAGE) {
|
||||
throw VideoOrImageException()
|
||||
|
@ -388,6 +388,7 @@ class ComposeViewModel
|
|||
val mediaType = when (a.type) {
|
||||
Attachment.Type.VIDEO, Attachment.Type.GIFV -> QueuedMedia.Type.VIDEO
|
||||
Attachment.Type.UNKNOWN, Attachment.Type.IMAGE -> QueuedMedia.Type.IMAGE
|
||||
Attachment.Type.AUDIO -> QueuedMedia.Type.AUDIO
|
||||
else -> QueuedMedia.Type.IMAGE
|
||||
}
|
||||
addUploadedMedia(a.id, mediaType, a.url.toUri(), a.description)
|
||||
|
|
|
@ -69,12 +69,17 @@ class MediaPreviewAdapter(
|
|||
val item = differ.currentList[position]
|
||||
holder.progressImageView.setChecked(!item.description.isNullOrEmpty())
|
||||
holder.progressImageView.setProgress(item.uploadPercent)
|
||||
if (item.type == ComposeActivity.QueuedMedia.Type.AUDIO) {
|
||||
// TODO: Fancy waveform display?
|
||||
holder.progressImageView.setImageResource(R.drawable.ic_music_box_preview_24dp)
|
||||
} else {
|
||||
Glide.with(holder.itemView.context)
|
||||
.load(item.uri)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontAnimate()
|
||||
.into(holder.progressImageView)
|
||||
}
|
||||
}
|
||||
|
||||
private val differ = AsyncListDiffer(this, object : DiffUtil.ItemCallback<ComposeActivity.QueuedMedia>() {
|
||||
override fun areItemsTheSame(oldItem: ComposeActivity.QueuedMedia, newItem: ComposeActivity.QueuedMedia): Boolean {
|
||||
|
|
|
@ -63,6 +63,7 @@ interface MediaUploader {
|
|||
fun uploadMedia(media: QueuedMedia): Observable<UploadEvent>
|
||||
}
|
||||
|
||||
class AudioSizeException : Exception()
|
||||
class VideoSizeException : Exception()
|
||||
class MediaTypeException : Exception()
|
||||
class CouldNotOpenFileException : Exception()
|
||||
|
@ -128,6 +129,12 @@ class MediaUploaderImpl(
|
|||
"image" -> {
|
||||
PreparedMedia(QueuedMedia.Type.IMAGE, uri, mediaSize)
|
||||
}
|
||||
"audio" -> {
|
||||
if (mediaSize > STATUS_AUDIO_SIZE_LIMIT) {
|
||||
throw AudioSizeException()
|
||||
}
|
||||
PreparedMedia(QueuedMedia.Type.AUDIO, uri, mediaSize)
|
||||
}
|
||||
else -> {
|
||||
throw MediaTypeException()
|
||||
}
|
||||
|
@ -196,6 +203,7 @@ class MediaUploaderImpl(
|
|||
private companion object {
|
||||
private const val TAG = "MediaUploaderImpl"
|
||||
private const val STATUS_VIDEO_SIZE_LIMIT = 41943040 // 40MiB
|
||||
private const val STATUS_AUDIO_SIZE_LIMIT = 41943040 // 40MiB
|
||||
private const val STATUS_IMAGE_SIZE_LIMIT = 8388608 // 8MiB
|
||||
private const val STATUS_IMAGE_PIXEL_SIZE_LIMIT = 16777216 // 4096^2 Pixels
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path android:fillColor="?android:textColorTertiary" android:pathData="M16,9H13V14.5A2.5,2.5 0 0,1 10.5,17A2.5,2.5 0 0,1 8,14.5A2.5,2.5 0 0,1 10.5,12C11.07,12 11.58,12.19 12,12.5V7H16M19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3Z" />
|
||||
</vector>
|
|
@ -12,6 +12,7 @@
|
|||
<string name="error_compose_character_limit">The status is too long!</string>
|
||||
<string name="error_image_upload_size">The file must be less than 8MB.</string>
|
||||
<string name="error_video_upload_size">Video files must be less than 40MB.</string>
|
||||
<string name="error_audio_upload_size">Audio files must be less than 40MB.</string>
|
||||
<string name="error_media_upload_type">That type of file cannot be uploaded.</string>
|
||||
<string name="error_media_upload_opening">That file could not be opened.</string>
|
||||
<string name="error_media_upload_permission">Permission to read media is required.</string>
|
||||
|
|
Loading…
Reference in New Issue