Compare commits

...
19 changed files with 70 additions and 44 deletions
+2 -2
View File
@@ -33,8 +33,8 @@ android {
applicationId "com.audiobookshelf.app" applicationId "com.audiobookshelf.app"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 98 versionCode 99
versionName "0.9.67-beta" versionName "0.9.68-beta"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
manifestPlaceholders = [ manifestPlaceholders = [
"appAuthRedirectScheme": "com.audiobookshelf.app" "appAuthRedirectScheme": "com.audiobookshelf.app"
@@ -2,4 +2,5 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background"/> <background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/> <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon> <monochrome android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
@@ -2,4 +2,5 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background"/> <background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/> <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon> <monochrome android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
+2 -2
View File
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<resources> <resources>
<string name="app_name">audiobookshelf</string> <string name="app_name">Audiobookshelf</string>
<string name="title_activity_main">audiobookshelf</string> <string name="title_activity_main">Audiobookshelf</string>
<string name="package_name">com.audiobookshelf.app</string> <string name="package_name">com.audiobookshelf.app</string>
<string name="custom_url_scheme">audiobookshelf</string> <string name="custom_url_scheme">audiobookshelf</string>
<string name="add_widget">Add widget</string> <string name="add_widget">Add widget</string>
+1 -1
View File
@@ -15,10 +15,10 @@
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/app_name" android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config" android:networkSecurityConfig="@xml/network_security_config"
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
@@ -116,15 +116,16 @@ class MediaSessionCallback(var playerNotificationService:PlayerNotificationServi
if (mediaId.isNullOrEmpty()) { if (mediaId.isNullOrEmpty()) {
libraryItemWrapper = playerNotificationService.mediaManager.getFirstItem() libraryItemWrapper = playerNotificationService.mediaManager.getFirstItem()
} else if (mediaId.startsWith("ep_") || mediaId.startsWith("local_ep_")) { // Playing podcast episode
val libraryItemWithEpisode = playerNotificationService.mediaManager.getPodcastWithEpisodeByEpisodeId(mediaId)
libraryItemWrapper = libraryItemWithEpisode?.libraryItemWrapper
podcastEpisode = libraryItemWithEpisode?.episode
} else { } else {
libraryItemWrapper = playerNotificationService.mediaManager.getById(mediaId) val libraryItemWithEpisode = playerNotificationService.mediaManager.getPodcastWithEpisodeByEpisodeId(mediaId)
if (libraryItemWithEpisode != null) {
if (libraryItemWrapper == null) { libraryItemWrapper = libraryItemWithEpisode.libraryItemWrapper
Log.e(tag, "onPlayFromMediaId: Media item not found $mediaId") podcastEpisode = libraryItemWithEpisode.episode
} else {
libraryItemWrapper = playerNotificationService.mediaManager.getById(mediaId)
if (libraryItemWrapper == null) {
Log.e(tag, "onPlayFromMediaId: Media item not found $mediaId")
}
} }
} }
@@ -49,10 +49,10 @@ class MediaSessionPlaybackPreparer(var playerNotificationService:PlayerNotificat
val libraryItemWrapper: LibraryItemWrapper? val libraryItemWrapper: LibraryItemWrapper?
var podcastEpisode: PodcastEpisode? = null var podcastEpisode: PodcastEpisode? = null
if (mediaId.startsWith("ep_") || mediaId.startsWith("local_ep_")) { // Playing podcast episode val libraryItemWithEpisode = playerNotificationService.mediaManager.getPodcastWithEpisodeByEpisodeId(mediaId)
val libraryItemWithEpisode = playerNotificationService.mediaManager.getPodcastWithEpisodeByEpisodeId(mediaId) if (libraryItemWithEpisode != null) {
libraryItemWrapper = libraryItemWithEpisode?.libraryItemWrapper libraryItemWrapper = libraryItemWithEpisode.libraryItemWrapper
podcastEpisode = libraryItemWithEpisode?.episode podcastEpisode = libraryItemWithEpisode.episode
} else { } else {
libraryItemWrapper = playerNotificationService.mediaManager.getById(mediaId) libraryItemWrapper = playerNotificationService.mediaManager.getById(mediaId)
} }
@@ -2,4 +2,5 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background"/> <background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/> <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon> <monochrome android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
@@ -2,4 +2,5 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background"/> <background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/> <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon> <monochrome android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
+2 -2
View File
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<resources> <resources>
<string name="app_name">audiobookshelf</string> <string name="app_name">Audiobookshelf</string>
<string name="title_activity_main">audiobookshelf</string> <string name="title_activity_main">Audiobookshelf</string>
<string name="package_name">com.audiobookshelf.app</string> <string name="package_name">com.audiobookshelf.app</string>
<string name="custom_url_scheme">audiobookshelf</string> <string name="custom_url_scheme">audiobookshelf</string>
<string name="add_widget">Add widget</string> <string name="add_widget">Add widget</string>
+2 -2
View File
@@ -244,7 +244,7 @@ export default {
this.oauth.challenge = challenge this.oauth.challenge = challenge
// set parameter isRest to true, so the backend wont attempt a redirect after we call backend:/callback in exchangeCodeForToken // set parameter isRest to true, so the backend wont attempt a redirect after we call backend:/callback in exchangeCodeForToken
const backendEndpoint = `${url}auth/openid?code_challenge=${challenge}&code_challenge_method=S256&isRest=true` const backendEndpoint = `${url}/auth/openid?code_challenge=${challenge}&code_challenge_method=S256&isRest=true`
try { try {
const response = await CapacitorHttp.get({ const response = await CapacitorHttp.get({
@@ -568,7 +568,7 @@ export default {
}) })
}, },
requestServerLogin() { requestServerLogin() {
return this.postRequest(`${this.serverConfig.address}/login`, { username: this.serverConfig.username, password: this.password }, this.serverConfig.customHeaders, 20000) return this.postRequest(`${this.serverConfig.address}/login`, { username: this.serverConfig.username, password: this.password || '' }, this.serverConfig.customHeaders, 20000)
.then((data) => { .then((data) => {
if (!data.user) { if (!data.user) {
console.error(data.error) console.error(data.error)
+1 -1
View File
@@ -165,7 +165,7 @@ export default {
}, },
localEpisode() { localEpisode() {
if (this.isLocal) return this.episode if (this.isLocal) return this.episode
return this.episode.localEpisode return this.episode?.localEpisode
}, },
localEpisodeId() { localEpisodeId() {
return this.localEpisode?.id || null return this.localEpisode?.id || null
+3 -3
View File
@@ -132,10 +132,10 @@ export default {
} }
}, },
itemProgressPercent() { itemProgressPercent() {
return this.itemProgress ? this.itemProgress.progress : 0 return this.itemProgress?.progress || 0
}, },
userIsFinished() { userIsFinished() {
return this.itemProgress ? !!this.itemProgress.isFinished : false return !!this.itemProgress?.isFinished
}, },
timeRemaining() { timeRemaining() {
if (this.streamIsPlaying) return 'Playing' if (this.streamIsPlaying) return 'Playing'
@@ -151,7 +151,7 @@ export default {
return this.$store.getters['globals/getDownloadItem'](this.libraryItemId, this.episode.id) return this.$store.getters['globals/getDownloadItem'](this.libraryItemId, this.episode.id)
}, },
localEpisodeId() { localEpisodeId() {
return this.localEpisode ? this.localEpisode.id : null return this.localEpisode?.id || null
} }
}, },
methods: { methods: {
+14 -4
View File
@@ -116,6 +116,10 @@ export default {
{ {
text: 'Complete', text: 'Complete',
value: 'complete' value: 'complete'
},
{
text: 'Downloaded',
value: 'downloaded'
} }
], ],
fetchingRSSFeed: false, fetchingRSSFeed: false,
@@ -141,10 +145,10 @@ export default {
return this.$store.state.networkConnected return this.$store.state.networkConnected
}, },
libraryItemId() { libraryItemId() {
return this.libraryItem ? this.libraryItem.id : null return this.libraryItem?.id || null
}, },
media() { media() {
return this.libraryItem ? this.libraryItem.media || {} : {} return this.libraryItem?.media || {}
}, },
mediaMetadata() { mediaMetadata() {
return this.media.metadata || {} return this.media.metadata || {}
@@ -154,11 +158,14 @@ export default {
}, },
episodesFiltered() { episodesFiltered() {
return this.episodesCopy.filter((ep) => { return this.episodesCopy.filter((ep) => {
if (this.filterKey === 'downloaded') {
return !!this.localEpisodeMap[ep.id]
}
var mediaProgress = this.getEpisodeProgress(ep) var mediaProgress = this.getEpisodeProgress(ep)
if (this.filterKey === 'incomplete') { if (this.filterKey === 'incomplete') {
return !mediaProgress || !mediaProgress.isFinished return !mediaProgress?.isFinished
} else if (this.filterKey === 'complete') { } else if (this.filterKey === 'complete') {
return mediaProgress && mediaProgress.isFinished return mediaProgress?.isFinished
} else if (this.filterKey === 'inProgress') { } else if (this.filterKey === 'inProgress') {
return mediaProgress && !mediaProgress.isFinished return mediaProgress && !mediaProgress.isFinished
} else if (this.filterKey === 'all') { } else if (this.filterKey === 'all') {
@@ -290,6 +297,9 @@ export default {
} }
}, },
mounted() { mounted() {
if (this.$route.query['episodefilter'] === 'downloaded') {
this.filterKey = 'downloaded'
}
this.$socket.$on('episode_download_queued', this.episodeDownloadQueued) this.$socket.$on('episode_download_queued', this.episodeDownloadQueued)
this.$socket.$on('episode_download_started', this.episodeDownloadStarted) this.$socket.$on('episode_download_started', this.episodeDownloadStarted)
this.$socket.$on('episode_download_finished', this.episodeDownloadFinished) this.$socket.$on('episode_download_finished', this.episodeDownloadFinished)
+4 -4
View File
@@ -728,12 +728,12 @@
ASSETCATALOG_COMPILER_APPICON_NAME = Icons; ASSETCATALOG_COMPILER_APPICON_NAME = Icons;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 24; CURRENT_PROJECT_VERSION = 25;
DEVELOPMENT_TEAM = 7UFJ7D8V6A; DEVELOPMENT_TEAM = 7UFJ7D8V6A;
INFOPLIST_FILE = App/Info.plist; INFOPLIST_FILE = App/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0; IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 0.9.67; MARKETING_VERSION = 0.9.68;
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
PRODUCT_BUNDLE_IDENTIFIER = com.audiobookshelf.app.dev; PRODUCT_BUNDLE_IDENTIFIER = com.audiobookshelf.app.dev;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -752,12 +752,12 @@
ASSETCATALOG_COMPILER_APPICON_NAME = Icons; ASSETCATALOG_COMPILER_APPICON_NAME = Icons;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 24; CURRENT_PROJECT_VERSION = 25;
DEVELOPMENT_TEAM = 7UFJ7D8V6A; DEVELOPMENT_TEAM = 7UFJ7D8V6A;
INFOPLIST_FILE = App/Info.plist; INFOPLIST_FILE = App/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0; IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 0.9.67; MARKETING_VERSION = 0.9.68;
PRODUCT_BUNDLE_IDENTIFIER = com.audiobookshelf.app; PRODUCT_BUNDLE_IDENTIFIER = com.audiobookshelf.app;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "audiobookshelf-app", "name": "audiobookshelf-app",
"version": "0.9.67-beta", "version": "0.9.68-beta",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "audiobookshelf-app", "name": "audiobookshelf-app",
"version": "0.9.67-beta", "version": "0.9.68-beta",
"dependencies": { "dependencies": {
"@capacitor/android": "^5.0.0", "@capacitor/android": "^5.0.0",
"@capacitor/app": "^5.0.6", "@capacitor/app": "^5.0.6",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "audiobookshelf-app", "name": "audiobookshelf-app",
"version": "0.9.67-beta", "version": "0.9.68-beta",
"author": "advplyr", "author": "advplyr",
"scripts": { "scripts": {
"dev": "nuxt --hostname 0.0.0.0 --port 1337", "dev": "nuxt --hostname 0.0.0.0 --port 1337",
+8 -3
View File
@@ -169,8 +169,13 @@ export default {
libraryItem = await app.$db.getLocalLibraryItem(libraryItemId) libraryItem = await app.$db.getLocalLibraryItem(libraryItemId)
console.log('Got lli', libraryItemId) console.log('Got lli', libraryItemId)
// If library item is linked to the currently connected server then redirect to the page using the server library item id // If library item is linked to the currently connected server then redirect to the page using the server library item id
if (libraryItem?.libraryItemId && libraryItem?.serverAddress === store.getters['user/getServerAddress']) { if (libraryItem?.libraryItemId?.startsWith('li_')) {
return redirect(`/item/${libraryItem.libraryItemId}`) // Detect old library item id
console.error('Local library item has old server library item id', libraryItem.libraryItemId)
} else if (libraryItem?.libraryItemId && libraryItem?.serverAddress === store.getters['user/getServerAddress'] && store.state.networkConnected) {
let query = ''
if (libraryItem.mediaType === 'podcast') query = '?episodefilter=downloaded' // Filter by downloaded when redirecting from the local copy
return redirect(`/item/${libraryItem.libraryItemId}${query}`)
} }
} else if (store.state.user.serverConnectionConfig) { } else if (store.state.user.serverConnectionConfig) {
libraryItem = await app.$nativeHttp.get(`/api/items/${libraryItemId}?expanded=1&include=rssfeed`).catch((error) => { libraryItem = await app.$nativeHttp.get(`/api/items/${libraryItemId}?expanded=1&include=rssfeed`).catch((error) => {
@@ -272,7 +277,7 @@ export default {
*/ */
isLocalMatchingUser() { isLocalMatchingUser() {
if (this.isLocalOnly || !this.localLibraryItem || !this.user) return false if (this.isLocalOnly || !this.localLibraryItem || !this.user) return false
return this.localLibraryItem.serverUserId === this.user.id return this.localLibraryItem.serverUserId === this.user.id || this.localLibraryItem.serverUserId === this.user.oldUserId
}, },
/** /**
* User is currently connected to a server and this local library item has the same connection config id * User is currently connected to a server and this local library item has the same connection config id
+7 -1
View File
@@ -27,7 +27,13 @@ export default function ({ store }, inject) {
data, data,
headers, headers,
...options ...options
}).then(res => res.data) }).then(res => {
if (res.status >= 400) {
console.error(`[nativeHttp] ${res.status} status for url "${url}"`)
throw new Error(res.data)
}
return res.data
})
}, },
get(url, options = {}) { get(url, options = {}) {
return this.request('GET', url, undefined, options) return this.request('GET', url, undefined, options)