mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-07-31 08:04:46 +02:00
Initial work
This commit is contained in:
parent
f047f6a23b
commit
d788623509
9 changed files with 214 additions and 44 deletions
|
@ -20,6 +20,14 @@ enum class ShakeSensitivitySetting {
|
|||
VERY_LOW, LOW, MEDIUM, HIGH, VERY_HIGH
|
||||
}
|
||||
|
||||
enum class DownloadUsingCellularSetting {
|
||||
ASK, ALWAYS, NEVER
|
||||
}
|
||||
|
||||
enum class StreamingUsingCellularSetting {
|
||||
ASK, ALWAYS, NEVER
|
||||
}
|
||||
|
||||
data class ServerConnectionConfig(
|
||||
var id:String,
|
||||
var index:Int,
|
||||
|
@ -123,7 +131,9 @@ data class DeviceSettings(
|
|||
var sleepTimerLength: Long, // Time in milliseconds
|
||||
var disableSleepTimerFadeOut: Boolean,
|
||||
var disableSleepTimerResetFeedback: Boolean,
|
||||
var languageCode: String
|
||||
var languageCode: String,
|
||||
var downloadUsingCellular: DownloadUsingCellularSetting,
|
||||
var streamingUsingCellular: StreamingUsingCellularSetting
|
||||
) {
|
||||
companion object {
|
||||
// Static method to get default device settings
|
||||
|
@ -147,7 +157,9 @@ data class DeviceSettings(
|
|||
autoSleepTimerAutoRewindTime = 300000L, // 5 minutes
|
||||
disableSleepTimerFadeOut = false,
|
||||
disableSleepTimerResetFeedback = false,
|
||||
languageCode = "en-us"
|
||||
languageCode = "en-us",
|
||||
downloadUsingCellular = DownloadUsingCellularSetting.ALWAYS,
|
||||
streamingUsingCellular = StreamingUsingCellularItems.ALWAYS
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,14 @@ object DeviceManager {
|
|||
if (deviceData.deviceSettings?.languageCode == null) {
|
||||
deviceData.deviceSettings?.languageCode = "en-us"
|
||||
}
|
||||
|
||||
if (deviceData.deviceSettings?.downloadUsingCellular == null) {
|
||||
deviceData.deviceSettings?.downloadUsingCellular = DownloadUsingCellularSetting.ALWAYS
|
||||
}
|
||||
|
||||
if (deviceData.deviceSettings?.streamingUsingCellular == null) {
|
||||
deviceData.deviceSettings?.streamingUsingCellular = StreamingUsingCellularSetting.ALWAYS
|
||||
}
|
||||
}
|
||||
|
||||
fun getBase64Id(id:String):String {
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { Dialog } from '@capacitor/dialog'
|
||||
import { AbsFileSystem, AbsDownloader } from '@/plugins/capacitor'
|
||||
|
||||
export default {
|
||||
|
@ -96,6 +97,15 @@ export default {
|
|||
userCanDownload() {
|
||||
return this.$store.getters['user/getUserCanDownload']
|
||||
},
|
||||
canDownloadUsingCellular() {
|
||||
return this.$store.getters['getCanDownloadUsingCellular']
|
||||
},
|
||||
canStreamUsingCellular() {
|
||||
return this.$store.getters['getCanStreamingUsingCellular']
|
||||
},
|
||||
isCellular() {
|
||||
return this.$store.state.networkConnectionType === 'cellular'
|
||||
},
|
||||
audioFile() {
|
||||
return this.episode.audioFile
|
||||
},
|
||||
|
@ -185,8 +195,45 @@ export default {
|
|||
}
|
||||
return folderObj
|
||||
},
|
||||
async confirmAction(action) {
|
||||
const { value } = await Dialog.confirm({
|
||||
title: 'Confirm',
|
||||
message: `You are about to ${action} using cellular data. Do you want to proceed?`
|
||||
});
|
||||
return value
|
||||
},
|
||||
async checkDownloadPermission() {
|
||||
if (this.isCellular) {
|
||||
const permission = this.canDownloadUsingCellular
|
||||
if (permission === 'NEVER') {
|
||||
this.$toast.error('Downloading is not allowed on cellular data.')
|
||||
return false
|
||||
} else if (permission === 'ASK') {
|
||||
const confirmed = await this.confirmAction('download')
|
||||
return confirmed
|
||||
}
|
||||
}
|
||||
return true
|
||||
},
|
||||
async checkStreamPermission() {
|
||||
if (this.isCellular) {
|
||||
const permission = this.canStreamUsingCellular
|
||||
if (permission === 'NEVER') {
|
||||
this.$toast.error('Streaming is not allowed on cellular data.')
|
||||
return false
|
||||
} else if (permission === 'ASK') {
|
||||
const confirmed = await this.confirmAction('stream')
|
||||
return confirmed
|
||||
}
|
||||
}
|
||||
return true
|
||||
},
|
||||
async downloadClick() {
|
||||
if (this.downloadItem || this.pendingDownload) return
|
||||
|
||||
const hasPermission = await this.checkDownloadPermission()
|
||||
if (!hasPermission) return
|
||||
|
||||
this.pendingDownload = true
|
||||
await this.$hapticsImpact()
|
||||
if (this.isIos) {
|
||||
|
@ -258,9 +305,8 @@ export default {
|
|||
if (this.streamIsPlaying) {
|
||||
this.$eventBus.$emit('pause-item')
|
||||
} else {
|
||||
this.$store.commit('setPlayerIsStartingPlayback', this.episode.id)
|
||||
|
||||
if (this.localEpisode && this.localLibraryItemId) {
|
||||
this.$store.commit('setPlayerIsStartingPlayback', this.episode.id)
|
||||
console.log('Play local episode', this.localEpisode.id, this.localLibraryItemId)
|
||||
|
||||
this.$eventBus.$emit('play-item', {
|
||||
|
@ -270,6 +316,10 @@ export default {
|
|||
serverEpisodeId: this.episode.id
|
||||
})
|
||||
} else {
|
||||
const hasPermission = await this.checkStreamPermission()
|
||||
if (!hasPermission) return
|
||||
|
||||
this.$store.commit('setPlayerIsStartingPlayback', this.episode.id)
|
||||
this.$eventBus.$emit('play-item', {
|
||||
libraryItemId: this.libraryItemId,
|
||||
episodeId: this.episode.id
|
||||
|
|
|
@ -14,7 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
// Override point for customization after application launch.
|
||||
|
||||
let configuration = Realm.Configuration(
|
||||
schemaVersion: 17,
|
||||
schemaVersion: 18,
|
||||
migrationBlock: { [weak self] migration, oldSchemaVersion in
|
||||
if (oldSchemaVersion < 1) {
|
||||
self?.logger.log("Realm schema version was \(oldSchemaVersion)")
|
||||
|
@ -54,6 +54,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
newObject?["chapterTrack"] = false
|
||||
}
|
||||
}
|
||||
if (oldSchemaVersion < 17) {
|
||||
self?.logger.log("Realm schema version was \(oldSchemaVersion)... Adding downloadUsingCellular and streamingUsingCellular settings")
|
||||
migration.enumerateObjects(ofType: PlayerSettings.className()) { oldObject, newObject in
|
||||
newObject?["downloadUsingCellular"] = "ALWAYS"
|
||||
newObject?["streamingUsingCellular"] = "ALWAYS"
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
|
|
|
@ -244,6 +244,8 @@ public class AbsDatabase: CAPPlugin {
|
|||
let lockOrientation = call.getString("lockOrientation") ?? "NONE"
|
||||
let hapticFeedback = call.getString("hapticFeedback") ?? "LIGHT"
|
||||
let languageCode = call.getString("languageCode") ?? "en-us"
|
||||
let downloadUsingCellular = call.getString("downloadUsingCellular") ?? "ALWAYS"
|
||||
let streamingUsingCellular = call.getString("downloadUsingCellular") ?? "ALWAYS"
|
||||
let settings = DeviceSettings()
|
||||
settings.disableAutoRewind = disableAutoRewind
|
||||
settings.enableAltView = enableAltView
|
||||
|
@ -253,6 +255,8 @@ public class AbsDatabase: CAPPlugin {
|
|||
settings.lockOrientation = lockOrientation
|
||||
settings.hapticFeedback = hapticFeedback
|
||||
settings.languageCode = languageCode
|
||||
settings.downloadUsingCellular = downloadUsingCellular
|
||||
settings.streamingUsingCellular = streamingUsingCellular
|
||||
|
||||
Database.shared.setDeviceSettings(deviceSettings: settings)
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ class DeviceSettings: Object {
|
|||
@Persisted var lockOrientation: String = "NONE"
|
||||
@Persisted var hapticFeedback: String = "LIGHT"
|
||||
@Persisted var languageCode: String = "en-us"
|
||||
@Persisted var downloadUsingCellular: String = "ALWAYS"
|
||||
@Persisted var streamingUsingCellular: String = "ALWAYS"
|
||||
}
|
||||
|
||||
func getDefaultDeviceSettings() -> DeviceSettings {
|
||||
|
@ -32,6 +34,8 @@ func deviceSettingsToJSON(settings: DeviceSettings) -> Dictionary<String, Any> {
|
|||
"jumpForwardTime": settings.jumpForwardTime,
|
||||
"lockOrientation": settings.lockOrientation,
|
||||
"hapticFeedback": settings.hapticFeedback,
|
||||
"languageCode": settings.languageCode
|
||||
"languageCode": settings.languageCode,
|
||||
"downloadUsingCellular": settings.downloadUsingCellular,
|
||||
"streamingUsingCellular": settings.streamingUsingCellular
|
||||
]
|
||||
}
|
||||
|
|
|
@ -135,6 +135,21 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Data settings -->
|
||||
<p class="uppercase text-xs font-semibold text-fg-muted mb-2 mt-10">{{ $strings.HeaderDataSettings }}</p>
|
||||
<div class="py-3 flex items-center">
|
||||
<p class="pr-4 w-36">{{ $strings.LabelDownloadUsingCellular }}</p>
|
||||
<div @click.stop="showDownloadUsingCellularOptions">
|
||||
<ui-text-input :value="downloadUsingCellularOption" readonly append-icon="expand_more" style="max-width: 200px" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-3 flex items-center">
|
||||
<p class="pr-4 w-36">{{ $strings.LabelStreamingUsingCellular }}</p>
|
||||
<div @click.stop="showStreamingUsingCellularOptions">
|
||||
<ui-text-input :value="streamingUsingCellularOption" readonly append-icon="expand_more" style="max-width: 200px" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-show="loading" class="w-full h-full absolute top-0 left-0 flex items-center justify-center z-10">
|
||||
<ui-loading-indicator />
|
||||
</div>
|
||||
|
@ -176,7 +191,9 @@ export default {
|
|||
disableSleepTimerResetFeedback: false,
|
||||
autoSleepTimerAutoRewind: false,
|
||||
autoSleepTimerAutoRewindTime: 300000, // 5 minutes
|
||||
languageCode: 'en-us'
|
||||
languageCode: 'en-us',
|
||||
downloadUsingCellular: 'ALWAYS',
|
||||
streamingUsingCellular: 'ALWAYS'
|
||||
},
|
||||
theme: 'dark',
|
||||
lockCurrentOrientation: false,
|
||||
|
@ -245,6 +262,34 @@ export default {
|
|||
text: this.$strings.LabelVeryHigh,
|
||||
value: 'VERY_HIGH'
|
||||
}
|
||||
],
|
||||
downloadUsingCellularItems: [
|
||||
{
|
||||
text: this.$strings.LabelAskConfirmation,
|
||||
value: 'ASK'
|
||||
},
|
||||
{
|
||||
text: this.$strings.LabelAlways,
|
||||
value: 'ALWAYS'
|
||||
},
|
||||
{
|
||||
text: this.$strings.LabelNever,
|
||||
value: 'NEVER'
|
||||
}
|
||||
],
|
||||
streamingUsingCellularItems: [
|
||||
{
|
||||
text: this.$strings.LabelAskConfirmation,
|
||||
value: 'ASK'
|
||||
},
|
||||
{
|
||||
text: this.$strings.LabelAlways,
|
||||
value: 'ALWAYS'
|
||||
},
|
||||
{
|
||||
text: this.$strings.LabelNever,
|
||||
value: 'NEVER'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -319,11 +364,21 @@ export default {
|
|||
const minutes = Number(this.settings.autoSleepTimerAutoRewindTime) / 1000 / 60
|
||||
return `${minutes} min`
|
||||
},
|
||||
downloadUsingCellularOption() {
|
||||
const item = this.downloadUsingCellularItems.find((i) => i.value === this.settings.downloadUsingCellular)
|
||||
return item?.text || 'Error'
|
||||
},
|
||||
streamingUsingCellularOption() {
|
||||
const item = this.streamingUsingCellularItems.find((i) => i.value === this.settings.streamingUsingCellular)
|
||||
return item?.text || 'Error'
|
||||
},
|
||||
moreMenuItems() {
|
||||
if (this.moreMenuSetting === 'shakeSensitivity') return this.shakeSensitivityItems
|
||||
else if (this.moreMenuSetting === 'hapticFeedback') return this.hapticFeedbackItems
|
||||
else if (this.moreMenuSetting === 'language') return this.languageOptionItems
|
||||
else if (this.moreMenuSetting === 'theme') return this.themeOptionItems
|
||||
else if (this.moreMenuSetting === 'downloadUsingCellular') return this.downloadUsingCellularItems
|
||||
else if (this.moreMenuSetting === 'streamingUsingCellular') return this.streamingUsingCellularItems
|
||||
return []
|
||||
}
|
||||
},
|
||||
|
@ -358,6 +413,14 @@ export default {
|
|||
this.moreMenuSetting = 'theme'
|
||||
this.showMoreMenuDialog = true
|
||||
},
|
||||
showDownloadUsingCellularOptions() {
|
||||
this.moreMenuSetting = 'downloadUsingCellular'
|
||||
this.showMoreMenuDialog = true
|
||||
},
|
||||
showStreamingUsingCellularOptions() {
|
||||
this.moreMenuSetting = 'streamingUsingCellular'
|
||||
this.showMoreMenuDialog = true
|
||||
},
|
||||
clickMenuAction(action) {
|
||||
this.showMoreMenuDialog = false
|
||||
if (this.moreMenuSetting === 'shakeSensitivity') {
|
||||
|
@ -372,6 +435,12 @@ export default {
|
|||
} else if (this.moreMenuSetting === 'theme') {
|
||||
this.theme = action
|
||||
this.saveTheme(action)
|
||||
} else if (this.moreMenuSetting === 'downloadUsingCellular') {
|
||||
this.settings.downloadUsingCellular = action
|
||||
this.saveSettings()
|
||||
} else if (this.moreMenuSetting === 'streamingUsingCellular') {
|
||||
this.settings.streamingUsingCellular = action
|
||||
this.saveSettings()
|
||||
}
|
||||
},
|
||||
saveTheme(theme) {
|
||||
|
@ -504,6 +573,9 @@ export default {
|
|||
this.settings.autoSleepTimerAutoRewindTime = !isNaN(deviceSettings.autoSleepTimerAutoRewindTime) ? deviceSettings.autoSleepTimerAutoRewindTime : 300000 // 5 minutes
|
||||
|
||||
this.settings.languageCode = deviceSettings.languageCode || 'en-us'
|
||||
|
||||
this.settings.downloadUsingCellular = deviceSettings.downloadUsingCellular || 'ALWAYS'
|
||||
this.settings.streamingUsingCellular = deviceSettings.streamingUsingCellular || 'ALWAYS'
|
||||
},
|
||||
async init() {
|
||||
this.loading = true
|
||||
|
|
|
@ -77,6 +77,14 @@ export const getters = {
|
|||
},
|
||||
getOrientationLockSetting: state => {
|
||||
return state.deviceData?.deviceSettings?.lockOrientation
|
||||
},
|
||||
getCanDownloadUsingCellular: state => {
|
||||
if (!state.deviceData?.deviceSettings?.downloadUsingCellular) return 'ALWAYS'
|
||||
return state.deviceData.deviceSettings.downloadUsingCellular || 'ALWAYS'
|
||||
},
|
||||
getCanStreamingUsingCellular: state => {
|
||||
if (!state.deviceData?.deviceSettings?.streamingUsingCellular) return 'ALWAYS'
|
||||
return state.deviceData.deviceSettings.streamingUsingCellular || 'ALWAYS'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
"HeaderCollection": "Collection",
|
||||
"HeaderCollectionItems": "Collection Items",
|
||||
"HeaderConnectionStatus": "Connection Status",
|
||||
"HeaderDataSettings": "Data Settings",
|
||||
"HeaderDetails": "Details",
|
||||
"HeaderDownloads": "Downloads",
|
||||
"HeaderEbookFiles": "Ebook Files",
|
||||
|
@ -87,6 +88,8 @@
|
|||
"LabelAddToPlaylist": "Add to Playlist",
|
||||
"LabelAll": "All",
|
||||
"LabelAllowSeekingOnMediaControls": "Allow position seeking on media notification controls",
|
||||
"LabelAlways": "Always",
|
||||
"LabelAskConfirmation": "Ask for confirmation",
|
||||
"LabelAuthor": "Author",
|
||||
"LabelAuthorFirstLast": "Author (First Last)",
|
||||
"LabelAuthorLastFirst": "Author (Last, First)",
|
||||
|
@ -120,6 +123,7 @@
|
|||
"LabelDiscover": "Discover",
|
||||
"LabelDownload": "Download",
|
||||
"LabelDownloaded": "Downloaded",
|
||||
"LabelDownloadUsingCellular": "Download using Cellular",
|
||||
"LabelDuration": "Duration",
|
||||
"LabelEbook": "Ebook",
|
||||
"LabelEbooks": "Ebooks",
|
||||
|
@ -170,6 +174,7 @@
|
|||
"LabelName": "Name",
|
||||
"LabelNarrator": "Narrator",
|
||||
"LabelNarrators": "Narrators",
|
||||
"LabelNever": "Never",
|
||||
"LabelNewestAuthors": "Newest Authors",
|
||||
"LabelNewestEpisodes": "Newest Episodes",
|
||||
"LabelNo": "No",
|
||||
|
@ -219,6 +224,7 @@
|
|||
"LabelStatsMinutes": "minutes",
|
||||
"LabelStatsMinutesListening": "Minutes Listening",
|
||||
"LabelStatsWeekListening": "Week Listening",
|
||||
"LabelStreamingUsingCellular": "Streaming using Cellular",
|
||||
"LabelTag": "Tag",
|
||||
"LabelTags": "Tags",
|
||||
"LabelTheme": "Theme",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue