mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-08-08 21:08:43 +02:00
Add translation strings for download dialogs and notification
This commit is contained in:
@@ -53,6 +53,18 @@ class AbsDownloader : Plugin() {
|
||||
super.handleOnDestroy()
|
||||
}
|
||||
|
||||
@PluginMethod
|
||||
fun setDownloadNotificationStrings(call: PluginCall) {
|
||||
DownloadServiceHost.setNotificationStrings(
|
||||
mainActivity,
|
||||
call.getString("preparing") ?: "Preparing downloads",
|
||||
call.getString("downloadingFile") ?: "Downloading {0}",
|
||||
call.getString("waitingForStorage") ?: "Waiting for available storage",
|
||||
call.getString("downloads") ?: "Downloads",
|
||||
call.getString("cancel") ?: "Cancel")
|
||||
call.resolve()
|
||||
}
|
||||
|
||||
/** Replays restored queue items when the frontend subscribes to download events. */
|
||||
@PluginMethod(returnType = PluginMethod.RETURN_NONE)
|
||||
override fun addListener(call: PluginCall) {
|
||||
@@ -91,7 +103,7 @@ class AbsDownloader : Plugin() {
|
||||
|
||||
if (localFolder == null && localFolderId.startsWith("internal-")) {
|
||||
Log.d(tag, "Creating new App Storage internal LocalFolder $localFolderId")
|
||||
localFolder = LocalFolder(localFolderId, "Internal App Storage", "", "", "", "", "internal", libraryItem.mediaType)
|
||||
localFolder = LocalFolder(localFolderId, "Internal App Storage", "", "", "", "internal", libraryItem.mediaType)
|
||||
DeviceManager.dbManager.saveLocalFolder(localFolder)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.audiobookshelf.app.plugins
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
@@ -68,6 +69,19 @@ class AbsFileSystem : Plugin() {
|
||||
}
|
||||
}
|
||||
|
||||
@PluginMethod
|
||||
fun setFolderPickerStrings(call: PluginCall) {
|
||||
mainActivity.getSharedPreferences(FOLDER_PICKER_PREFERENCES, Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
.putString(KEY_WRITE_ACCESS_REQUIRED, call.getString("writeAccessRequired"))
|
||||
.putString(KEY_ALLOW, call.getString("allow"))
|
||||
.putString(KEY_CANCEL, call.getString("cancel"))
|
||||
.putString(KEY_ACCESS_DENIED, call.getString("accessDenied"))
|
||||
.putString(KEY_PERMISSION_DENIED, call.getString("permissionDenied"))
|
||||
.apply()
|
||||
call.resolve()
|
||||
}
|
||||
|
||||
@PluginMethod
|
||||
fun selectFolder(call: PluginCall) {
|
||||
val mediaType = call.data.getString("mediaType", "book").toString()
|
||||
@@ -114,17 +128,14 @@ class AbsFileSystem : Plugin() {
|
||||
if (requestCode == REQUEST_CODE_SELECT_FOLDER) {
|
||||
|
||||
val builder: AlertDialog.Builder = AlertDialog.Builder(mainActivity)
|
||||
builder.setMessage(
|
||||
"You have no write access to this storage, thus selecting this folder is useless." +
|
||||
"\nWould you like to grant access to this folder?"
|
||||
)
|
||||
builder.setNegativeButton("Dont Allow") { _, _ ->
|
||||
builder.setMessage(folderPickerString(KEY_WRITE_ACCESS_REQUIRED, DEFAULT_WRITE_ACCESS_REQUIRED))
|
||||
builder.setNegativeButton(folderPickerString(KEY_CANCEL, DEFAULT_CANCEL)) { _, _ ->
|
||||
run {
|
||||
jsobj.put("error", "User Canceled, Access Denied")
|
||||
jsobj.put("error", folderPickerString(KEY_ACCESS_DENIED, DEFAULT_ACCESS_DENIED))
|
||||
call.resolve(jsobj)
|
||||
}
|
||||
}
|
||||
builder.setPositiveButton("Allow.") { _, _ ->
|
||||
builder.setPositiveButton(folderPickerString(KEY_ALLOW, DEFAULT_ALLOW)) { _, _ ->
|
||||
mainActivity.storageHelper.requestStorageAccess(
|
||||
REQUEST_CODE_SDCARD_ACCESS,
|
||||
initialPath = FileFullPath(mainActivity, storageId, "")
|
||||
@@ -133,7 +144,7 @@ class AbsFileSystem : Plugin() {
|
||||
builder.show()
|
||||
} else {
|
||||
Log.d(TAG, "STORAGE ACCESS DENIED $requestCode")
|
||||
jsobj.put("error", "Access Denied")
|
||||
jsobj.put("error", folderPickerString(KEY_ACCESS_DENIED, DEFAULT_ACCESS_DENIED))
|
||||
call.resolve(jsobj)
|
||||
}
|
||||
}
|
||||
@@ -141,7 +152,7 @@ class AbsFileSystem : Plugin() {
|
||||
override fun onStoragePermissionDenied(requestCode: Int) {
|
||||
Log.d(TAG, "STORAGE PERMISSION DENIED $requestCode")
|
||||
val jsobj = JSObject()
|
||||
jsobj.put("error", "Permission Denied")
|
||||
jsobj.put("error", folderPickerString(KEY_PERMISSION_DENIED, DEFAULT_PERMISSION_DENIED))
|
||||
call.resolve(jsobj)
|
||||
}
|
||||
}
|
||||
@@ -295,4 +306,23 @@ class AbsFileSystem : Plugin() {
|
||||
call.resolve(JSObject("{\"success\":false}"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun folderPickerString(key: String, defaultValue: String): String =
|
||||
mainActivity.getSharedPreferences(FOLDER_PICKER_PREFERENCES, Context.MODE_PRIVATE)
|
||||
.getString(key, defaultValue) ?: defaultValue
|
||||
|
||||
private companion object {
|
||||
const val FOLDER_PICKER_PREFERENCES = "folder_picker"
|
||||
const val KEY_WRITE_ACCESS_REQUIRED = "write_access_required"
|
||||
const val KEY_ALLOW = "allow"
|
||||
const val KEY_CANCEL = "cancel"
|
||||
const val KEY_ACCESS_DENIED = "access_denied"
|
||||
const val KEY_PERMISSION_DENIED = "permission_denied"
|
||||
const val DEFAULT_WRITE_ACCESS_REQUIRED =
|
||||
"You do not have write access to this folder. Would you like to grant access?"
|
||||
const val DEFAULT_ALLOW = "Allow"
|
||||
const val DEFAULT_CANCEL = "Cancel"
|
||||
const val DEFAULT_ACCESS_DENIED = "Access denied"
|
||||
const val DEFAULT_PERMISSION_DENIED = "Permission denied"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class DownloadService : Service() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
createChannel()
|
||||
startForeground(NOTIFICATION_ID, notification("Preparing downloads"))
|
||||
startForeground(NOTIFICATION_ID, notification(DownloadServiceHost.notificationStrings(this).preparing))
|
||||
DownloadServiceHost.attachService(this)
|
||||
}
|
||||
|
||||
@@ -37,7 +37,10 @@ class DownloadService : Service() {
|
||||
override fun onBind(intent: Intent?): IBinder? = null
|
||||
|
||||
fun onPartUpdate(part: DownloadItemPart) {
|
||||
val text = if (part.waitingForSpace) "Waiting for available storage" else "Downloading ${part.filename}"
|
||||
val strings = DownloadServiceHost.notificationStrings(this)
|
||||
val text =
|
||||
if (part.waitingForSpace) strings.waitingForStorage
|
||||
else strings.downloadingFile.replace("{0}", part.filename)
|
||||
val progress = part.progress.coerceIn(0L, 100L).toInt()
|
||||
val notification = notification(text, progress, part.fileSize > 0L)
|
||||
(getSystemService(NOTIFICATION_SERVICE) as NotificationManager).notify(NOTIFICATION_ID, notification)
|
||||
@@ -55,18 +58,22 @@ class DownloadService : Service() {
|
||||
this, 1, Intent(this, DownloadService::class.java).setAction(ACTION_CANCEL), pendingIntentFlags())
|
||||
return NotificationCompat.Builder(this, CHANNEL_ID)
|
||||
.setSmallIcon(R.drawable.icon)
|
||||
.setContentTitle("Audiobookshelf downloads")
|
||||
.setContentTitle(DownloadServiceHost.notificationStrings(this).downloads)
|
||||
.setContentText(text)
|
||||
.setOnlyAlertOnce(true)
|
||||
.setOngoing(true)
|
||||
.setProgress(100, progress, !determinate)
|
||||
.addAction(0, "Cancel", cancelIntent)
|
||||
.addAction(0, DownloadServiceHost.notificationStrings(this).cancel, cancelIntent)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun createChannel() {
|
||||
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
||||
manager.createNotificationChannel(NotificationChannel(CHANNEL_ID, "Downloads", NotificationManager.IMPORTANCE_LOW))
|
||||
manager.createNotificationChannel(
|
||||
NotificationChannel(
|
||||
CHANNEL_ID,
|
||||
DownloadServiceHost.notificationStrings(this).downloads,
|
||||
NotificationManager.IMPORTANCE_LOW))
|
||||
}
|
||||
|
||||
private fun pendingIntentFlags(): Int = PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
|
||||
@@ -11,6 +11,14 @@ import java.util.Collections
|
||||
|
||||
/** Shared process owner used by the foreground service and the Capacitor bridge. */
|
||||
object DownloadServiceHost {
|
||||
data class NotificationStrings(
|
||||
val preparing: String,
|
||||
val downloadingFile: String,
|
||||
val waitingForStorage: String,
|
||||
val downloads: String,
|
||||
val cancel: String
|
||||
)
|
||||
|
||||
private var manager: DownloadItemManager? = null
|
||||
private var bridgeEmitter: DownloadItemManager.DownloadEventEmitter = NoopEmitter
|
||||
private var service: DownloadService? = null
|
||||
@@ -58,6 +66,36 @@ object DownloadServiceHost {
|
||||
@Synchronized
|
||||
fun cancelAll(context: Context) { ensure(context).cancelAll() }
|
||||
|
||||
fun setNotificationStrings(
|
||||
context: Context,
|
||||
preparing: String,
|
||||
downloadingFile: String,
|
||||
waitingForStorage: String,
|
||||
downloads: String,
|
||||
cancel: String
|
||||
) {
|
||||
context.getSharedPreferences(NOTIFICATION_PREFERENCES, Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
.putString(KEY_PREPARING, preparing)
|
||||
.putString(KEY_DOWNLOADING_FILE, downloadingFile)
|
||||
.putString(KEY_WAITING_FOR_STORAGE, waitingForStorage)
|
||||
.putString(KEY_DOWNLOADS, downloads)
|
||||
.putString(KEY_CANCEL, cancel)
|
||||
.apply()
|
||||
}
|
||||
|
||||
fun notificationStrings(context: Context): NotificationStrings {
|
||||
val preferences = context.getSharedPreferences(NOTIFICATION_PREFERENCES, Context.MODE_PRIVATE)
|
||||
return NotificationStrings(
|
||||
preferences.getString(KEY_PREPARING, DEFAULT_PREPARING) ?: DEFAULT_PREPARING,
|
||||
preferences.getString(KEY_DOWNLOADING_FILE, DEFAULT_DOWNLOADING_FILE)
|
||||
?: DEFAULT_DOWNLOADING_FILE,
|
||||
preferences.getString(KEY_WAITING_FOR_STORAGE, DEFAULT_WAITING_FOR_STORAGE)
|
||||
?: DEFAULT_WAITING_FOR_STORAGE,
|
||||
preferences.getString(KEY_DOWNLOADS, DEFAULT_DOWNLOADS) ?: DEFAULT_DOWNLOADS,
|
||||
preferences.getString(KEY_CANCEL, DEFAULT_CANCEL) ?: DEFAULT_CANCEL)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun attachService(downloadService: DownloadService) {
|
||||
service = downloadService
|
||||
@@ -94,4 +132,16 @@ object DownloadServiceHost {
|
||||
override fun onDownloadItemComplete(jsobj: JSObject) = Unit
|
||||
override fun onQueueChanged(hasWork: Boolean) = Unit
|
||||
}
|
||||
|
||||
private const val NOTIFICATION_PREFERENCES = "download_notifications"
|
||||
private const val KEY_PREPARING = "preparing"
|
||||
private const val KEY_DOWNLOADING_FILE = "downloading_file"
|
||||
private const val KEY_WAITING_FOR_STORAGE = "waiting_for_storage"
|
||||
private const val KEY_DOWNLOADS = "downloads"
|
||||
private const val KEY_CANCEL = "cancel"
|
||||
private const val DEFAULT_PREPARING = "Preparing downloads"
|
||||
private const val DEFAULT_DOWNLOADING_FILE = "Downloading {0}"
|
||||
private const val DEFAULT_WAITING_FOR_STORAGE = "Waiting for available storage"
|
||||
private const val DEFAULT_DOWNLOADS = "Downloads"
|
||||
private const val DEFAULT_CANCEL = "Cancel"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user