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
main
Levi Bard 4 years ago committed by Konrad Pozniak
parent 46b997a642
commit 6c592b6723
  1. 7
      app/src/main/AndroidManifest.xml
  2. 13
      app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt
  3. 3
      app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeViewModel.kt
  4. 15
      app/src/main/java/com/keylesspalace/tusky/components/compose/MediaPreviewAdapter.kt
  5. 8
      app/src/main/java/com/keylesspalace/tusky/components/compose/MediaUploader.kt
  6. 8
      app/src/main/res/drawable/ic_music_box_preview_24dp.xml
  7. 1
      app/src/main/res/values/strings.xml

@ -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,11 +69,16 @@ class MediaPreviewAdapter(
val item = differ.currentList[position]
holder.progressImageView.setChecked(!item.description.isNullOrEmpty())
holder.progressImageView.setProgress(item.uploadPercent)
Glide.with(holder.itemView.context)
.load(item.uri)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.dontAnimate()
.into(holder.progressImageView)
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>() {

@ -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…
Cancel
Save