Downloads go into sub-directory, fix text overflow in downloads modal

This commit is contained in:
advplyr 2021-09-16 19:41:07 -05:00
parent 8232cfb796
commit 87f1deff19
6 changed files with 69 additions and 84 deletions

View file

@ -10,8 +10,8 @@ android {
applicationId "com.audiobookshelf.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 10
versionName "0.8.1-beta"
versionCode 11
versionName "0.8.2-beta"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.

View file

@ -7,7 +7,6 @@ import android.net.Uri
import android.os.Environment
import android.provider.MediaStore
import android.util.Log
import android.widget.Toast
import com.getcapacitor.JSObject
import com.getcapacitor.Plugin
import com.getcapacitor.PluginCall
@ -23,10 +22,10 @@ class AudioDownloader : Plugin() {
lateinit var mainActivity:MainActivity
lateinit var downloadManager:DownloadManager
data class AudiobookDownload(val url: String, val filename:String, val downloadId: Long)
data class AudiobookDownload(val url: String, val filename: String, val downloadId: Long)
var downloads:MutableList<AudiobookDownload> = mutableListOf()
data class CoverItem(val name:String, val coverUrl:String)
data class CoverItem(val name: String, val coverUrl: String)
data class AudiobookItem(val id: Long, val uri: Uri, val name: String, val size: Int, val duration: Int, val coverUrl: String) {
fun toJSObject() : JSObject {
var obj = JSObject()
@ -76,7 +75,8 @@ class AudioDownloader : Plugin() {
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.SIZE,
MediaStore.Audio.Media.IS_AUDIOBOOK
MediaStore.Audio.Media.IS_AUDIOBOOK,
MediaStore.Audio.Media.RELATIVE_PATH
)
var _audiobookItems:MutableList<AudiobookItem> = mutableListOf()
@ -99,6 +99,7 @@ class AudioDownloader : Plugin() {
cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)
val sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)
val isAudiobookColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.IS_AUDIOBOOK)
var relativePathColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.RELATIVE_PATH)
while (cursor.moveToNext()) {
val id = cursor.getLong(idColumn)
@ -106,6 +107,7 @@ class AudioDownloader : Plugin() {
val duration = cursor.getInt(durationColumn)
val size = cursor.getInt(sizeColumn)
var isAudiobook = cursor.getInt(isAudiobookColumn)
var relativePath = cursor.getString(relativePathColumn)
if (isAudiobook == 1) {
val contentUri: Uri = ContentUris.withAppendedId(
@ -113,7 +115,7 @@ class AudioDownloader : Plugin() {
id
)
Log.d(tag, "Got Content FRom MEdia STORE $id $contentUri, Name: $name, Dur: $duration, Size: $size")
Log.d(tag, "Got Content FRom MEdia STORE $id $contentUri, Name: $name, Dur: $duration, Size: $size, relativePath: $relativePath")
var audiobookId = File(name).nameWithoutExtension
var coverItem:CoverItem? = covers.find{it.name == audiobookId}
var coverUrl = coverItem?.coverUrl ?: ""
@ -177,6 +179,7 @@ class AudioDownloader : Plugin() {
@PluginMethod
fun downloadCover(call: PluginCall) {
var audiobookId = call.data.getString("audiobookId", "audiobook").toString()
var url = call.data.getString("downloadUrl", "unknown").toString()
var title = call.data.getString("title", "Cover").toString()
var filename = call.data.getString("filename", "audiobook.jpg").toString()
@ -187,7 +190,10 @@ class AudioDownloader : Plugin() {
dlRequest.setTitle("Cover Art: $title")
dlRequest.setDescription("Cover art for audiobook")
dlRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION)
dlRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_AUDIOBOOKS, filename)
var file:File = File(audiobookId, filename)
Log.d(tag, "FILE ${file.path} | ${file.canonicalPath}")
dlRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_AUDIOBOOKS, file.path)
var downloadId = downloadManager.enqueue(dlRequest)
var progressReceiver : (prog: Long) -> Unit = { prog: Long ->
@ -212,6 +218,7 @@ class AudioDownloader : Plugin() {
@PluginMethod
fun download(call: PluginCall) {
var audiobookId = call.data.getString("audiobookId", "audiobook").toString()
var url = call.data.getString("downloadUrl", "unknown").toString()
var title = call.data.getString("title", "Audiobook").toString()
var filename = call.data.getString("filename", "audiobook.mp3").toString()
@ -223,7 +230,9 @@ class AudioDownloader : Plugin() {
dlRequest.setDescription("Downloading to Audiobooks directory")
dlRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION)
dlRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_AUDIOBOOKS, filename)
var file:File = File(audiobookId, filename)
Log.d(tag, "FILE ${file.path} | ${file.canonicalPath}")
dlRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_AUDIOBOOKS, file.path)
var downloadId = downloadManager.enqueue(dlRequest)
@ -251,12 +260,31 @@ class AudioDownloader : Plugin() {
}
@PluginMethod
fun delete(call:PluginCall) {
fun delete(call: PluginCall) {
var audiobookId = call.data.getString("audiobookId", "audiobook").toString()
var filename = call.data.getString("filename", "audiobook.mp3").toString()
var url = call.data.getString("url", "").toString()
var coverUrl = call.data.getString("coverUrl", "").toString()
Log.d(tag, "Called delete file $filename $url")
// Does Not Work
// var audiobookDirRoot = activity.applicationContext.getExternalFilesDir(Environment.DIRECTORY_AUDIOBOOKS)
// Log.d(tag, "AUDIOBOOK DIR ROOT $audiobookDirRoot")
// var result = audiobookDirRoot?.deleteRecursively()
// Log.d(tag, "DONE DELETING FOLDER $result")
// Does Not Work
// var audiobookDir = File(audiobookDirRoot, audiobookId + "/")
// Log.d(tag, "Delete Audiobook DIR ${audiobookDir.path} is dir ${audiobookDir.isDirectory}")
// var result = audiobookDir.deleteRecursively()
//
// Does Not Work
// var audiobookDir = activity.applicationContext.getExternalFilesDir(Environment.DIRECTORY_AUDIOBOOKS)
// Log.d(tag, "AUDIOBOOK DIR ${audiobookDir?.path}")
// var dir = File(audiobookDir, "$audiobookId/")
// Log.d(tag, "DIR DIR ${dir.path}")
// var res = dir.delete()
// Log.d(tag, "DELETED $res")
var contentResolver = activity.applicationContext.contentResolver
contentResolver.delete(Uri.parse(url), null, null)
@ -268,7 +296,7 @@ class AudioDownloader : Plugin() {
call.resolve()
}
internal class DownloadProgressUpdater(private val manager: DownloadManager, private val downloadId: Long, private var receiver:(Long) -> Unit, private var doneReceiver:(Boolean) -> Unit) : Thread() {
internal class DownloadProgressUpdater(private val manager: DownloadManager, private val downloadId: Long, private var receiver: (Long) -> Unit, private var doneReceiver: (Boolean) -> Unit) : Thread() {
private val query: DownloadManager.Query = DownloadManager.Query()
private var totalBytes: Int = 0
private var TAG = "DownloadProgressUpdater"

View file

@ -11,7 +11,7 @@
<template v-for="download in downloadsDownloading">
<li :key="download.id" class="text-gray-400 select-none relative px-4 py-5 border-b border-white border-opacity-10 bg-black bg-opacity-10">
<div class="flex items-center justify-center">
<div>
<div class="w-3/4">
<span class="text-xs">({{ downloadingProgress[download.id] || 0 }}%) {{ download.isPreparing ? 'Preparing' : 'Downloading' }}...</span>
<p class="font-normal truncate text-sm">{{ download.audiobook.book.title }}</p>
</div>
@ -28,7 +28,7 @@
<div class="flex items-center justify-center">
<img v-if="download.cover" :src="download.cover" class="w-10 h-16 object-contain" />
<img v-else src="/book_placeholder.jpg" class="w-10 h-16 object-contain" />
<div class="pl-2">
<div class="pl-2 w-1/2">
<p class="font-normal truncate text-sm">{{ download.audiobook.book.title }}</p>
<p class="font-normal truncate text-xs text-gray-400">{{ download.audiobook.book.author }}</p>
</div>
@ -48,7 +48,11 @@
<template v-for="download in orphanDownloads">
<li :key="download.id" class="text-gray-50 select-none relative cursor-pointer px-4 py-5 border-b border-white border-opacity-10">
<div class="flex items-center justify-center">
<span class="font-normal block truncate text-sm">{{ download.filename }}</span>
<div class="w-3/4">
<span class="text-xs text-gray-400">Unknown Audio File</span>
<p class="font-normal truncate text-sm">{{ download.filename }}</p>
</div>
<!-- <span class="font-normal block truncate text-sm pr-2">{{ download.filename }}</span> -->
<div class="flex-grow" />
<div class="shadow-sm text-warning flex items-center justify-center rounded-full">
<span class="material-icons">error_outline</span>
@ -94,27 +98,35 @@ export default {
},
orphanDownloads() {
return this.$store.state.downloads.orphanDownloads
// return [
// {
// id: 'asdf',
// filename: 'Test Title 1 another long title on the downloading widget.jpg'
// }
// ]
},
downloads() {
return this.$store.state.downloads.downloads
// return [
// {
// id: 'asdf1',
// title: 'Test Title 1',
// author: 'Test Author 1',
// audiobook: {
// book: {
// title: 'Test Title 1 another long title on the downloading widget',
// author: 'Test Author 1'
// }
// },
// isDownloading: true
// },
// {
// id: 'asdf2',
// title: 'Test Title 2',
// author: 'Author 2',
// audiobook: {
// book: {
// title: 'Test Title 2',
// author: 'Test Author 2 long test author to test the overflow capabilities'
// }
// },
// isReady: true
// },
// {
// id: 'asdf3',
// name: 'asdf.mp3',
// isReady: false,
// isDownloading: false
// }
// ]
}

View file

@ -247,7 +247,7 @@ export default {
}
if (download.contentUrl) {
await AudioDownloader.delete({ filename: download.filename, url: download.contentUrl, coverUrl: download.coverUrl })
await AudioDownloader.delete({ audiobookId: download.id, filename: download.filename, url: download.contentUrl, coverUrl: download.coverUrl })
}
this.$store.commit('downloads/removeDownload', download)
},
@ -268,63 +268,6 @@ export default {
})
AudioDownloader.load()
},
// parseSemver(ver) {
// if (!ver) return null
// var groups = ver.match(/^v((([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)$/)
// if (groups && groups.length > 6) {
// var total = Number(groups[3]) * 100 + Number(groups[4]) * 10 + Number(groups[5])
// if (isNaN(total)) {
// console.warn('Invalid version total', groups[3], groups[4], groups[5])
// return null
// }
// return {
// total,
// version: groups[2],
// major: Number(groups[3]),
// minor: Number(groups[4]),
// patch: Number(groups[5]),
// preRelease: groups[6] || null
// }
// } else {
// console.warn('Invalid semver string', ver)
// }
// return null
// },
// checkForUpdateWebVersion() {
// if (!this.$config.version) {
// return
// }
// var currVerObj = this.parseSemver(this.$config.version)
// if (!currVerObj) {
// console.error('Invalid version', this.$config.version)
// return
// }
// console.log('Check for update, your version:', currVerObj.version)
// this.$store.commit('setCurrentVersion', currVerObj)
// var largestVer = null
// this.$axios.$get(`https://api.github.com/repos/advplyr/audiobookshelf-app/tags`).then((tags) => {
// if (tags && tags.length) {
// tags.forEach((tag) => {
// var verObj = this.parseSemver(tag.name)
// if (verObj) {
// if (!largestVer || largestVer.total < verObj.total) {
// largestVer = verObj
// }
// }
// })
// }
// })
// if (!largestVer) {
// console.error('No valid version tags to compare with')
// return
// }
// this.$store.commit('setLatestVersion', largestVer)
// if (largestVer.total > currVerObj.total) {
// console.log('Has Update!', largestVer.version)
// this.$store.commit('setHasUpdate', true)
// }
// }
async setupNetworkListener() {
var status = await Network.getStatus()
console.log('Network status', status.connected, status.connectionType)

View file

@ -1,6 +1,6 @@
{
"name": "audiobookshelf-app",
"version": "v0.8.1-beta",
"version": "v0.8.2-beta",
"author": "advplyr",
"scripts": {
"dev": "nuxt --hostname localhost --port 1337",

View file

@ -286,6 +286,7 @@ export default {
var extname = Path.extname(coverUrl) || '.jpg'
var downloadRequestPayload = {
audiobookId: download.id,
downloadUrl: coverUrl,
filename: `${download.id}${extname}`,
title: download.audiobook.book.title
@ -310,6 +311,7 @@ export default {
console.log('Starting Download URL', url)
var downloadRequestPayload = {
audiobookId: download.id,
filename: download.filename,
downloadUrl: url,
title: download.audiobook.book.title