Initial work

This commit is contained in:
Marcos Carvalho 2024-05-23 22:33:06 +01:00
parent f047f6a23b
commit d788623509
No known key found for this signature in database
9 changed files with 214 additions and 44 deletions

View file

@ -20,6 +20,14 @@ enum class ShakeSensitivitySetting {
VERY_LOW, LOW, MEDIUM, HIGH, VERY_HIGH VERY_LOW, LOW, MEDIUM, HIGH, VERY_HIGH
} }
enum class DownloadUsingCellularSetting {
ASK, ALWAYS, NEVER
}
enum class StreamingUsingCellularSetting {
ASK, ALWAYS, NEVER
}
data class ServerConnectionConfig( data class ServerConnectionConfig(
var id:String, var id:String,
var index:Int, var index:Int,
@ -123,7 +131,9 @@ data class DeviceSettings(
var sleepTimerLength: Long, // Time in milliseconds var sleepTimerLength: Long, // Time in milliseconds
var disableSleepTimerFadeOut: Boolean, var disableSleepTimerFadeOut: Boolean,
var disableSleepTimerResetFeedback: Boolean, var disableSleepTimerResetFeedback: Boolean,
var languageCode: String var languageCode: String,
var downloadUsingCellular: DownloadUsingCellularSetting,
var streamingUsingCellular: StreamingUsingCellularSetting
) { ) {
companion object { companion object {
// Static method to get default device settings // Static method to get default device settings
@ -147,7 +157,9 @@ data class DeviceSettings(
autoSleepTimerAutoRewindTime = 300000L, // 5 minutes autoSleepTimerAutoRewindTime = 300000L, // 5 minutes
disableSleepTimerFadeOut = false, disableSleepTimerFadeOut = false,
disableSleepTimerResetFeedback = false, disableSleepTimerResetFeedback = false,
languageCode = "en-us" languageCode = "en-us",
downloadUsingCellular = DownloadUsingCellularSetting.ALWAYS,
streamingUsingCellular = StreamingUsingCellularItems.ALWAYS
) )
} }
} }

View file

