Refactor capacitor plugins, clean up and organize android plugin classes

This commit is contained in:
advplyr 2022-04-04 19:08:27 -05:00
parent cc744bb975
commit 77ef0c119b
26 changed files with 376 additions and 385 deletions

View file

@ -9,8 +9,12 @@ import android.util.Log
import androidx.core.app.ActivityCompat
import com.anggrayudi.storage.SimpleStorage
import com.anggrayudi.storage.SimpleStorageHelper
import com.audiobookshelf.app.data.AbsDatabase
import com.audiobookshelf.app.data.DbManager
import com.audiobookshelf.app.player.PlayerNotificationService
import com.audiobookshelf.app.plugins.AbsDownloader
import com.audiobookshelf.app.plugins.AbsAudioPlayer
import com.audiobookshelf.app.plugins.AbsFileSystem
import com.getcapacitor.BridgeActivity
import io.paperdb.Paper
@ -63,10 +67,10 @@ class MainActivity : BridgeActivity() {
REQUEST_PERMISSIONS)
}
registerPlugin(MyNativeAudio::class.java)
registerPlugin(AudioDownloader::class.java)
registerPlugin(StorageManager::class.java)
registerPlugin(DbManager::class.java)
registerPlugin(AbsAudioPlayer::class.java)
registerPlugin(AbsDownloader::class.java)
registerPlugin(AbsFileSystem::class.java)
registerPlugin(AbsDatabase::class.java)
var filter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE).apply {
addAction(DownloadManager.ACTION_NOTIFICATION_CLICKED)
@ -98,7 +102,7 @@ class MainActivity : BridgeActivity() {
val mLocalBinder = service as PlayerNotificationService.LocalBinder
foregroundService = mLocalBinder.getService()
// Let MyNativeAudio know foreground service is ready and setup event listener
// Let NativeAudio know foreground service is ready and setup event listener
if (pluginCallback != null) {
pluginCallback()
}

View file

@ -1,23 +1,10 @@
package com.audiobookshelf.app.data
import android.util.Log
import androidx.documentfile.provider.DocumentFile
import com.audiobookshelf.app.device.DeviceManager
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.getcapacitor.JSObject
import com.getcapacitor.Plugin
import com.getcapacitor.PluginCall
import com.getcapacitor.PluginMethod
import com.getcapacitor.annotation.CapacitorPlugin
import io.paperdb.Paper
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.json.JSONObject
import java.io.File
@CapacitorPlugin(name = "DbManager")
class DbManager : Plugin() {
class DbManager {
val tag = "DbManager"
fun getDeviceData(): DeviceData {
@ -107,179 +94,4 @@ class DbManager : Plugin() {
Log.d(tag, "Loaded Object $key $json")
return json
}
//
// Database calls from webview
//
@PluginMethod
fun getDeviceData_WV(call:PluginCall) {
GlobalScope.launch(Dispatchers.IO) {
var deviceData = getDeviceData()
call.resolve(JSObject(jacksonObjectMapper().writeValueAsString(deviceData)))
}
}
@PluginMethod
fun getLocalFolders_WV(call:PluginCall) {
GlobalScope.launch(Dispatchers.IO) {
var folders = getAllLocalFolders()
var folderObjArray = jacksonObjectMapper().writeValueAsString(folders)
var jsobj = JSObject()
jsobj.put("folders", folderObjArray)
call.resolve(jsobj)
}
}
@PluginMethod
fun getLocalFolder_WV(call:PluginCall) {
var folderId = call.getString("folderId", "").toString()
GlobalScope.launch(Dispatchers.IO) {
getLocalFolder(folderId)?.let {
var folderObj = jacksonObjectMapper().writeValueAsString(it)
call.resolve(JSObject(folderObj))
} ?: call.resolve()
}
}
@PluginMethod
fun getLocalMediaItemsInFolder_WV(call:PluginCall) {
var folderId = call.getString("folderId", "").toString()
GlobalScope.launch(Dispatchers.IO) {
var localMediaItems = getLocalMediaItemsInFolder(folderId)
var mediaItemsArray = jacksonObjectMapper().writeValueAsString(localMediaItems)
var jsobj = JSObject()
jsobj.put("localMediaItems", mediaItemsArray)
call.resolve(jsobj)
}
}
@PluginMethod
fun getLocalLibraryItems_WV(call:PluginCall) {
GlobalScope.launch(Dispatchers.IO) {
var localLibraryItems = getLocalMediaItems().map {
it.getLocalLibraryItem()
}
var jsobj = JSObject()
jsobj.put("localLibraryItems", jacksonObjectMapper().writeValueAsString(localLibraryItems))
call.resolve(jsobj)
}
}
@PluginMethod
fun getLocalLibraryItem_WV(call:PluginCall) {
var id = call.getString("id", "").toString()
GlobalScope.launch(Dispatchers.IO) {
var mediaItem = getLocalMediaItem(id)
var localLibraryItem = mediaItem?.getLocalLibraryItem()
if (localLibraryItem == null) {
call.resolve()
} else {
call.resolve(JSObject(jacksonObjectMapper().writeValueAsString(localLibraryItem)))
}
}
}
@PluginMethod
fun setCurrentServerConnectionConfig_WV(call:PluginCall) {
var serverConnectionConfigId = call.getString("id", "").toString()
var serverConnectionConfig = DeviceManager.deviceData.serverConnectionConfigs.find { it.id == serverConnectionConfigId }
var username = call.getString("username", "").toString()
var token = call.getString("token", "").toString()
GlobalScope.launch(Dispatchers.IO) {
if (serverConnectionConfig == null) { // New Server Connection
var serverAddress = call.getString("address", "").toString()
// Create new server connection config
var sscId = DeviceManager.getBase64Id("$serverAddress@$username")
var sscIndex = DeviceManager.deviceData.serverConnectionConfigs.size
serverConnectionConfig = ServerConnectionConfig(sscId, sscIndex, "$serverAddress ($username)", serverAddress, username, token)
// Add and save
DeviceManager.deviceData.serverConnectionConfigs.add(serverConnectionConfig!!)
DeviceManager.deviceData.lastServerConnectionConfigId = serverConnectionConfig?.id
saveDeviceData(DeviceManager.deviceData)
} else {
var shouldSave = false
if (serverConnectionConfig?.username != username || serverConnectionConfig?.token != token) {
serverConnectionConfig?.username = username
serverConnectionConfig?.name = "${serverConnectionConfig?.address} (${serverConnectionConfig?.username})"
serverConnectionConfig?.token = token
shouldSave = true
}
// Set last connection config
if (DeviceManager.deviceData.lastServerConnectionConfigId != serverConnectionConfigId) {
DeviceManager.deviceData.lastServerConnectionConfigId = serverConnectionConfigId
shouldSave = true
}
if (shouldSave) saveDeviceData(DeviceManager.deviceData)
}
DeviceManager.serverConnectionConfig = serverConnectionConfig
call.resolve(JSObject(jacksonObjectMapper().writeValueAsString(DeviceManager.serverConnectionConfig)))
}
}
@PluginMethod
fun removeServerConnectionConfig_WV(call:PluginCall) {
GlobalScope.launch(Dispatchers.IO) {
var serverConnectionConfigId = call.getString("serverConnectionConfigId", "").toString()
DeviceManager.deviceData.serverConnectionConfigs = DeviceManager.deviceData.serverConnectionConfigs.filter { it.id != serverConnectionConfigId } as MutableList<ServerConnectionConfig>
if (DeviceManager.deviceData.lastServerConnectionConfigId == serverConnectionConfigId) {
DeviceManager.deviceData.lastServerConnectionConfigId = null
}
saveDeviceData(DeviceManager.deviceData)
if (DeviceManager.serverConnectionConfig?.id == serverConnectionConfigId) {
DeviceManager.serverConnectionConfig = null
}
call.resolve()
}
}
@PluginMethod
fun logout_WV(call:PluginCall) {
GlobalScope.launch(Dispatchers.IO) {
DeviceManager.serverConnectionConfig = null
DeviceManager.deviceData.lastServerConnectionConfigId = null
saveDeviceData(DeviceManager.deviceData)
call.resolve()
}
}
//
// Generic Webview calls to db
//
@PluginMethod
fun saveFromWebview(call: PluginCall) {
var db = call.getString("db", "").toString()
var key = call.getString("key", "").toString()
var value = call.getObject("value")
GlobalScope.launch(Dispatchers.IO) {
if (db == "" || key == "" || value == null) {
Log.d(tag, "saveFromWebview Invalid key/value")
} else {
var json = value as JSONObject
saveObject(db, key, json)
}
call.resolve()
}
}
@PluginMethod
fun loadFromWebview(call:PluginCall) {
var db = call.getString("db", "").toString()
var key = call.getString("key", "").toString()
if (db == "" || key == "") {
Log.d(tag, "loadFromWebview Invalid Key")
call.resolve()
return
}
var json = loadObject(db, key)
var jsobj = JSObject.fromJSONObject(json)
call.resolve(jsobj)
}
}

View file

@ -1,8 +1,9 @@
package com.audiobookshelf.app
package com.audiobookshelf.app.plugins
import android.os.Handler
import android.os.Looper
import android.util.Log
import com.audiobookshelf.app.MainActivity
import com.audiobookshelf.app.data.PlaybackSession
import com.audiobookshelf.app.device.DeviceManager
import com.audiobookshelf.app.player.CastManager
@ -13,11 +14,11 @@ import com.getcapacitor.*
import com.getcapacitor.annotation.CapacitorPlugin
import org.json.JSONObject
@CapacitorPlugin(name = "MyNativeAudio")
class MyNativeAudio : Plugin() {
private val tag = "MyNativeAudio"
@CapacitorPlugin(name = "AbsAudioPlayer")
class AbsAudioPlayer : Plugin() {
private val tag = "AbsAudioPlayer"
lateinit var mainActivity:MainActivity
lateinit var mainActivity: MainActivity
lateinit var apiHandler:ApiHandler
lateinit var playerNotificationService: PlayerNotificationService

View file

@ -0,0 +1,191 @@
package com.audiobookshelf.app.data
import android.util.Log
import com.audiobookshelf.app.device.DeviceManager
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.getcapacitor.JSObject
import com.getcapacitor.Plugin
import com.getcapacitor.PluginCall
import com.getcapacitor.PluginMethod
import com.getcapacitor.annotation.CapacitorPlugin
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.json.JSONObject
@CapacitorPlugin(name = "AbsDatabase")
class AbsDatabase : Plugin() {
val tag = "AbsDatabase"
@PluginMethod
fun getDeviceData(call:PluginCall) {
GlobalScope.launch(Dispatchers.IO) {
var deviceData = DeviceManager.dbManager.getDeviceData()
call.resolve(JSObject(jacksonObjectMapper().writeValueAsString(deviceData)))
}
}
@PluginMethod
fun getLocalFolders(call:PluginCall) {
GlobalScope.launch(Dispatchers.IO) {
var folders = DeviceManager.dbManager.getAllLocalFolders()
var folderObjArray = jacksonObjectMapper().writeValueAsString(folders)
var jsobj = JSObject()
jsobj.put("folders", folderObjArray)
call.resolve(jsobj)
}
}
@PluginMethod
fun getLocalFolder(call:PluginCall) {
var folderId = call.getString("folderId", "").toString()
GlobalScope.launch(Dispatchers.IO) {
DeviceManager.dbManager.getLocalFolder(folderId)?.let {
var folderObj = jacksonObjectMapper().writeValueAsString(it)
call.resolve(JSObject(folderObj))
} ?: call.resolve()
}
}
@PluginMethod
fun getLocalMediaItemsInFolder(call:PluginCall) {
var folderId = call.getString("folderId", "").toString()
GlobalScope.launch(Dispatchers.IO) {
var localMediaItems = DeviceManager.dbManager.getLocalMediaItemsInFolder(folderId)
var mediaItemsArray = jacksonObjectMapper().writeValueAsString(localMediaItems)
var jsobj = JSObject()
jsobj.put("localMediaItems", mediaItemsArray)
call.resolve(jsobj)
}
}
@PluginMethod
fun getLocalLibraryItems(call:PluginCall) {
GlobalScope.launch(Dispatchers.IO) {
var localLibraryItems = DeviceManager.dbManager.getLocalMediaItems().map {
it.getLocalLibraryItem()
}
var jsobj = JSObject()
jsobj.put("localLibraryItems", jacksonObjectMapper().writeValueAsString(localLibraryItems))
call.resolve(jsobj)
}
}
@PluginMethod
fun getLocalLibraryItem(call:PluginCall) {
var id = call.getString("id", "").toString()
GlobalScope.launch(Dispatchers.IO) {
var mediaItem = DeviceManager.dbManager.getLocalMediaItem(id)
var localLibraryItem = mediaItem?.getLocalLibraryItem()
if (localLibraryItem == null) {
call.resolve()
} else {
call.resolve(JSObject(jacksonObjectMapper().writeValueAsString(localLibraryItem)))
}
}
}
@PluginMethod
fun setCurrentServerConnectionConfig(call:PluginCall) {
var serverConnectionConfigId = call.getString("id", "").toString()
var serverConnectionConfig = DeviceManager.deviceData.serverConnectionConfigs.find { it.id == serverConnectionConfigId }
var username = call.getString("username", "").toString()
var token = call.getString("token", "").toString()
GlobalScope.launch(Dispatchers.IO) {
if (serverConnectionConfig == null) { // New Server Connection
var serverAddress = call.getString("address", "").toString()
// Create new server connection config
var sscId = DeviceManager.getBase64Id("$serverAddress@$username")
var sscIndex = DeviceManager.deviceData.serverConnectionConfigs.size
serverConnectionConfig = ServerConnectionConfig(sscId, sscIndex, "$serverAddress ($username)", serverAddress, username, token)
// Add and save
DeviceManager.deviceData.serverConnectionConfigs.add(serverConnectionConfig!!)
DeviceManager.deviceData.lastServerConnectionConfigId = serverConnectionConfig?.id
DeviceManager.dbManager.saveDeviceData(DeviceManager.deviceData)
} else {
var shouldSave = false
if (serverConnectionConfig?.username != username || serverConnectionConfig?.token != token) {
serverConnectionConfig?.username = username
serverConnectionConfig?.name = "${serverConnectionConfig?.address} (${serverConnectionConfig?.username})"
serverConnectionConfig?.token = token
shouldSave = true
}
// Set last connection config
if (DeviceManager.deviceData.lastServerConnectionConfigId != serverConnectionConfigId) {
DeviceManager.deviceData.lastServerConnectionConfigId = serverConnectionConfigId
shouldSave = true
}
if (shouldSave) DeviceManager.dbManager.saveDeviceData(DeviceManager.deviceData)
}
DeviceManager.serverConnectionConfig = serverConnectionConfig
call.resolve(JSObject(jacksonObjectMapper().writeValueAsString(DeviceManager.serverConnectionConfig)))
}
}
@PluginMethod
fun removeServerConnectionConfig(call:PluginCall) {
GlobalScope.launch(Dispatchers.IO) {
var serverConnectionConfigId = call.getString("serverConnectionConfigId", "").toString()
DeviceManager.deviceData.serverConnectionConfigs = DeviceManager.deviceData.serverConnectionConfigs.filter { it.id != serverConnectionConfigId } as MutableList<ServerConnectionConfig>
if (DeviceManager.deviceData.lastServerConnectionConfigId == serverConnectionConfigId) {
DeviceManager.deviceData.lastServerConnectionConfigId = null
}
DeviceManager.dbManager.saveDeviceData(DeviceManager.deviceData)
if (DeviceManager.serverConnectionConfig?.id == serverConnectionConfigId) {
DeviceManager.serverConnectionConfig = null
}
call.resolve()
}
}
@PluginMethod
fun logout(call:PluginCall) {
GlobalScope.launch(Dispatchers.IO) {
DeviceManager.serverConnectionConfig = null
DeviceManager.deviceData.lastServerConnectionConfigId = null
DeviceManager.dbManager.saveDeviceData(DeviceManager.deviceData)
call.resolve()
}
}
//
// Generic Webview calls to db
//
@PluginMethod
fun saveFromWebview(call: PluginCall) {
var db = call.getString("db", "").toString()
var key = call.getString("key", "").toString()
var value = call.getObject("value")
GlobalScope.launch(Dispatchers.IO) {
if (db == "" || key == "" || value == null) {
Log.d(tag, "saveFromWebview Invalid key/value")
} else {
var json = value as JSONObject
DeviceManager.dbManager.saveObject(db, key, json)
}
call.resolve()
}
}
@PluginMethod
fun loadFromWebview(call:PluginCall) {
var db = call.getString("db", "").toString()
var key = call.getString("key", "").toString()
if (db == "" || key == "") {
Log.d(tag, "loadFromWebview Invalid Key")
call.resolve()
return
}
var json = DeviceManager.dbManager.loadObject(db, key)
var jsobj = JSObject.fromJSONObject(json)
call.resolve(jsobj)
}
}

View file

@ -1,10 +1,11 @@
package com.audiobookshelf.app
package com.audiobookshelf.app.plugins
import android.app.DownloadManager
import android.content.Context
import android.net.Uri
import android.os.Build
import android.util.Log
import com.audiobookshelf.app.MainActivity
import com.audiobookshelf.app.data.LibraryItem
import com.audiobookshelf.app.data.LocalFolder
import com.audiobookshelf.app.device.DeviceManager
@ -25,9 +26,9 @@ import java.io.File
import java.util.*
@CapacitorPlugin(name = "AudioDownloader")
class AudioDownloader : Plugin() {
private val tag = "AudioDownloader"
@CapacitorPlugin(name = "AbsDownloader")
class AbsDownloader : Plugin() {
private val tag = "AbsDownloader"
lateinit var mainActivity: MainActivity
lateinit var downloadManager: DownloadManager
@ -76,7 +77,7 @@ class AudioDownloader : Plugin() {
if (evt == "complete") {
}
if (evt == "clicked") {
Log.d(tag, "Clicked $id back in the audiodownloader")
Log.d(tag, "Clicked $id back in the downloader")
}
}
mainActivity.registerBroadcastReceiver(recieverEvent)

View file

@ -1,4 +1,4 @@
package com.audiobookshelf.app
package com.audiobookshelf.app.plugins
import android.database.Cursor
import android.net.Uri
@ -10,6 +10,7 @@ import com.anggrayudi.storage.SimpleStorage
import com.anggrayudi.storage.callback.FolderPickerCallback
import com.anggrayudi.storage.callback.StorageAccessCallback
import com.anggrayudi.storage.file.*
import com.audiobookshelf.app.MainActivity
import com.audiobookshelf.app.data.LocalFolder
import com.audiobookshelf.app.device.DeviceManager
import com.audiobookshelf.app.device.FolderScanner
@ -17,11 +18,11 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.getcapacitor.*
import com.getcapacitor.annotation.CapacitorPlugin
@CapacitorPlugin(name = "StorageManager")
class StorageManager : Plugin() {
private val TAG = "StorageManager"
@CapacitorPlugin(name = "AbsFileSystem")
class AbsFileSystem : Plugin() {
private val TAG = "AbsFileSystem"
lateinit var mainActivity:MainActivity
lateinit var mainActivity: MainActivity
override fun load() {
mainActivity = (activity as MainActivity)

View file

@ -91,7 +91,7 @@
<script>
import { Capacitor } from '@capacitor/core'
import MyNativeAudio from '@/plugins/my-native-audio'
import { AbsAudioPlayer } from '@/plugins/capacitor'
export default {
props: {
@ -266,7 +266,7 @@ export default {
},
castClick() {
console.log('Cast Btn Click')
MyNativeAudio.requestSession()
AbsAudioPlayer.requestSession()
},
clickContainer() {
this.showFullscreen = true
@ -308,18 +308,18 @@ export default {
setPlaybackSpeed(speed) {
console.log(`[AudioPlayer] Set Playback Rate: ${speed}`)
this.currentPlaybackRate = speed
MyNativeAudio.setPlaybackSpeed({ speed: speed })
AbsAudioPlayer.setPlaybackSpeed({ speed: speed })
},
restart() {
this.seek(0)
},
backward10() {
if (this.isLoading) return
MyNativeAudio.seekBackward({ amount: '10000' })
AbsAudioPlayer.seekBackward({ amount: '10000' })
},
forward10() {
if (this.isLoading) return
MyNativeAudio.seekForward({ amount: '10000' })
AbsAudioPlayer.seekForward({ amount: '10000' })
},
setStreamReady() {
this.readyTrackWidth = this.trackWidth
@ -421,7 +421,7 @@ export default {
this.seekedTime = time
this.seekLoading = true
MyNativeAudio.seekPlayer({ timeMs: String(Math.floor(time * 1000)) })
AbsAudioPlayer.seekPlayer({ timeMs: String(Math.floor(time * 1000)) })
if (this.$refs.playedTrack) {
var perc = time / this.totalDuration
@ -466,19 +466,19 @@ export default {
}
},
play() {
MyNativeAudio.playPlayer()
AbsAudioPlayer.playPlayer()
this.startPlayInterval()
this.isPlaying = true
},
pause() {
MyNativeAudio.pausePlayer()
AbsAudioPlayer.pausePlayer()
this.stopPlayInterval()
this.isPlaying = false
},
startPlayInterval() {
clearInterval(this.playInterval)
this.playInterval = setInterval(async () => {
var data = await MyNativeAudio.getCurrentTime()
var data = await AbsAudioPlayer.getCurrentTime()
this.currentTime = Number((data.value / 1000).toFixed(2))
this.bufferedTime = Number((data.bufferedTime / 1000).toFixed(2))
console.log('[AudioPlayer] Got Current Time', this.currentTime)
@ -494,7 +494,7 @@ export default {
},
terminateStream() {
if (!this.playbackSession) return
MyNativeAudio.terminateStream()
AbsAudioPlayer.terminateStream()
},
onPlayingUpdate(data) {
console.log('onPlayingUpdate', JSON.stringify(data))
@ -542,10 +542,10 @@ export default {
async init() {
this.useChapterTrack = await this.$localStore.getUseChapterTrack()
this.onPlaybackSessionListener = MyNativeAudio.addListener('onPlaybackSession', this.onPlaybackSession)
this.onPlaybackClosedListener = MyNativeAudio.addListener('onPlaybackClosed', this.onPlaybackClosed)
this.onPlayingUpdateListener = MyNativeAudio.addListener('onPlayingUpdate', this.onPlayingUpdate)
this.onMetadataListener = MyNativeAudio.addListener('onMetadata', this.onMetadata)
this.onPlaybackSessionListener = AbsAudioPlayer.addListener('onPlaybackSession', this.onPlaybackSession)
this.onPlaybackClosedListener = AbsAudioPlayer.addListener('onPlaybackClosed', this.onPlaybackClosed)
this.onPlayingUpdateListener = AbsAudioPlayer.addListener('onPlayingUpdate', this.onPlayingUpdate)
this.onMetadataListener = AbsAudioPlayer.addListener('onMetadata', this.onMetadata)
},
handleGesture() {
var touchDistance = this.touchEndY - this.touchStartY

View file

@ -11,7 +11,7 @@
</template>
<script>
import MyNativeAudio from '@/plugins/my-native-audio'
import { AbsAudioPlayer } from '@/plugins/capacitor'
export default {
data() {
@ -92,21 +92,21 @@ export default {
},
async selectSleepTimeout({ time, isChapterTime }) {
console.log('Setting sleep timer', time, isChapterTime)
var res = await MyNativeAudio.setSleepTimer({ time: String(time), isChapterTime })
var res = await AbsAudioPlayer.setSleepTimer({ time: String(time), isChapterTime })
if (!res.success) {
return this.$toast.error('Sleep timer did not set, invalid time')
}
},
increaseSleepTimer() {
// Default time to increase = 5 min
MyNativeAudio.increaseSleepTime({ time: '300000' })
AbsAudioPlayer.increaseSleepTime({ time: '300000' })
},
decreaseSleepTimer() {
MyNativeAudio.decreaseSleepTime({ time: '300000' })
AbsAudioPlayer.decreaseSleepTime({ time: '300000' })
},
async cancelSleepTimer() {
console.log('Canceling sleep timer')
await MyNativeAudio.cancelSleepTimer()
await AbsAudioPlayer.cancelSleepTimer()
},
streamClosed() {
console.log('Stream Closed')
@ -168,7 +168,7 @@ export default {
}
},
async playLibraryItem(libraryItemId) {
MyNativeAudio.prepareLibraryItem({ libraryItemId, playWhenReady: true })
AbsAudioPlayer.prepareLibraryItem({ libraryItemId, playWhenReady: true })
.then((data) => {
console.log('TEST library item play response', JSON.stringify(data))
})
@ -178,8 +178,8 @@ export default {
}
},
mounted() {
this.onSleepTimerEndedListener = MyNativeAudio.addListener('onSleepTimerEnded', this.onSleepTimerEnded)
this.onSleepTimerSetListener = MyNativeAudio.addListener('onSleepTimerSet', this.onSleepTimerSet)
this.onSleepTimerEndedListener = AbsAudioPlayer.addListener('onSleepTimerEnded', this.onSleepTimerEnded)
this.onSleepTimerSetListener = AbsAudioPlayer.addListener('onSleepTimerSet', this.onSleepTimerSet)
this.playbackSpeed = this.$store.getters['user/getUserSetting']('playbackRate')
console.log(`[AudioPlayerContainer] Init Playback Speed: ${this.playbackSpeed}`)

View file

@ -46,8 +46,8 @@ export default {
}
},
computed: {
isSocketConnected() {
return this.$store.state.socketConnected
user() {
return this.$store.state.user.user
},
isBookEntity() {
return this.entityName === 'books' || this.entityName === 'series-books'
@ -62,9 +62,6 @@ export default {
hasFilter() {
return this.filterBy !== 'all'
},
books() {
return this.$store.getters['downloads/getAudiobooks']
},
orderBy() {
return this.$store.getters['user/getUserSetting']('mobileOrderBy')
},
@ -110,12 +107,6 @@ export default {
totalEntityCardWidth() {
// Includes margin
return this.entityWidth + 24
},
downloads() {
return this.$store.getters['downloads/getDownloads']
},
downloadedBooks() {
return []
}
},
methods: {
@ -132,19 +123,6 @@ export default {
if (!this.initialized) {
this.currentSFQueryString = this.buildSearchParams()
}
// var entityPath = this.entityName === 'books' ? `books/all` : this.entityName
// var sfQueryString = this.currentSFQueryString ? this.currentSFQueryString + '&' : ''
// var queryString = `?${sfQueryString}&limit=${this.booksPerFetch}&page=${page}`
// if (this.entityName === 'series-books') {
// entityPath = `series/${this.seriesId}`
// queryString = ''
// }
// var payload = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/${entityPath}${queryString}`).catch((error) => {
// console.error('failed to fetch books', error)
// return null
// })
var entityPath = this.entityName === 'books' || this.entityName === 'series-books' ? `items` : this.entityName
var sfQueryString = this.currentSFQueryString ? this.currentSFQueryString + '&' : ''
@ -174,12 +152,12 @@ export default {
for (let i = 0; i < payload.results.length; i++) {
if (this.entityName === 'books' || this.entityName === 'series-books') {
// Check if has download and append download obj
var download = this.downloads.find((dl) => dl.id === payload.results[i].id)
if (download) {
var dl = { ...download }
delete dl.audiobook
payload.results[i].download = dl
}
// var download = this.downloads.find((dl) => dl.id === payload.results[i].id)
// if (download) {
// var dl = { ...download }
// delete dl.audiobook
// payload.results[i].download = dl
// }
}
var index = i + startIndex
@ -191,6 +169,10 @@ export default {
}
},
async loadPage(page) {
if (!this.currentLibraryId) {
console.error('[LazyBookshelf] loadPage current library id not set')
return
}
this.pagesLoaded[page] = true
await this.fetchEntities(page)
},
@ -241,7 +223,7 @@ export default {
},
setDownloads() {
if (this.entityName === 'books') {
this.entities = this.downloadedBooks
this.entities = []
// TOOD: Sort and filter here
this.totalEntities = this.entities.length
this.totalShelves = Math.ceil(this.totalEntities / this.entitiesPerShelf)
@ -269,14 +251,12 @@ export default {
this.initialized = false
this.initSizeData()
if (this.isSocketConnected) {
if (this.user) {
await this.loadPage(0)
var lastBookIndex = Math.min(this.totalEntities, this.shelvesPerPage * this.entitiesPerShelf)
this.mountEntites(0, lastBookIndex)
} else {
this.setDownloads()
this.mountEntites(0, this.totalEntities - 1)
// Local only
}
},
remountEntities() {
@ -321,28 +301,12 @@ export default {
var lastBookIndex = Math.min(this.totalEntities, this.shelvesPerPage * this.entitiesPerShelf)
this.mountEntites(0, lastBookIndex)
},
initDownloads() {
this.initSizeData()
this.setDownloads()
this.$nextTick(() => {
console.log('Mounting downloads', this.totalEntities, 'total shelves', this.totalShelves)
this.mountEntites(0, this.totalEntities)
})
},
scroll(e) {
if (!e || !e.target) return
if (!this.isSocketConnected) return // Offline books are all mounted at once
if (!this.user) return
var { scrollTop } = e.target
this.handleScroll(scrollTop)
},
socketInit(isConnected) {
if (isConnected) {
this.init()
} else {
this.isFirstInit = false
this.resetEntities()
}
},
buildSearchParams() {
let searchParams = new URLSearchParams()
if (this.filterBy && this.filterBy !== 'all') {
@ -383,11 +347,6 @@ export default {
this.resetEntities()
}
},
downloadsLoaded() {
if (!this.isSocketConnected) {
this.resetEntities()
}
},
libraryItemAdded(libraryItem) {
console.log('libraryItem added', libraryItem)
// TODO: Check if item would be on this shelf
@ -433,18 +392,13 @@ export default {
}
this.$eventBus.$on('library-changed', this.libraryChanged)
this.$eventBus.$on('downloads-loaded', this.downloadsLoaded)
this.$store.commit('user/addSettingsListener', { id: 'lazy-bookshelf', meth: this.settingsUpdated })
// if (this.$server.socket) {
// this.$server.socket.on('item_updated', this.libraryItemUpdated)
// this.$server.socket.on('item_added', this.libraryItemAdded)
// this.$server.socket.on('item_removed', this.libraryItemRemoved)
// this.$server.socket.on('items_updated', this.libraryItemsUpdated)
// this.$server.socket.on('items_added', this.libraryItemsAdded)
// } else {
// console.error('Bookshelf - Socket not initialized')
// }
this.$socket.$on('item_updated', this.libraryItemUpdated)
this.$socket.$on('item_added', this.libraryItemAdded)
this.$socket.$on('item_removed', this.libraryItemRemoved)
this.$socket.$on('items_updated', this.libraryItemsUpdated)
this.$socket.$on('items_added', this.libraryItemsAdded)
},
removeListeners() {
var bookshelf = document.getElementById('bookshelf-wrapper')
@ -453,31 +407,20 @@ export default {
}
this.$eventBus.$off('library-changed', this.libraryChanged)
this.$eventBus.$off('downloads-loaded', this.downloadsLoaded)
this.$store.commit('user/removeSettingsListener', 'lazy-bookshelf')
// if (this.$server.socket) {
// this.$server.socket.off('item_updated', this.libraryItemUpdated)
// this.$server.socket.off('item_added', this.libraryItemAdded)
// this.$server.socket.off('item_removed', this.libraryItemRemoved)
// this.$server.socket.off('items_updated', this.libraryItemsUpdated)
// this.$server.socket.off('items_added', this.libraryItemsAdded)
// } else {
// console.error('Bookshelf - Socket not initialized')
// }
this.$socket.$off('item_updated', this.libraryItemUpdated)
this.$socket.$off('item_added', this.libraryItemAdded)
this.$socket.$off('item_removed', this.libraryItemRemoved)
this.$socket.$off('items_updated', this.libraryItemsUpdated)
this.$socket.$off('items_added', this.libraryItemsAdded)
}
},
mounted() {
// if (this.$server.initialized) {
// this.init()
// } else {
// this.initDownloads()
// }
this.$socket.on('initialized', this.socketInit)
this.init()
this.initListeners()
},
beforeDestroy() {
this.$socket.off('initialized', this.socketInit)
this.removeListeners()
}
}

View file

@ -12,10 +12,8 @@
</template>
<script>
import { Capacitor } from '@capacitor/core'
import { AppUpdate } from '@robingenz/capacitor-app-update'
import AudioDownloader from '@/plugins/audio-downloader'
import StorageManager from '@/plugins/storage-manager'
import { AbsFileSystem, AbsDownloader } from '@/plugins/capacitor'
export default {
data() {
@ -88,7 +86,7 @@ export default {
},
async searchFolder(downloadFolder) {
try {
var response = await StorageManager.searchFolder({ folderUrl: downloadFolder.uri })
var response = await AbsFileSystem.searchFolder({ folderUrl: downloadFolder.uri })
var searchResults = response
searchResults.folders = JSON.parse(searchResults.folders)
searchResults.files = JSON.parse(searchResults.files)
@ -146,10 +144,10 @@ export default {
},
async initMediaStore() {
// Request and setup listeners for media files on native
AudioDownloader.addListener('onItemDownloadUpdate', (data) => {
AbsDownloader.addListener('onItemDownloadUpdate', (data) => {
this.onItemDownloadUpdate(data)
})
AudioDownloader.addListener('onItemDownloadComplete', (data) => {
AbsDownloader.addListener('onItemDownloadComplete', (data) => {
this.onItemDownloadComplete(data)
})
},
@ -253,11 +251,6 @@ export default {
}
},
beforeDestroy() {
if (!this.$server) {
console.error('No Server beforeDestroy')
return
}
this.$socket.off('connection-update', this.socketConnectionUpdate)
this.$socket.off('initialized', this.socketInit)
}

View file

@ -40,9 +40,7 @@ export default {
'@/plugins/localStore.js',
'@/plugins/init.client.js',
'@/plugins/axios.js',
'@/plugins/my-native-audio.js',
'@/plugins/audio-downloader.js',
'@/plugins/storage-manager.js',
'@/plugins/capacitor/index.js',
'@/plugins/toast.js',
'@/plugins/constants.js'
],

View file

@ -35,7 +35,7 @@
<script>
import { AppUpdate } from '@robingenz/capacitor-app-update'
import MyNativeAudio from '@/plugins/my-native-audio'
import { AbsAudioPlayer } from '@/plugins/capacitor'
export default {
asyncData({ redirect, store }) {
@ -82,7 +82,7 @@ export default {
// Used for testing API
console.log('Making Test call')
var libraryId = this.$store.state.libraries.currentLibraryId
MyNativeAudio.getLibraryItems({ libraryId }).then((res) => {
AbsAudioPlayer.getLibraryItems({ libraryId }).then((res) => {
console.log('TEST CALL response', JSON.stringify(res))
})
},

View file

@ -35,7 +35,7 @@ export default {
data() {
return {
shelves: [],
loading: true
loading: false
}
},
computed: {
@ -87,11 +87,14 @@ export default {
return categories
},
async fetchCategories() {
if (this.loading) {
console.log('Already loading categories')
return
}
this.loading = true
this.shelves = []
var localCategories = await this.getLocalMediaItemCategories()
console.log('Category shelves', localCategories.length)
this.shelves = this.shelves.concat(localCategories)
if (this.user || !this.currentLibraryId) {

View file

@ -67,8 +67,7 @@
<script>
import { Dialog } from '@capacitor/dialog'
import AudioDownloader from '@/plugins/audio-downloader'
import StorageManager from '@/plugins/storage-manager'
import { AbsFileSystem, AbsDownloader } from '@/plugins/capacitor'
export default {
async asyncData({ store, params, redirect, app }) {
@ -239,7 +238,7 @@ export default {
},
async selectFolder() {
// Select and save the local folder for media type
var folderObj = await StorageManager.selectFolder({ mediaType: this.mediaType })
var folderObj = await AbsFileSystem.selectFolder({ mediaType: this.mediaType })
if (folderObj.error) {
return this.$toast.error(`Error: ${folderObj.error || 'Unknown Error'}`)
}
@ -296,7 +295,7 @@ export default {
},
async startDownload(localFolder) {
console.log('Starting download to local folder', localFolder.name)
var downloadRes = await AudioDownloader.downloadLibraryItem({ libraryItemId: this.libraryItemId, localFolderId: localFolder.id })
var downloadRes = await AbsDownloader.downloadLibraryItem({ libraryItemId: this.libraryItemId, localFolderId: localFolder.id })
if (downloadRes.error) {
var errorMsg = downloadRes.error || 'Unknown error'
console.error('Download error', errorMsg)

View file

@ -35,7 +35,7 @@
<script>
import { Capacitor } from '@capacitor/core'
import { Dialog } from '@capacitor/dialog'
import StorageManager from '@/plugins/storage-manager'
import { AbsFileSystem } from '@/plugins/capacitor'
export default {
asyncData({ params, query }) {
@ -75,7 +75,7 @@ export default {
})
if (value) {
this.removingFolder = true
await StorageManager.removeFolder({ folderId: this.folderId })
await AbsFileSystem.removeFolder({ folderId: this.folderId })
this.removingFolder = false
this.$router.replace('/localMedia/folders')
}
@ -85,7 +85,7 @@ export default {
},
async scanFolder(forceAudioProbe = false) {
this.isScanning = true
var response = await StorageManager.scanFolder({ folderId: this.folderId, forceAudioProbe })
var response = await AbsFileSystem.scanFolder({ folderId: this.folderId, forceAudioProbe })
if (response && response.localMediaItems) {
var itemsAdded = response.itemsAdded

View file

@ -26,7 +26,7 @@
</template>
<script>
import StorageManager from '@/plugins/storage-manager'
import { AbsFileSystem } from '@/plugins/capacitor'
export default {
data() {
@ -58,7 +58,7 @@ export default {
if (!this.newFolderMediaType) {
return this.$toast.error('Must select a media type')
}
var folderObj = await StorageManager.selectFolder({ mediaType: this.newFolderMediaType })
var folderObj = await AbsFileSystem.selectFolder({ mediaType: this.newFolderMediaType })
if (folderObj.error) {
return this.$toast.error(`Error: ${folderObj.error || 'Unknown Error'}`)
}
@ -70,7 +70,7 @@ export default {
this.localFolders.push(folderObj)
}
var permissionsGood = await StorageManager.checkFolderPermissions({ folderUrl: folderObj.contentUrl })
var permissionsGood = await AbsFileSystem.checkFolderPermissions({ folderUrl: folderObj.contentUrl })
if (!permissionsGood) {
this.$toast.error('Folder permissions failed')

View file

@ -1,4 +0,0 @@
import { registerPlugin } from '@capacitor/core';
const AudioDownloader = registerPlugin('AudioDownloader');
export default AudioDownloader;

View file

@ -0,0 +1,13 @@
import { registerPlugin, WebPlugin } from '@capacitor/core';
class AbsAudioPlayerWeb extends WebPlugin {
constructor() {
super()
}
}
const AbsAudioPlayer = registerPlugin('AbsAudioPlayer', {
web: () => new AbsAudioPlayerWeb()
})
export { AbsAudioPlayer }

View file

@ -1,11 +1,11 @@
import { registerPlugin, Capacitor, WebPlugin } from '@capacitor/core';
class DbWeb extends WebPlugin {
class AbsDatabaseWeb extends WebPlugin {
constructor() {
super()
}
async getDeviceData_WV() {
async getDeviceData() {
var dd = localStorage.getItem('device')
if (dd) {
return JSON.parse(dd)
@ -18,8 +18,8 @@ class DbWeb extends WebPlugin {
return deviceData
}
async setCurrentServerConnectionConfig_WV(serverConnectionConfig) {
var deviceData = await this.getDeviceData_WV()
async setCurrentServerConnectionConfig(serverConnectionConfig) {
var deviceData = await this.getDeviceData()
var ssc = deviceData.serverConnectionConfigs.find(_ssc => _ssc.id == serverConnectionConfig.id)
if (ssc) {
@ -44,20 +44,22 @@ class DbWeb extends WebPlugin {
return ssc
}
async removeServerConnectionConfig_WV(serverConnectionConfigCallObject) {
async removeServerConnectionConfig(serverConnectionConfigCallObject) {
var serverConnectionConfigId = serverConnectionConfigCallObject.serverConnectionConfigId
var deviceData = await this.getDeviceData_WV()
var deviceData = await this.getDeviceData()
deviceData.serverConnectionConfigs = deviceData.serverConnectionConfigs.filter(ssc => ssc.id == serverConnectionConfigId)
localStorage.setItem('device', JSON.stringify(deviceData))
}
logout_WV() {
// Nothing to do on web
async logout() {
var deviceData = await this.getDeviceData()
deviceData.lastServerConnectionConfigId = null
localStorage.setItem('device', JSON.stringify(deviceData))
}
}
const DbManager = registerPlugin('DbManager', {
web: () => new DbWeb()
const AbsDatabase = registerPlugin('AbsDatabase', {
web: () => new AbsDatabaseWeb()
})
export { DbManager }
export { AbsDatabase }

View file

@ -0,0 +1,13 @@
import { registerPlugin, WebPlugin } from '@capacitor/core';
class AbsDownloaderWeb extends WebPlugin {
constructor() {
super()
}
}
const AbsDownloader = registerPlugin('AbsDownloader', {
web: () => new AbsDownloaderWeb()
})
export { AbsDownloader }

View file

@ -0,0 +1,13 @@
import { registerPlugin, WebPlugin } from '@capacitor/core';
class AbsFileSystemWeb extends WebPlugin {
constructor() {
super()
}
}
const AbsFileSystem = registerPlugin('AbsFileSystem', {
web: () => new AbsFileSystemWeb()
})
export { AbsFileSystem }

View file

@ -0,0 +1,13 @@
import Vue from 'vue'
import { AbsAudioPlayer } from './AbsAudioPlayer'
import { AbsDownloader } from './AbsDownloader'
import { AbsFileSystem } from './AbsFileSystem'
import { Capacitor } from '@capacitor/core'
Vue.prototype.$platform = Capacitor.getPlatform()
export {
AbsAudioPlayer,
AbsDownloader,
AbsFileSystem
}

View file

@ -1,5 +1,5 @@
import { Capacitor } from '@capacitor/core';
import { DbManager } from './capacitor/DbManager'
import { AbsDatabase } from './capacitor/AbsDatabase'
const isWeb = Capacitor.getPlatform() == 'web'
@ -8,7 +8,7 @@ class DbService {
save(db, key, value) {
if (isWeb) return
return DbManager.saveFromWebview({ db, key, value }).then(() => {
return AbsDatabase.saveFromWebview({ db, key, value }).then(() => {
console.log('Saved data', db, key, JSON.stringify(value))
}).catch((error) => {
console.error('Failed to save data', error)
@ -17,7 +17,7 @@ class DbService {
load(db, key) {
if (isWeb) return null
return DbManager.loadFromWebview({ db, key }).then((data) => {
return AbsDatabase.loadFromWebview({ db, key }).then((data) => {
console.log('Loaded data', db, key, JSON.stringify(data))
return data
}).catch((error) => {
@ -27,33 +27,33 @@ class DbService {
}
getDeviceData() {
return DbManager.getDeviceData_WV().then((data) => {
return AbsDatabase.getDeviceData().then((data) => {
console.log('Loaded device data', JSON.stringify(data))
return data
})
}
setServerConnectionConfig(serverConnectionConfig) {
return DbManager.setCurrentServerConnectionConfig_WV(serverConnectionConfig).then((data) => {
return AbsDatabase.setCurrentServerConnectionConfig(serverConnectionConfig).then((data) => {
console.log('Set server connection config', JSON.stringify(data))
return data
})
}
removeServerConnectionConfig(serverConnectionConfigId) {
return DbManager.removeServerConnectionConfig_WV({ serverConnectionConfigId }).then((data) => {
return AbsDatabase.removeServerConnectionConfig({ serverConnectionConfigId }).then((data) => {
console.log('Removed server connection config', serverConnectionConfigId)
return true
})
}
logout() {
return DbManager.logout_WV()
return AbsDatabase.logout()
}
getLocalFolders() {
if (isWeb) return []
return DbManager.getLocalFolders_WV().then((data) => {
return AbsDatabase.getLocalFolders().then((data) => {
console.log('Loaded local folders', JSON.stringify(data))
if (data.folders && typeof data.folders == 'string') {
return JSON.parse(data.folders)
@ -67,7 +67,7 @@ class DbService {
getLocalFolder(folderId) {
if (isWeb) return null
return DbManager.getLocalFolder_WV({ folderId }).then((data) => {
return AbsDatabase.getLocalFolder({ folderId }).then((data) => {
console.log('Got local folder', JSON.stringify(data))
return data
})
@ -75,7 +75,7 @@ class DbService {
getLocalMediaItemsInFolder(folderId) {
if (isWeb) return []
return DbManager.getLocalMediaItemsInFolder_WV({ folderId }).then((data) => {
return AbsDatabase.getLocalMediaItemsInFolder({ folderId }).then((data) => {
console.log('Loaded local media items in folder', JSON.stringify(data))
if (data.localMediaItems && typeof data.localMediaItems == 'string') {
return JSON.parse(data.localMediaItems)
@ -86,7 +86,7 @@ class DbService {
getLocalLibraryItems() {
if (isWeb) return []
return DbManager.getLocalLibraryItems_WV().then((data) => {
return AbsDatabase.getLocalLibraryItems().then((data) => {
console.log('Loaded all local media items', JSON.stringify(data))
if (data.localLibraryItems && typeof data.localLibraryItems == 'string') {
return JSON.parse(data.localLibraryItems)
@ -97,7 +97,7 @@ class DbService {
getLocalLibraryItem(id) {
if (isWeb) return null
return DbManager.getLocalLibraryItem_WV({ id })
return AbsDatabase.getLocalLibraryItem({ id })
}
}

View file

@ -1,7 +0,0 @@
import Vue from 'vue'
import { registerPlugin, Capacitor } from '@capacitor/core';
Vue.prototype.$platform = Capacitor.getPlatform()
const MyNativeAudio = registerPlugin('MyNativeAudio');
export default MyNativeAudio;

View file

@ -13,6 +13,16 @@ class ServerSocket extends EventEmitter {
this.token = null
}
$on(evt, callback) {
if (this.socket) this.socket.on(evt, callback)
else console.error('$on Socket not initialized')
}
$off(evt, callback) {
if (this.socket) this.socket.off(evt, callback)
else console.error('$off Socket not initialized')
}
connect(serverAddress, token) {
this.serverAddress = serverAddress
this.token = token
@ -33,7 +43,6 @@ class ServerSocket extends EventEmitter {
}
setSocketListeners() {
if (!this.socket) return
this.socket.on('connect', this.onConnect.bind(this))
this.socket.on('disconnect', this.onDisconnect.bind(this))
this.socket.on('init', this.onInit.bind(this))
@ -41,7 +50,6 @@ class ServerSocket extends EventEmitter {
this.socket.onAny((evt, args) => {
console.log(`[SOCKET] ${this.socket.id}: ${evt} ${JSON.stringify(args)}`)
})
}
onConnect() {
@ -73,6 +81,5 @@ class ServerSocket extends EventEmitter {
}
export default ({ app, store }, inject) => {
console.log('Check event bus', this, Vue.prototype.$eventBus)
inject('socket', new ServerSocket(store))
}

View file

@ -1,5 +0,0 @@
import { registerPlugin } from '@capacitor/core';
const StorageManager = registerPlugin('StorageManager');
export default StorageManager;