@ -53,6 +53,14 @@ object DeviceManager {
if (deviceData.deviceSettings?.languageCode == null) { if (deviceData.deviceSettings?.languageCode == null) {
deviceData.deviceSettings?.languageCode = "en-us" 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 { fun getBase64Id(id:String):String {

View file

@ -60,6 +60,7 @@
</template> </template>
<script> <script>
import { Dialog } from '@capacitor/dialog'
import { AbsFileSystem, AbsDownloader } from '@/plugins/capacitor' import { AbsFileSystem, AbsDownloader } from '@/plugins/capacitor'
export default { export default {
@ -96,6 +97,15 @@ export default {
userCanDownload() { userCanDownload() {
return this.$store.getters['user/getUserCanDownload'] 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() { audioFile() {
return this.episode.audioFile return this.episode.audioFile
}, },
@ -185,8 +195,45 @@ export default {
} }
return folderObj 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() { async downloadClick() {
if (this.downloadItem || this.pendingDownload) return if (this.downloadItem || this.pendingDownload) return
const hasPermission = await this.checkDownloadPermission()
if (!hasPermission) return
this.pendingDownload = true this.pendingDownload = true
await this.$hapticsImpact() await this.$hapticsImpact()
if (this.isIos) { if (this.isIos) {
@ -258,9 +305,8 @@ export default {
if (this.streamIsPlaying) { if (this.streamIsPlaying) {
this.$eventBus.$emit('pause-item') this.$eventBus.$emit('pause-item')
} else { } else {
this.$store.commit('setPlayerIsStartingPlayback', this.episode.id)
if (this.localEpisode && this.localLibraryItemId) { if (this.localEpisode && this.localLibraryItemId) {
this.$store.commit('setPlayerIsStartingPlayback', this.episode.id)
console.log('Play local episode', this.localEpisode.id, this.localLibraryItemId) console.log('Play local episode', this.localEpisode.id, this.localLibraryItemId)
this.$eventBus.$emit('play-item', { this.$eventBus.$emit('play-item', {
@ -270,6 +316,10 @@ export default {
serverEpisodeId: this.episode.id serverEpisodeId: this.episode.id
}) })
} else { } else {
const hasPermission = await this.checkStreamPermission()
if (!hasPermission) return
this.$store.commit('setPlayerIsStartingPlayback', this.episode.id)
this.$eventBus.$emit('play-item', { this.$eventBus.$emit('play-item', {
libraryItemId: this.libraryItemId, libraryItemId: this.libraryItemId,
episodeId: this.episode.id episodeId: this.episode.id

View file

@ -14,7 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// Override point for customization after application launch. // Override point for customization after application launch.
let configuration = Realm.Configuration( let configuration = Realm.Configuration(
schemaVersion: 17, schemaVersion: 18,
migrationBlock: { [weak self] migration, oldSchemaVersion in migrationBlock: { [weak self] migration, oldSchemaVersion in
if (oldSchemaVersion < 1) { if (oldSchemaVersion < 1) {
self?.logger.log("Realm schema version was \(oldSchemaVersion)") self?.logger.log("Realm schema version was \(oldSchemaVersion)")
@ -54,6 +54,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
newObject?["chapterTrack"] = false 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"
}
} }
) )

View file

@ -244,6 +244,8 @@ public class AbsDatabase: CAPPlugin {
let lockOrientation = call.getString("lockOrientation") ?? "NONE" let lockOrientation = call.getString("lockOrientation") ?? "NONE"
let hapticFeedback = call.getString("hapticFeedback") ?? "LIGHT" let hapticFeedback = call.getString("hapticFeedback") ?? "LIGHT"
let languageCode = call.getString("languageCode") ?? "en-us" let languageCode = call.getString("languageCode") ?? "en-us"
let downloadUsingCellular = call.getString("downloadUsingCellular") ?? "ALWAYS"
let streamingUsingCellular = call.getString("downloadUsingCellular") ?? "ALWAYS"
let settings = DeviceSettings() let settings = DeviceSettings()
settings.disableAutoRewind = disableAutoRewind settings.disableAutoRewind = disableAutoRewind
settings.enableAltView = enableAltView settings.enableAltView = enableAltView
@ -253,6 +255,8 @@ public class AbsDatabase: CAPPlugin {
settings.lockOrientation = lockOrientation settings.lockOrientation = lockOrientation
settings.hapticFeedback = hapticFeedback settings.hapticFeedback = hapticFeedback
settings.languageCode = languageCode settings.languageCode = languageCode
settings.downloadUsingCellular = downloadUsingCellular
settings.streamingUsingCellular = streamingUsingCellular
Database.shared.setDeviceSettings(deviceSettings: settings) Database.shared.setDeviceSettings(deviceSettings: settings)

View file

@ -17,6 +17,8 @@ class DeviceSettings: Object {
@Persisted var lockOrientation: String = "NONE" @Persisted var lockOrientation: String = "NONE"
@Persisted var hapticFeedback: String = "LIGHT" @Persisted var hapticFeedback: String = "LIGHT"
@Persisted var languageCode: String = "en-us" @Persisted var languageCode: String = "en-us"
@Persisted var downloadUsingCellular: String = "ALWAYS"
@Persisted var streamingUsingCellular: String = "ALWAYS"
} }
func getDefaultDeviceSettings() -> DeviceSettings { func getDefaultDeviceSettings() -> DeviceSettings {
@ -32,6 +34,8 @@ func deviceSettingsToJSON(settings: DeviceSettings) -> Dictionary<String, Any> {
"jumpForwardTime": settings.jumpForwardTime, "jumpForwardTime": settings.jumpForwardTime,
"lockOrientation": settings.lockOrientation, "lockOrientation": settings.lockOrientation,
"hapticFeedback": settings.hapticFeedback, "hapticFeedback": settings.hapticFeedback,
"languageCode": settings.languageCode "languageCode": settings.languageCode,
"downloadUsingCellular": settings.downloadUsingCellular,
"streamingUsingCellular": settings.streamingUsingCellular
] ]
} }

View file

@ -135,6 +135,21 @@
</div> </div>
</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"> <div v-show="loading" class="w-full h-full absolute top-0 left-0 flex items-center justify-center z-10">
<ui-loading-indicator /> <ui-loading-indicator />
</div> </div>
@ -176,7 +191,9 @@ export default {
disableSleepTimerResetFeedback: false, disableSleepTimerResetFeedback: false,
autoSleepTimerAutoRewind: false, autoSleepTimerAutoRewind: false,
autoSleepTimerAutoRewindTime: 300000, // 5 minutes autoSleepTimerAutoRewindTime: 300000, // 5 minutes
languageCode: 'en-us' languageCode: 'en-us',
downloadUsingCellular: 'ALWAYS',
streamingUsingCellular: 'ALWAYS'
}, },
theme: 'dark', theme: 'dark',
lockCurrentOrientation: false, lockCurrentOrientation: false,
@ -245,6 +262,34 @@ export default {
text: this.$strings.LabelVeryHigh, text: this.$strings.LabelVeryHigh,
value: 'VERY_HIGH' 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 const minutes = Number(this.settings.autoSleepTimerAutoRewindTime) / 1000 / 60
return `${minutes} min` 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() { moreMenuItems() {
if (this.moreMenuSetting === 'shakeSensitivity') return this.shakeSensitivityItems if (this.moreMenuSetting === 'shakeSensitivity') return this.shakeSensitivityItems
else if (this.moreMenuSetting === 'hapticFeedback') return this.hapticFeedbackItems else if (this.moreMenuSetting === 'hapticFeedback') return this.hapticFeedbackItems
else if (this.moreMenuSetting === 'language') return this.languageOptionItems else if (this.moreMenuSetting === 'language') return this.languageOptionItems
else if (this.moreMenuSetting === 'theme') return this.themeOptionItems 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 [] return []
} }
}, },
@ -358,6 +413,14 @@ export default {
this.moreMenuSetting = 'theme' this.moreMenuSetting = 'theme'
this.showMoreMenuDialog = true this.showMoreMenuDialog = true
}, },
showDownloadUsingCellularOptions() {
this.moreMenuSetting = 'downloadUsingCellular'
this.showMoreMenuDialog = true
},
showStreamingUsingCellularOptions() {
this.moreMenuSetting = 'streamingUsingCellular'
this.showMoreMenuDialog = true
},
clickMenuAction(action) { clickMenuAction(action) {
this.showMoreMenuDialog = false this.showMoreMenuDialog = false
if (this.moreMenuSetting === 'shakeSensitivity') { if (this.moreMenuSetting === 'shakeSensitivity') {
@ -372,6 +435,12 @@ export default {
} else if (this.moreMenuSetting === 'theme') { } else if (this.moreMenuSetting === 'theme') {
this.theme = action this.theme = action
this.saveTheme(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) { saveTheme(theme) {
@ -504,6 +573,9 @@ export default {
this.settings.autoSleepTimerAutoRewindTime = !isNaN(deviceSettings.autoSleepTimerAutoRewindTime) ? deviceSettings.autoSleepTimerAutoRewindTime : 300000 // 5 minutes this.settings.autoSleepTimerAutoRewindTime = !isNaN(deviceSettings.autoSleepTimerAutoRewindTime) ? deviceSettings.autoSleepTimerAutoRewindTime : 300000 // 5 minutes
this.settings.languageCode = deviceSettings.languageCode || 'en-us' this.settings.languageCode = deviceSettings.languageCode || 'en-us'
this.settings.downloadUsingCellular = deviceSettings.downloadUsingCellular || 'ALWAYS'
this.settings.streamingUsingCellular = deviceSettings.streamingUsingCellular || 'ALWAYS'
}, },
async init() { async init() {
this.loading = true this.loading = true

View file

@ -77,6 +77,14 @@ export const getters = {
}, },
getOrientationLockSetting: state => { getOrientationLockSetting: state => {
return state.deviceData?.deviceSettings?.lockOrientation 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'
} }
} }

View file

@ -56,6 +56,7 @@
"HeaderCollection": "Collection", "HeaderCollection": "Collection",
"HeaderCollectionItems": "Collection Items", "HeaderCollectionItems": "Collection Items",
"HeaderConnectionStatus": "Connection Status", "HeaderConnectionStatus": "Connection Status",
"HeaderDataSettings": "Data Settings",
"HeaderDetails": "Details", "HeaderDetails": "Details",
"HeaderDownloads": "Downloads", "HeaderDownloads": "Downloads",
"HeaderEbookFiles": "Ebook Files", "HeaderEbookFiles": "Ebook Files",
@ -87,6 +88,8 @@
"LabelAddToPlaylist": "Add to Playlist", "LabelAddToPlaylist": "Add to Playlist",
"LabelAll": "All", "LabelAll": "All",
"LabelAllowSeekingOnMediaControls": "Allow position seeking on media notification controls", "LabelAllowSeekingOnMediaControls": "Allow position seeking on media notification controls",
"LabelAlways": "Always",
"LabelAskConfirmation": "Ask for confirmation",
"LabelAuthor": "Author", "LabelAuthor": "Author",
"LabelAuthorFirstLast": "Author (First Last)", "LabelAuthorFirstLast": "Author (First Last)",
"LabelAuthorLastFirst": "Author (Last, First)", "LabelAuthorLastFirst": "Author (Last, First)",
@ -120,6 +123,7 @@
"LabelDiscover": "Discover", "LabelDiscover": "Discover",
"LabelDownload": "Download", "LabelDownload": "Download",
"LabelDownloaded": "Downloaded", "LabelDownloaded": "Downloaded",
"LabelDownloadUsingCellular": "Download using Cellular",
"LabelDuration": "Duration", "LabelDuration": "Duration",
"LabelEbook": "Ebook", "LabelEbook": "Ebook",
"LabelEbooks": "Ebooks", "LabelEbooks": "Ebooks",
@ -170,6 +174,7 @@
"LabelName": "Name", "LabelName": "Name",
"LabelNarrator": "Narrator", "LabelNarrator": "Narrator",
"LabelNarrators": "Narrators", "LabelNarrators": "Narrators",
"LabelNever": "Never",
"LabelNewestAuthors": "Newest Authors", "LabelNewestAuthors": "Newest Authors",
"LabelNewestEpisodes": "Newest Episodes", "LabelNewestEpisodes": "Newest Episodes",
"LabelNo": "No", "LabelNo": "No",
@ -219,6 +224,7 @@
"LabelStatsMinutes": "minutes", "LabelStatsMinutes": "minutes",
"LabelStatsMinutesListening": "Minutes Listening", "LabelStatsMinutesListening": "Minutes Listening",
"LabelStatsWeekListening": "Week Listening", "LabelStatsWeekListening": "Week Listening",
"LabelStreamingUsingCellular": "Streaming using Cellular",
"LabelTag": "Tag", "LabelTag": "Tag",
"LabelTags": "Tags", "LabelTags": "Tags",
"LabelTheme": "Theme", "LabelTheme": "Theme",