diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index abaa9ce9..7b1d958a 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -15,7 +15,7 @@
}
# Keep Chromecast methods
--keepclassmembers class org.jellyfin.mobile.cast.Chromecast {
+-keepclassmembers class org.jellyfin.mobile.player.cast.Chromecast {
public *;
}
diff --git a/app/src/libre/java/org/jellyfin/mobile/cast/CastPlayerProvider.kt b/app/src/libre/java/org/jellyfin/mobile/player/cast/CastPlayerProvider.kt
similarity index 73%
rename from app/src/libre/java/org/jellyfin/mobile/cast/CastPlayerProvider.kt
rename to app/src/libre/java/org/jellyfin/mobile/player/cast/CastPlayerProvider.kt
index a778d22d..70d84821 100644
--- a/app/src/libre/java/org/jellyfin/mobile/cast/CastPlayerProvider.kt
+++ b/app/src/libre/java/org/jellyfin/mobile/player/cast/CastPlayerProvider.kt
@@ -1,7 +1,7 @@
-package org.jellyfin.mobile.cast
+package org.jellyfin.mobile.player.cast
import com.google.android.exoplayer2.Player
-import org.jellyfin.mobile.media.MediaService
+import org.jellyfin.mobile.player.audio.MediaService
class CastPlayerProvider(@Suppress("UNUSED_PARAMETER") mediaService: MediaService) : ICastPlayerProvider {
override val isCastSessionAvailable: Boolean = false
diff --git a/app/src/libre/java/org/jellyfin/mobile/cast/Chromecast.kt b/app/src/libre/java/org/jellyfin/mobile/player/cast/Chromecast.kt
similarity index 89%
rename from app/src/libre/java/org/jellyfin/mobile/cast/Chromecast.kt
rename to app/src/libre/java/org/jellyfin/mobile/player/cast/Chromecast.kt
index e51c4ade..49163fd7 100644
--- a/app/src/libre/java/org/jellyfin/mobile/cast/Chromecast.kt
+++ b/app/src/libre/java/org/jellyfin/mobile/player/cast/Chromecast.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.cast
+package org.jellyfin.mobile.player.cast
import android.app.Activity
import org.jellyfin.mobile.bridge.JavascriptCallback
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5c87bc31..5d6e86a4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -59,7 +59,7 @@
diff --git a/app/src/main/java/org/jellyfin/mobile/JellyfinApplication.kt b/app/src/main/java/org/jellyfin/mobile/JellyfinApplication.kt
index 29d07c15..34938611 100644
--- a/app/src/main/java/org/jellyfin/mobile/JellyfinApplication.kt
+++ b/app/src/main/java/org/jellyfin/mobile/JellyfinApplication.kt
@@ -3,8 +3,9 @@ package org.jellyfin.mobile
import android.app.Application
import android.webkit.WebView
import com.melegy.redscreenofdeath.RedScreenOfDeath
-import org.jellyfin.mobile.api.apiModule
-import org.jellyfin.mobile.model.databaseModule
+import org.jellyfin.mobile.app.apiModule
+import org.jellyfin.mobile.app.applicationModule
+import org.jellyfin.mobile.data.databaseModule
import org.jellyfin.mobile.utils.JellyTree
import org.jellyfin.mobile.utils.isWebViewSupported
import org.koin.android.ext.koin.androidContext
diff --git a/app/src/main/java/org/jellyfin/mobile/MainActivity.kt b/app/src/main/java/org/jellyfin/mobile/MainActivity.kt
index 51605960..1b291098 100644
--- a/app/src/main/java/org/jellyfin/mobile/MainActivity.kt
+++ b/app/src/main/java/org/jellyfin/mobile/MainActivity.kt
@@ -13,18 +13,16 @@ import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
-import org.jellyfin.mobile.cast.Chromecast
-import org.jellyfin.mobile.cast.IChromecast
-import org.jellyfin.mobile.fragment.ConnectFragment
-import org.jellyfin.mobile.fragment.WebViewFragment
-import org.jellyfin.mobile.player.PlayerFragment
+import org.jellyfin.mobile.player.cast.Chromecast
+import org.jellyfin.mobile.player.cast.IChromecast
+import org.jellyfin.mobile.setup.ConnectFragment
+import org.jellyfin.mobile.webapp.WebViewFragment
+import org.jellyfin.mobile.player.ui.PlayerFragment
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.mobile.utils.PermissionRequestHelper
import org.jellyfin.mobile.utils.SmartOrientationListener
import org.jellyfin.mobile.utils.isWebViewSupported
-import org.jellyfin.mobile.utils.replaceFragment
-import org.jellyfin.mobile.viewmodel.MainViewModel
-import org.jellyfin.mobile.viewmodel.ServerState
+import org.jellyfin.mobile.utils.extensions.replaceFragment
import org.jellyfin.mobile.webapp.RemotePlayerService
import org.koin.android.ext.android.inject
import org.koin.androidx.fragment.android.setupKoinFragmentFactory
diff --git a/app/src/main/java/org/jellyfin/mobile/viewmodel/MainViewModel.kt b/app/src/main/java/org/jellyfin/mobile/MainViewModel.kt
similarity index 74%
rename from app/src/main/java/org/jellyfin/mobile/viewmodel/MainViewModel.kt
rename to app/src/main/java/org/jellyfin/mobile/MainViewModel.kt
index 6236c796..fdf33f9c 100644
--- a/app/src/main/java/org/jellyfin/mobile/viewmodel/MainViewModel.kt
+++ b/app/src/main/java/org/jellyfin/mobile/MainViewModel.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.viewmodel
+package org.jellyfin.mobile
import android.app.Application
import androidx.lifecycle.AndroidViewModel
@@ -6,25 +6,25 @@ import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
-import org.jellyfin.mobile.controller.ApiController
-import org.jellyfin.mobile.model.sql.entity.ServerEntity
+import org.jellyfin.mobile.app.ApiClientController
+import org.jellyfin.mobile.data.entity.ServerEntity
class MainViewModel(
app: Application,
- private val apiController: ApiController,
+ private val apiClientController: ApiClientController,
) : AndroidViewModel(app) {
private val _serverState: MutableStateFlow = MutableStateFlow(ServerState.Pending)
val serverState: StateFlow get() = _serverState
init {
viewModelScope.launch {
- apiController.migrateFromPreferences()
+ apiClientController.migrateFromPreferences()
refreshServer()
}
}
suspend fun refreshServer() {
- val server = apiController.loadSavedServer()
+ val server = apiClientController.loadSavedServer()
_serverState.value = server?.let { ServerState.Available(it) } ?: ServerState.Unset
}
}
diff --git a/app/src/main/java/org/jellyfin/mobile/controller/ApiController.kt b/app/src/main/java/org/jellyfin/mobile/app/ApiClientController.kt
similarity index 91%
rename from app/src/main/java/org/jellyfin/mobile/controller/ApiController.kt
rename to app/src/main/java/org/jellyfin/mobile/app/ApiClientController.kt
index 7e34acab..db391f13 100644
--- a/app/src/main/java/org/jellyfin/mobile/controller/ApiController.kt
+++ b/app/src/main/java/org/jellyfin/mobile/app/ApiClientController.kt
@@ -1,18 +1,17 @@
-package org.jellyfin.mobile.controller
+package org.jellyfin.mobile.app
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
-import org.jellyfin.mobile.AppPreferences
-import org.jellyfin.mobile.model.sql.dao.ServerDao
-import org.jellyfin.mobile.model.sql.dao.UserDao
-import org.jellyfin.mobile.model.sql.entity.ServerEntity
+import org.jellyfin.mobile.data.dao.ServerDao
+import org.jellyfin.mobile.data.dao.UserDao
+import org.jellyfin.mobile.data.entity.ServerEntity
import org.jellyfin.sdk.Jellyfin
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.model.DeviceInfo
import org.jellyfin.sdk.model.serializer.toUUID
import java.util.*
-class ApiController(
+class ApiClientController(
private val appPreferences: AppPreferences,
private val jellyfin: Jellyfin,
private val apiClient: ApiClient,
diff --git a/app/src/main/java/org/jellyfin/mobile/api/ApiModule.kt b/app/src/main/java/org/jellyfin/mobile/app/ApiModule.kt
similarity index 94%
rename from app/src/main/java/org/jellyfin/mobile/api/ApiModule.kt
rename to app/src/main/java/org/jellyfin/mobile/app/ApiModule.kt
index 66e50038..08246209 100644
--- a/app/src/main/java/org/jellyfin/mobile/api/ApiModule.kt
+++ b/app/src/main/java/org/jellyfin/mobile/app/ApiModule.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.api
+package org.jellyfin.mobile.app
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.sdk.Jellyfin
diff --git a/app/src/main/java/org/jellyfin/mobile/ApplicationModule.kt b/app/src/main/java/org/jellyfin/mobile/app/AppModule.kt
similarity index 87%
rename from app/src/main/java/org/jellyfin/mobile/ApplicationModule.kt
rename to app/src/main/java/org/jellyfin/mobile/app/AppModule.kt
index 7b6cd62b..35d865db 100644
--- a/app/src/main/java/org/jellyfin/mobile/ApplicationModule.kt
+++ b/app/src/main/java/org/jellyfin/mobile/app/AppModule.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile
+package org.jellyfin.mobile.app
import android.content.Context
import coil.ImageLoader
@@ -15,19 +15,18 @@ import com.google.android.exoplayer2.upstream.DefaultHttpDataSource
import com.google.android.exoplayer2.util.Util
import kotlinx.coroutines.channels.Channel
import okhttp3.OkHttpClient
-import org.jellyfin.mobile.api.DeviceProfileBuilder
+import org.jellyfin.mobile.MainViewModel
+import org.jellyfin.mobile.player.deviceprofile.DeviceProfileBuilder
import org.jellyfin.mobile.bridge.ExternalPlayer
-import org.jellyfin.mobile.controller.ApiController
-import org.jellyfin.mobile.fragment.ConnectFragment
-import org.jellyfin.mobile.fragment.WebViewFragment
-import org.jellyfin.mobile.media.car.LibraryBrowser
-import org.jellyfin.mobile.player.PlayerEvent
-import org.jellyfin.mobile.player.PlayerFragment
+import org.jellyfin.mobile.setup.ConnectFragment
+import org.jellyfin.mobile.webapp.WebViewFragment
+import org.jellyfin.mobile.player.audio.car.LibraryBrowser
+import org.jellyfin.mobile.player.interaction.PlayerEvent
+import org.jellyfin.mobile.player.ui.PlayerFragment
import org.jellyfin.mobile.player.source.MediaSourceResolver
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.mobile.utils.PermissionRequestHelper
import org.jellyfin.mobile.utils.isLowRamDevice
-import org.jellyfin.mobile.viewmodel.MainViewModel
import org.jellyfin.mobile.webapp.RemoteVolumeProvider
import org.jellyfin.mobile.webapp.WebappFunctionChannel
import org.koin.android.ext.koin.androidApplication
@@ -49,7 +48,7 @@ val applicationModule = module {
single(named(PLAYER_EVENT_CHANNEL)) { Channel() }
// Controllers
- single { ApiController(get(), get(), get(), get(), get()) }
+ single { ApiClientController(get(), get(), get(), get(), get()) }
// ViewModels
viewModel { MainViewModel(get(), get()) }
diff --git a/app/src/main/java/org/jellyfin/mobile/AppPreferences.kt b/app/src/main/java/org/jellyfin/mobile/app/AppPreferences.kt
similarity index 99%
rename from app/src/main/java/org/jellyfin/mobile/AppPreferences.kt
rename to app/src/main/java/org/jellyfin/mobile/app/AppPreferences.kt
index b82c0077..cdce7428 100644
--- a/app/src/main/java/org/jellyfin/mobile/AppPreferences.kt
+++ b/app/src/main/java/org/jellyfin/mobile/app/AppPreferences.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile
+package org.jellyfin.mobile.app
import android.content.Context
import android.content.SharedPreferences
diff --git a/app/src/main/java/org/jellyfin/mobile/bridge/ExternalPlayer.kt b/app/src/main/java/org/jellyfin/mobile/bridge/ExternalPlayer.kt
index 261be9b5..1aa5049b 100644
--- a/app/src/main/java/org/jellyfin/mobile/bridge/ExternalPlayer.kt
+++ b/app/src/main/java/org/jellyfin/mobile/bridge/ExternalPlayer.kt
@@ -12,9 +12,10 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.LifecycleOwner
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
-import org.jellyfin.mobile.AppPreferences
+import org.jellyfin.mobile.app.AppPreferences
import org.jellyfin.mobile.R
import org.jellyfin.mobile.player.PlayerException
+import org.jellyfin.mobile.player.interaction.PlayOptions
import org.jellyfin.mobile.player.source.ExternalSubtitleStream
import org.jellyfin.mobile.player.source.JellyfinMediaSource
import org.jellyfin.mobile.player.source.MediaSourceResolver
diff --git a/app/src/main/java/org/jellyfin/mobile/bridge/NativeInterface.kt b/app/src/main/java/org/jellyfin/mobile/bridge/NativeInterface.kt
index 9a834a40..ea8fd77f 100644
--- a/app/src/main/java/org/jellyfin/mobile/bridge/NativeInterface.kt
+++ b/app/src/main/java/org/jellyfin/mobile/bridge/NativeInterface.kt
@@ -11,7 +11,7 @@ import android.webkit.JavascriptInterface
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import org.jellyfin.mobile.R
-import org.jellyfin.mobile.fragment.WebViewFragment
+import org.jellyfin.mobile.webapp.WebViewFragment
import org.jellyfin.mobile.settings.SettingsFragment
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.mobile.utils.Constants.EXTRA_ALBUM
@@ -25,11 +25,11 @@ import org.jellyfin.mobile.utils.Constants.EXTRA_ITEM_ID
import org.jellyfin.mobile.utils.Constants.EXTRA_PLAYER_ACTION
import org.jellyfin.mobile.utils.Constants.EXTRA_POSITION
import org.jellyfin.mobile.utils.Constants.EXTRA_TITLE
-import org.jellyfin.mobile.utils.addFragment
-import org.jellyfin.mobile.utils.disableFullscreen
-import org.jellyfin.mobile.utils.enableFullscreen
+import org.jellyfin.mobile.utils.extensions.addFragment
+import org.jellyfin.mobile.utils.extensions.disableFullscreen
+import org.jellyfin.mobile.utils.extensions.enableFullscreen
import org.jellyfin.mobile.utils.requestDownload
-import org.jellyfin.mobile.utils.requireMainActivity
+import org.jellyfin.mobile.utils.extensions.requireMainActivity
import org.jellyfin.mobile.utils.runOnUiThread
import org.jellyfin.mobile.webapp.RemotePlayerService
import org.jellyfin.mobile.webapp.RemoteVolumeProvider
diff --git a/app/src/main/java/org/jellyfin/mobile/bridge/NativePlayer.kt b/app/src/main/java/org/jellyfin/mobile/bridge/NativePlayer.kt
index 05206a38..01b0e02c 100644
--- a/app/src/main/java/org/jellyfin/mobile/bridge/NativePlayer.kt
+++ b/app/src/main/java/org/jellyfin/mobile/bridge/NativePlayer.kt
@@ -2,9 +2,10 @@ package org.jellyfin.mobile.bridge
import android.webkit.JavascriptInterface
import kotlinx.coroutines.channels.Channel
-import org.jellyfin.mobile.AppPreferences
-import org.jellyfin.mobile.PLAYER_EVENT_CHANNEL
-import org.jellyfin.mobile.player.PlayerEvent
+import org.jellyfin.mobile.app.AppPreferences
+import org.jellyfin.mobile.app.PLAYER_EVENT_CHANNEL
+import org.jellyfin.mobile.player.interaction.PlayOptions
+import org.jellyfin.mobile.player.interaction.PlayerEvent
import org.jellyfin.mobile.settings.VideoPlayerType
import org.jellyfin.mobile.utils.Constants
import org.json.JSONObject
diff --git a/app/src/main/java/org/jellyfin/mobile/bridge/NativePlayerHost.kt b/app/src/main/java/org/jellyfin/mobile/bridge/NativePlayerHost.kt
index 4e58397d..d111627f 100644
--- a/app/src/main/java/org/jellyfin/mobile/bridge/NativePlayerHost.kt
+++ b/app/src/main/java/org/jellyfin/mobile/bridge/NativePlayerHost.kt
@@ -1,5 +1,7 @@
package org.jellyfin.mobile.bridge
+import org.jellyfin.mobile.player.interaction.PlayOptions
+
interface NativePlayerHost {
fun loadNativePlayer(playOptions: PlayOptions)
}
diff --git a/app/src/main/java/org/jellyfin/mobile/model/DatabaseModule.kt b/app/src/main/java/org/jellyfin/mobile/data/DatabaseModule.kt
similarity index 85%
rename from app/src/main/java/org/jellyfin/mobile/model/DatabaseModule.kt
rename to app/src/main/java/org/jellyfin/mobile/data/DatabaseModule.kt
index 88ae07c2..0b44e3c5 100644
--- a/app/src/main/java/org/jellyfin/mobile/model/DatabaseModule.kt
+++ b/app/src/main/java/org/jellyfin/mobile/data/DatabaseModule.kt
@@ -1,7 +1,6 @@
-package org.jellyfin.mobile.model
+package org.jellyfin.mobile.data
import androidx.room.Room
-import org.jellyfin.mobile.model.sql.JellyfinDatabase
import org.koin.android.ext.koin.androidApplication
import org.koin.dsl.module
diff --git a/app/src/main/java/org/jellyfin/mobile/model/sql/JellyfinDatabase.kt b/app/src/main/java/org/jellyfin/mobile/data/JellyfinDatabase.kt
similarity index 51%
rename from app/src/main/java/org/jellyfin/mobile/model/sql/JellyfinDatabase.kt
rename to app/src/main/java/org/jellyfin/mobile/data/JellyfinDatabase.kt
index 89ca1607..660f777b 100644
--- a/app/src/main/java/org/jellyfin/mobile/model/sql/JellyfinDatabase.kt
+++ b/app/src/main/java/org/jellyfin/mobile/data/JellyfinDatabase.kt
@@ -1,11 +1,11 @@
-package org.jellyfin.mobile.model.sql
+package org.jellyfin.mobile.data
import androidx.room.Database
import androidx.room.RoomDatabase
-import org.jellyfin.mobile.model.sql.dao.ServerDao
-import org.jellyfin.mobile.model.sql.dao.UserDao
-import org.jellyfin.mobile.model.sql.entity.ServerEntity
-import org.jellyfin.mobile.model.sql.entity.UserEntity
+import org.jellyfin.mobile.data.dao.ServerDao
+import org.jellyfin.mobile.data.dao.UserDao
+import org.jellyfin.mobile.data.entity.ServerEntity
+import org.jellyfin.mobile.data.entity.UserEntity
@Database(entities = [ServerEntity::class, UserEntity::class], version = 2)
abstract class JellyfinDatabase : RoomDatabase() {
diff --git a/app/src/main/java/org/jellyfin/mobile/model/sql/dao/ServerDao.kt b/app/src/main/java/org/jellyfin/mobile/data/dao/ServerDao.kt
similarity index 75%
rename from app/src/main/java/org/jellyfin/mobile/model/sql/dao/ServerDao.kt
rename to app/src/main/java/org/jellyfin/mobile/data/dao/ServerDao.kt
index f0528ca9..9d335f38 100644
--- a/app/src/main/java/org/jellyfin/mobile/model/sql/dao/ServerDao.kt
+++ b/app/src/main/java/org/jellyfin/mobile/data/dao/ServerDao.kt
@@ -1,11 +1,11 @@
-package org.jellyfin.mobile.model.sql.dao
+package org.jellyfin.mobile.data.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
-import org.jellyfin.mobile.model.sql.entity.ServerEntity
-import org.jellyfin.mobile.model.sql.entity.ServerEntity.Key.TABLE_NAME
+import org.jellyfin.mobile.data.entity.ServerEntity
+import org.jellyfin.mobile.data.entity.ServerEntity.Key.TABLE_NAME
@Dao
interface ServerDao {
diff --git a/app/src/main/java/org/jellyfin/mobile/model/sql/dao/UserDao.kt b/app/src/main/java/org/jellyfin/mobile/data/dao/UserDao.kt
similarity index 76%
rename from app/src/main/java/org/jellyfin/mobile/model/sql/dao/UserDao.kt
rename to app/src/main/java/org/jellyfin/mobile/data/dao/UserDao.kt
index 8401d66a..f48567d5 100644
--- a/app/src/main/java/org/jellyfin/mobile/model/sql/dao/UserDao.kt
+++ b/app/src/main/java/org/jellyfin/mobile/data/dao/UserDao.kt
@@ -1,17 +1,17 @@
-package org.jellyfin.mobile.model.sql.dao
+package org.jellyfin.mobile.data.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
-import org.jellyfin.mobile.model.sql.entity.ServerUser
-import org.jellyfin.mobile.model.sql.entity.UserEntity
-import org.jellyfin.mobile.model.sql.entity.UserEntity.Key.ACCESS_TOKEN
-import org.jellyfin.mobile.model.sql.entity.UserEntity.Key.ID
-import org.jellyfin.mobile.model.sql.entity.UserEntity.Key.SERVER_ID
-import org.jellyfin.mobile.model.sql.entity.UserEntity.Key.TABLE_NAME
-import org.jellyfin.mobile.model.sql.entity.UserEntity.Key.USER_ID
+import org.jellyfin.mobile.data.entity.ServerUser
+import org.jellyfin.mobile.data.entity.UserEntity
+import org.jellyfin.mobile.data.entity.UserEntity.Key.ACCESS_TOKEN
+import org.jellyfin.mobile.data.entity.UserEntity.Key.ID
+import org.jellyfin.mobile.data.entity.UserEntity.Key.SERVER_ID
+import org.jellyfin.mobile.data.entity.UserEntity.Key.TABLE_NAME
+import org.jellyfin.mobile.data.entity.UserEntity.Key.USER_ID
@Dao
@Suppress("TooManyFunctions")
diff --git a/app/src/main/java/org/jellyfin/mobile/model/sql/entity/ServerEntity.kt b/app/src/main/java/org/jellyfin/mobile/data/entity/ServerEntity.kt
similarity index 81%
rename from app/src/main/java/org/jellyfin/mobile/model/sql/entity/ServerEntity.kt
rename to app/src/main/java/org/jellyfin/mobile/data/entity/ServerEntity.kt
index d9560e20..9521cfd7 100644
--- a/app/src/main/java/org/jellyfin/mobile/model/sql/entity/ServerEntity.kt
+++ b/app/src/main/java/org/jellyfin/mobile/data/entity/ServerEntity.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.model.sql.entity
+package org.jellyfin.mobile.data.entity
import android.os.Parcelable
import androidx.room.ColumnInfo
@@ -6,8 +6,8 @@ import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey
import kotlinx.parcelize.Parcelize
-import org.jellyfin.mobile.model.sql.entity.ServerEntity.Key.HOSTNAME
-import org.jellyfin.mobile.model.sql.entity.ServerEntity.Key.TABLE_NAME
+import org.jellyfin.mobile.data.entity.ServerEntity.Key.HOSTNAME
+import org.jellyfin.mobile.data.entity.ServerEntity.Key.TABLE_NAME
@Parcelize
@Entity(tableName = TABLE_NAME, indices = [Index(value = arrayOf(HOSTNAME), unique = true)])
diff --git a/app/src/main/java/org/jellyfin/mobile/model/sql/entity/ServerUser.kt b/app/src/main/java/org/jellyfin/mobile/data/entity/ServerUser.kt
similarity index 85%
rename from app/src/main/java/org/jellyfin/mobile/model/sql/entity/ServerUser.kt
rename to app/src/main/java/org/jellyfin/mobile/data/entity/ServerUser.kt
index 9aa15af5..b925020f 100644
--- a/app/src/main/java/org/jellyfin/mobile/model/sql/entity/ServerUser.kt
+++ b/app/src/main/java/org/jellyfin/mobile/data/entity/ServerUser.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.model.sql.entity
+package org.jellyfin.mobile.data.entity
import androidx.room.Embedded
import androidx.room.Relation
diff --git a/app/src/main/java/org/jellyfin/mobile/model/sql/entity/UserEntity.kt b/app/src/main/java/org/jellyfin/mobile/data/entity/UserEntity.kt
similarity index 82%
rename from app/src/main/java/org/jellyfin/mobile/model/sql/entity/UserEntity.kt
rename to app/src/main/java/org/jellyfin/mobile/data/entity/UserEntity.kt
index 8178cfc8..65031896 100644
--- a/app/src/main/java/org/jellyfin/mobile/model/sql/entity/UserEntity.kt
+++ b/app/src/main/java/org/jellyfin/mobile/data/entity/UserEntity.kt
@@ -1,13 +1,13 @@
-package org.jellyfin.mobile.model.sql.entity
+package org.jellyfin.mobile.data.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey
-import org.jellyfin.mobile.model.sql.entity.UserEntity.Key.SERVER_ID
-import org.jellyfin.mobile.model.sql.entity.UserEntity.Key.TABLE_NAME
-import org.jellyfin.mobile.model.sql.entity.UserEntity.Key.USER_ID
+import org.jellyfin.mobile.data.entity.UserEntity.Key.SERVER_ID
+import org.jellyfin.mobile.data.entity.UserEntity.Key.TABLE_NAME
+import org.jellyfin.mobile.data.entity.UserEntity.Key.USER_ID
@Entity(
tableName = TABLE_NAME,
diff --git a/app/src/main/java/org/jellyfin/mobile/player/PlayerViewModel.kt b/app/src/main/java/org/jellyfin/mobile/player/PlayerViewModel.kt
index 62d8e162..343c832d 100644
--- a/app/src/main/java/org/jellyfin/mobile/player/PlayerViewModel.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/PlayerViewModel.kt
@@ -28,10 +28,14 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.jellyfin.mobile.BuildConfig
-import org.jellyfin.mobile.PLAYER_EVENT_CHANNEL
-import org.jellyfin.mobile.model.DisplayPreferences
+import org.jellyfin.mobile.app.PLAYER_EVENT_CHANNEL
+import org.jellyfin.mobile.player.ui.DisplayPreferences
+import org.jellyfin.mobile.player.interaction.PlayerEvent
+import org.jellyfin.mobile.player.interaction.PlayerLifecycleObserver
+import org.jellyfin.mobile.player.interaction.PlayerMediaSessionCallback
+import org.jellyfin.mobile.player.interaction.PlayerNotificationHelper
import org.jellyfin.mobile.player.source.JellyfinMediaSource
-import org.jellyfin.mobile.player.source.MediaQueueManager
+import org.jellyfin.mobile.player.queue.QueueManager
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.mobile.utils.Constants.SUPPORTED_VIDEO_PLAYER_PLAYBACK_ACTIONS
import org.jellyfin.mobile.utils.applyDefaultAudioAttributes
@@ -39,11 +43,11 @@ import org.jellyfin.mobile.utils.applyDefaultLocalAudioAttributes
import org.jellyfin.mobile.utils.getVolumeLevelPercent
import org.jellyfin.mobile.utils.getVolumeRange
import org.jellyfin.mobile.utils.logTracks
-import org.jellyfin.mobile.utils.scaleInRange
+import org.jellyfin.mobile.utils.extensions.scaleInRange
import org.jellyfin.mobile.utils.seekToOffset
import org.jellyfin.mobile.utils.setPlaybackState
import org.jellyfin.mobile.utils.toMediaMetadata
-import org.jellyfin.mobile.utils.width
+import org.jellyfin.mobile.utils.extensions.width
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.api.client.exception.ApiClientException
import org.jellyfin.sdk.api.client.extensions.displayPreferencesApi
@@ -75,7 +79,7 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application),
val notificationHelper: PlayerNotificationHelper by lazy { PlayerNotificationHelper(this) }
// Media source handling
- val mediaQueueManager = MediaQueueManager(this)
+ val mediaQueueManager = QueueManager(this)
val mediaSourceOrNull: JellyfinMediaSource?
get() = mediaQueueManager.mediaQueue.value?.jellyfinMediaSource
@@ -188,7 +192,7 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application),
_player.value = null
}
- fun play(queueItem: MediaQueueManager.QueueItem.Loaded) {
+ fun play(queueItem: QueueManager.QueueItem.Loaded) {
val player = playerOrNull ?: return
player.setMediaSource(queueItem.exoMediaSource)
@@ -353,14 +357,14 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application),
}
/**
- * @see MediaQueueManager.selectAudioTrack
+ * @see QueueManager.selectAudioTrack
*/
fun selectAudioTrack(streamIndex: Int): Boolean = mediaQueueManager.selectAudioTrack(streamIndex).also { success ->
if (success) playerOrNull?.logTracks(analyticsCollector)
}
/**
- * @see MediaQueueManager.selectSubtitle
+ * @see QueueManager.selectSubtitle
*/
fun selectSubtitle(streamIndex: Int): Boolean = mediaQueueManager.selectSubtitle(streamIndex).also { success ->
if (success) playerOrNull?.logTracks(analyticsCollector)
diff --git a/app/src/main/java/org/jellyfin/mobile/media/MediaNotificationManager.kt b/app/src/main/java/org/jellyfin/mobile/player/audio/AudioNotificationManager.kt
similarity index 98%
rename from app/src/main/java/org/jellyfin/mobile/media/MediaNotificationManager.kt
rename to app/src/main/java/org/jellyfin/mobile/player/audio/AudioNotificationManager.kt
index 3045e443..22b82a6e 100644
--- a/app/src/main/java/org/jellyfin/mobile/media/MediaNotificationManager.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/audio/AudioNotificationManager.kt
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package org.jellyfin.mobile.media
+package org.jellyfin.mobile.player.audio
import android.app.PendingIntent
import android.content.Context
@@ -45,7 +45,7 @@ import org.koin.core.component.inject
* A wrapper class for ExoPlayer's PlayerNotificationManager. It sets up the notification shown to
* the user during audio playback and provides track metadata, such as track title and icon image.
*/
-class MediaNotificationManager(
+class AudioNotificationManager(
private val context: Context,
sessionToken: MediaSessionCompat.Token,
notificationListener: PlayerNotificationManager.NotificationListener
diff --git a/app/src/main/java/org/jellyfin/mobile/media/MediaService.kt b/app/src/main/java/org/jellyfin/mobile/player/audio/MediaService.kt
similarity index 96%
rename from app/src/main/java/org/jellyfin/mobile/media/MediaService.kt
rename to app/src/main/java/org/jellyfin/mobile/player/audio/MediaService.kt
index bf4be7df..2e031f2a 100644
--- a/app/src/main/java/org/jellyfin/mobile/media/MediaService.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/audio/MediaService.kt
@@ -1,6 +1,6 @@
// Contains code adapted from https://github.com/android/uamp/blob/main/common/src/main/java/com/example/android/uamp/media/MediaService.kt
-package org.jellyfin.mobile.media
+package org.jellyfin.mobile.player.audio
import android.app.Notification
import android.app.PendingIntent
@@ -36,11 +36,12 @@ import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import org.jellyfin.mobile.R
-import org.jellyfin.mobile.cast.CastPlayerProvider
-import org.jellyfin.mobile.cast.ICastPlayerProvider
-import org.jellyfin.mobile.controller.ApiController
-import org.jellyfin.mobile.media.car.LibraryBrowser
-import org.jellyfin.mobile.media.car.LibraryPage
+import org.jellyfin.mobile.player.cast.CastPlayerProvider
+import org.jellyfin.mobile.player.cast.ICastPlayerProvider
+import org.jellyfin.mobile.app.ApiClientController
+import org.jellyfin.mobile.player.audio.car.LibraryBrowser
+import org.jellyfin.mobile.player.audio.car.LibraryPage
+import org.jellyfin.mobile.utils.extensions.mediaUri
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.mobile.utils.toast
import org.jellyfin.sdk.api.client.ApiClient
@@ -51,7 +52,7 @@ import timber.log.Timber
import com.google.android.exoplayer2.MediaItem as ExoPlayerMediaItem
class MediaService : MediaBrowserServiceCompat() {
- private val apiController: ApiController by inject()
+ private val apiClientController: ApiClientController by inject()
private val apiClient: ApiClient by inject()
private val libraryBrowser: LibraryBrowser by inject()
@@ -64,7 +65,7 @@ class MediaService : MediaBrowserServiceCompat() {
// remote playback through a Cast device).
private lateinit var currentPlayer: Player
- private lateinit var notificationManager: MediaNotificationManager
+ private lateinit var notificationManager: AudioNotificationManager
private lateinit var mediaController: MediaControllerCompat
private lateinit var mediaSession: MediaSessionCompat
private lateinit var mediaSessionConnector: MediaSessionConnector
@@ -98,7 +99,7 @@ class MediaService : MediaBrowserServiceCompat() {
super.onCreate()
loadingJob = serviceScope.launch {
- apiController.loadSavedServerUser()
+ apiClientController.loadSavedServerUser()
}
val sessionActivityPendingIntent = packageManager?.getLaunchIntentForPackage(packageName)?.let { sessionIntent ->
@@ -112,7 +113,7 @@ class MediaService : MediaBrowserServiceCompat() {
sessionToken = mediaSession.sessionToken
- notificationManager = MediaNotificationManager(
+ notificationManager = AudioNotificationManager(
this,
mediaSession.sessionToken,
PlayerNotificationListener()
diff --git a/app/src/main/java/org/jellyfin/mobile/media/car/LibraryBrowser.kt b/app/src/main/java/org/jellyfin/mobile/player/audio/car/LibraryBrowser.kt
similarity index 96%
rename from app/src/main/java/org/jellyfin/mobile/media/car/LibraryBrowser.kt
rename to app/src/main/java/org/jellyfin/mobile/player/audio/car/LibraryBrowser.kt
index c9b626fd..497a945b 100644
--- a/app/src/main/java/org/jellyfin/mobile/media/car/LibraryBrowser.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/audio/car/LibraryBrowser.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.media.car
+package org.jellyfin.mobile.player.audio.car
import android.content.Context
import android.net.Uri
@@ -12,17 +12,17 @@ import android.support.v4.media.MediaMetadataCompat
import androidx.media.MediaBrowserServiceCompat
import androidx.media.utils.MediaConstants
import org.jellyfin.mobile.R
-import org.jellyfin.mobile.media.MediaService
-import org.jellyfin.mobile.media.mediaId
-import org.jellyfin.mobile.media.setAlbum
-import org.jellyfin.mobile.media.setAlbumArtUri
-import org.jellyfin.mobile.media.setAlbumArtist
-import org.jellyfin.mobile.media.setArtist
-import org.jellyfin.mobile.media.setDisplayIconUri
-import org.jellyfin.mobile.media.setMediaId
-import org.jellyfin.mobile.media.setMediaUri
-import org.jellyfin.mobile.media.setTitle
-import org.jellyfin.mobile.media.setTrackNumber
+import org.jellyfin.mobile.player.audio.MediaService
+import org.jellyfin.mobile.utils.extensions.mediaId
+import org.jellyfin.mobile.utils.extensions.setAlbum
+import org.jellyfin.mobile.utils.extensions.setAlbumArtUri
+import org.jellyfin.mobile.utils.extensions.setAlbumArtist
+import org.jellyfin.mobile.utils.extensions.setArtist
+import org.jellyfin.mobile.utils.extensions.setDisplayIconUri
+import org.jellyfin.mobile.utils.extensions.setMediaId
+import org.jellyfin.mobile.utils.extensions.setMediaUri
+import org.jellyfin.mobile.utils.extensions.setTitle
+import org.jellyfin.mobile.utils.extensions.setTrackNumber
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.api.client.exception.ApiClientException
import org.jellyfin.sdk.api.client.extensions.genresApi
diff --git a/app/src/main/java/org/jellyfin/mobile/media/car/LibraryPage.kt b/app/src/main/java/org/jellyfin/mobile/player/audio/car/LibraryPage.kt
similarity index 96%
rename from app/src/main/java/org/jellyfin/mobile/media/car/LibraryPage.kt
rename to app/src/main/java/org/jellyfin/mobile/player/audio/car/LibraryPage.kt
index 7d5417dd..99b72837 100644
--- a/app/src/main/java/org/jellyfin/mobile/media/car/LibraryPage.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/audio/car/LibraryPage.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.media.car
+package org.jellyfin.mobile.player.audio.car
object LibraryPage {
/**
diff --git a/app/src/main/java/org/jellyfin/mobile/cast/ICastPlayerProvider.kt b/app/src/main/java/org/jellyfin/mobile/player/cast/ICastPlayerProvider.kt
similarity index 78%
rename from app/src/main/java/org/jellyfin/mobile/cast/ICastPlayerProvider.kt
rename to app/src/main/java/org/jellyfin/mobile/player/cast/ICastPlayerProvider.kt
index 3323ad55..3be6d01f 100644
--- a/app/src/main/java/org/jellyfin/mobile/cast/ICastPlayerProvider.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/cast/ICastPlayerProvider.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.cast
+package org.jellyfin.mobile.player.cast
import com.google.android.exoplayer2.Player
diff --git a/app/src/main/java/org/jellyfin/mobile/cast/IChromecast.kt b/app/src/main/java/org/jellyfin/mobile/player/cast/IChromecast.kt
similarity index 89%
rename from app/src/main/java/org/jellyfin/mobile/cast/IChromecast.kt
rename to app/src/main/java/org/jellyfin/mobile/player/cast/IChromecast.kt
index e2c499ba..35179373 100644
--- a/app/src/main/java/org/jellyfin/mobile/cast/IChromecast.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/cast/IChromecast.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.cast
+package org.jellyfin.mobile.player.cast
import android.app.Activity
import org.jellyfin.mobile.bridge.JavascriptCallback
diff --git a/app/src/main/java/org/jellyfin/mobile/player/CodecHelpers.kt b/app/src/main/java/org/jellyfin/mobile/player/deviceprofile/CodecHelpers.kt
similarity index 99%
rename from app/src/main/java/org/jellyfin/mobile/player/CodecHelpers.kt
rename to app/src/main/java/org/jellyfin/mobile/player/deviceprofile/CodecHelpers.kt
index 907566aa..39bcfe64 100644
--- a/app/src/main/java/org/jellyfin/mobile/player/CodecHelpers.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/deviceprofile/CodecHelpers.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.player
+package org.jellyfin.mobile.player.deviceprofile
import android.media.MediaCodecInfo.CodecProfileLevel
import android.media.MediaFormat
diff --git a/app/src/main/java/org/jellyfin/mobile/player/DeviceCodec.kt b/app/src/main/java/org/jellyfin/mobile/player/deviceprofile/DeviceCodec.kt
similarity index 89%
rename from app/src/main/java/org/jellyfin/mobile/player/DeviceCodec.kt
rename to app/src/main/java/org/jellyfin/mobile/player/deviceprofile/DeviceCodec.kt
index cceb4cb1..44c2525a 100644
--- a/app/src/main/java/org/jellyfin/mobile/player/DeviceCodec.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/deviceprofile/DeviceCodec.kt
@@ -1,12 +1,12 @@
-package org.jellyfin.mobile.player
+package org.jellyfin.mobile.player.deviceprofile
import android.media.MediaCodecInfo.CodecCapabilities
import android.util.Range
-import org.jellyfin.mobile.player.CodecHelpers.getAudioCodec
-import org.jellyfin.mobile.player.CodecHelpers.getAudioProfile
-import org.jellyfin.mobile.player.CodecHelpers.getVideoCodec
-import org.jellyfin.mobile.player.CodecHelpers.getVideoLevel
-import org.jellyfin.mobile.player.CodecHelpers.getVideoProfile
+import org.jellyfin.mobile.player.deviceprofile.CodecHelpers.getAudioCodec
+import org.jellyfin.mobile.player.deviceprofile.CodecHelpers.getAudioProfile
+import org.jellyfin.mobile.player.deviceprofile.CodecHelpers.getVideoCodec
+import org.jellyfin.mobile.player.deviceprofile.CodecHelpers.getVideoLevel
+import org.jellyfin.mobile.player.deviceprofile.CodecHelpers.getVideoProfile
import java.util.*
import kotlin.collections.HashSet
import kotlin.math.max
diff --git a/app/src/main/java/org/jellyfin/mobile/api/DeviceProfileBuilder.kt b/app/src/main/java/org/jellyfin/mobile/player/deviceprofile/DeviceProfileBuilder.kt
similarity index 99%
rename from app/src/main/java/org/jellyfin/mobile/api/DeviceProfileBuilder.kt
rename to app/src/main/java/org/jellyfin/mobile/player/deviceprofile/DeviceProfileBuilder.kt
index 97de8ffd..3b6a1338 100644
--- a/app/src/main/java/org/jellyfin/mobile/api/DeviceProfileBuilder.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/deviceprofile/DeviceProfileBuilder.kt
@@ -1,8 +1,7 @@
-package org.jellyfin.mobile.api
+package org.jellyfin.mobile.player.deviceprofile
import android.media.MediaCodecList
import org.jellyfin.mobile.bridge.ExternalPlayer
-import org.jellyfin.mobile.player.DeviceCodec
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.sdk.model.api.CodecProfile
import org.jellyfin.sdk.model.api.ContainerProfile
diff --git a/app/src/main/java/org/jellyfin/mobile/bridge/PlayOptions.kt b/app/src/main/java/org/jellyfin/mobile/player/interaction/PlayOptions.kt
similarity index 93%
rename from app/src/main/java/org/jellyfin/mobile/bridge/PlayOptions.kt
rename to app/src/main/java/org/jellyfin/mobile/player/interaction/PlayOptions.kt
index 9593df48..26b12423 100644
--- a/app/src/main/java/org/jellyfin/mobile/bridge/PlayOptions.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/interaction/PlayOptions.kt
@@ -1,8 +1,8 @@
-package org.jellyfin.mobile.bridge
+package org.jellyfin.mobile.player.interaction
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
-import org.jellyfin.mobile.utils.size
+import org.jellyfin.mobile.utils.extensions.size
import org.jellyfin.sdk.model.serializer.toUUIDOrNull
import org.json.JSONException
import org.json.JSONObject
diff --git a/app/src/main/java/org/jellyfin/mobile/player/PlayerEvent.kt b/app/src/main/java/org/jellyfin/mobile/player/interaction/PlayerEvent.kt
similarity index 85%
rename from app/src/main/java/org/jellyfin/mobile/player/PlayerEvent.kt
rename to app/src/main/java/org/jellyfin/mobile/player/interaction/PlayerEvent.kt
index 924c470e..4c8ed606 100644
--- a/app/src/main/java/org/jellyfin/mobile/player/PlayerEvent.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/interaction/PlayerEvent.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.player
+package org.jellyfin.mobile.player.interaction
sealed class PlayerEvent {
object Pause : PlayerEvent()
diff --git a/app/src/main/java/org/jellyfin/mobile/player/PlayerLifecycleObserver.kt b/app/src/main/java/org/jellyfin/mobile/player/interaction/PlayerLifecycleObserver.kt
similarity index 82%
rename from app/src/main/java/org/jellyfin/mobile/player/PlayerLifecycleObserver.kt
rename to app/src/main/java/org/jellyfin/mobile/player/interaction/PlayerLifecycleObserver.kt
index ae2ff6dc..200fecab 100644
--- a/app/src/main/java/org/jellyfin/mobile/player/PlayerLifecycleObserver.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/interaction/PlayerLifecycleObserver.kt
@@ -1,7 +1,8 @@
-package org.jellyfin.mobile.player
+package org.jellyfin.mobile.player.interaction
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
+import org.jellyfin.mobile.player.PlayerViewModel
class PlayerLifecycleObserver(private val viewModel: PlayerViewModel) : DefaultLifecycleObserver {
diff --git a/app/src/main/java/org/jellyfin/mobile/player/PlayerMediaSessionCallback.kt b/app/src/main/java/org/jellyfin/mobile/player/interaction/PlayerMediaSessionCallback.kt
similarity index 87%
rename from app/src/main/java/org/jellyfin/mobile/player/PlayerMediaSessionCallback.kt
rename to app/src/main/java/org/jellyfin/mobile/player/interaction/PlayerMediaSessionCallback.kt
index f790b37a..120a2150 100644
--- a/app/src/main/java/org/jellyfin/mobile/player/PlayerMediaSessionCallback.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/interaction/PlayerMediaSessionCallback.kt
@@ -1,6 +1,7 @@
-package org.jellyfin.mobile.player
+package org.jellyfin.mobile.player.interaction
import android.media.session.MediaSession
+import org.jellyfin.mobile.player.PlayerViewModel
class PlayerMediaSessionCallback(private val viewModel: PlayerViewModel) : MediaSession.Callback() {
override fun onPlay() {
diff --git a/app/src/main/java/org/jellyfin/mobile/player/PlayerNotificationHelper.kt b/app/src/main/java/org/jellyfin/mobile/player/interaction/PlayerNotificationHelper.kt
similarity index 98%
rename from app/src/main/java/org/jellyfin/mobile/player/PlayerNotificationHelper.kt
rename to app/src/main/java/org/jellyfin/mobile/player/interaction/PlayerNotificationHelper.kt
index 89d77cb6..9e17dbd5 100644
--- a/app/src/main/java/org/jellyfin/mobile/player/PlayerNotificationHelper.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/interaction/PlayerNotificationHelper.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.player
+package org.jellyfin.mobile.player.interaction
import android.app.Application
import android.app.Notification
@@ -20,10 +20,11 @@ import com.google.android.exoplayer2.Player
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
-import org.jellyfin.mobile.AppPreferences
+import org.jellyfin.mobile.app.AppPreferences
import org.jellyfin.mobile.BuildConfig
import org.jellyfin.mobile.MainActivity
import org.jellyfin.mobile.R
+import org.jellyfin.mobile.player.PlayerViewModel
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.mobile.utils.Constants.VIDEO_PLAYER_NOTIFICATION_ID
import org.jellyfin.mobile.utils.createMediaNotificationChannel
diff --git a/app/src/main/java/org/jellyfin/mobile/player/source/MediaQueueManager.kt b/app/src/main/java/org/jellyfin/mobile/player/queue/QueueManager.kt
similarity index 98%
rename from app/src/main/java/org/jellyfin/mobile/player/source/MediaQueueManager.kt
rename to app/src/main/java/org/jellyfin/mobile/player/queue/QueueManager.kt
index ac425d30..58fb7d14 100644
--- a/app/src/main/java/org/jellyfin/mobile/player/source/MediaQueueManager.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/queue/QueueManager.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.player.source
+package org.jellyfin.mobile.player.queue
import android.app.Application
import android.net.Uri
@@ -13,9 +13,11 @@ import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.source.SingleSampleMediaSource
import com.google.android.exoplayer2.source.hls.HlsMediaSource
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
-import org.jellyfin.mobile.bridge.PlayOptions
+import org.jellyfin.mobile.player.interaction.PlayOptions
import org.jellyfin.mobile.player.PlayerException
import org.jellyfin.mobile.player.PlayerViewModel
+import org.jellyfin.mobile.player.source.JellyfinMediaSource
+import org.jellyfin.mobile.player.source.MediaSourceResolver
import org.jellyfin.mobile.utils.clearSelectionAndDisableRendererByType
import org.jellyfin.mobile.utils.selectTrackByTypeAndGroup
import org.jellyfin.sdk.api.client.ApiClient
@@ -30,7 +32,7 @@ import org.koin.core.component.get
import org.koin.core.component.inject
import java.util.UUID
-class MediaQueueManager(
+class QueueManager(
private val viewModel: PlayerViewModel,
) : KoinComponent {
private val apiClient: ApiClient = get()
diff --git a/app/src/main/java/org/jellyfin/mobile/player/source/JellyfinMediaSource.kt b/app/src/main/java/org/jellyfin/mobile/player/source/JellyfinMediaSource.kt
index 10af580a..7ea9944a 100644
--- a/app/src/main/java/org/jellyfin/mobile/player/source/JellyfinMediaSource.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/source/JellyfinMediaSource.kt
@@ -1,6 +1,6 @@
package org.jellyfin.mobile.player.source
-import org.jellyfin.mobile.player.CodecHelpers
+import org.jellyfin.mobile.player.deviceprofile.CodecHelpers
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.MediaSourceInfo
diff --git a/app/src/main/java/org/jellyfin/mobile/model/DisplayPreferences.kt b/app/src/main/java/org/jellyfin/mobile/player/ui/DisplayPreferences.kt
similarity index 84%
rename from app/src/main/java/org/jellyfin/mobile/model/DisplayPreferences.kt
rename to app/src/main/java/org/jellyfin/mobile/player/ui/DisplayPreferences.kt
index 616cef55..9fe8027a 100644
--- a/app/src/main/java/org/jellyfin/mobile/model/DisplayPreferences.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/ui/DisplayPreferences.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.model
+package org.jellyfin.mobile.player.ui
import org.jellyfin.mobile.utils.Constants
diff --git a/app/src/main/java/org/jellyfin/mobile/player/PlayerFragment.kt b/app/src/main/java/org/jellyfin/mobile/player/ui/PlayerFragment.kt
similarity index 94%
rename from app/src/main/java/org/jellyfin/mobile/player/PlayerFragment.kt
rename to app/src/main/java/org/jellyfin/mobile/player/ui/PlayerFragment.kt
index 4ea8536f..be057dcf 100644
--- a/app/src/main/java/org/jellyfin/mobile/player/PlayerFragment.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/ui/PlayerFragment.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.player
+package org.jellyfin.mobile.player.ui
import android.app.Activity
import android.app.PictureInPictureParams
@@ -28,20 +28,22 @@ import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.ui.PlayerView
import kotlinx.coroutines.launch
import org.jellyfin.mobile.R
-import org.jellyfin.mobile.api.aspectRational
-import org.jellyfin.mobile.api.isLandscape
-import org.jellyfin.mobile.bridge.PlayOptions
+import org.jellyfin.mobile.utils.extensions.aspectRational
+import org.jellyfin.mobile.utils.extensions.isLandscape
+import org.jellyfin.mobile.player.interaction.PlayOptions
import org.jellyfin.mobile.databinding.ExoPlayerControlViewBinding
import org.jellyfin.mobile.databinding.FragmentPlayerBinding
+import org.jellyfin.mobile.player.PlayerException
+import org.jellyfin.mobile.player.PlayerViewModel
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.mobile.utils.Constants.DEFAULT_CONTROLS_TIMEOUT_MS
import org.jellyfin.mobile.utils.Constants.PIP_MAX_RATIONAL
import org.jellyfin.mobile.utils.Constants.PIP_MIN_RATIONAL
import org.jellyfin.mobile.utils.SmartOrientationListener
import org.jellyfin.mobile.utils.brightness
-import org.jellyfin.mobile.utils.disableFullscreen
-import org.jellyfin.mobile.utils.enableFullscreen
-import org.jellyfin.mobile.utils.isFullscreen
+import org.jellyfin.mobile.utils.extensions.disableFullscreen
+import org.jellyfin.mobile.utils.extensions.enableFullscreen
+import org.jellyfin.mobile.utils.extensions.isFullscreen
import org.jellyfin.mobile.utils.toast
import org.jellyfin.sdk.model.api.MediaStream
@@ -57,7 +59,7 @@ class PlayerFragment : Fragment() {
private val playerControlsView: View get() = playerControlsBinding.root
private val titleTextView: TextView get() = playerControlsBinding.trackTitle
private val fullscreenSwitcher: ImageButton get() = playerControlsBinding.fullscreenSwitcher
- private var playbackMenus: PlaybackMenus? = null
+ private var playerMenus: PlayerMenus? = null
lateinit var playerLockScreenHelper: PlayerLockScreenHelper
lateinit var playerGestureHelper: PlayerGestureHelper
@@ -108,7 +110,7 @@ class PlayerFragment : Fragment() {
// Update title and player menus
titleTextView.text = jellyfinMediaSource.name
- playbackMenus?.onQueueItemChanged(queueItem)
+ playerMenus?.onQueueItemChanged(queueItem)
}
// Handle fragment arguments, extract playback options and start playback
@@ -156,7 +158,7 @@ class PlayerFragment : Fragment() {
}
// Create playback menus
- playbackMenus = PlaybackMenus(this, playerBinding, playerControlsBinding)
+ playerMenus = PlayerMenus(this, playerBinding, playerControlsBinding)
// Set controller timeout
suppressControllerAutoHide(false)
@@ -318,7 +320,7 @@ class PlayerFragment : Fragment() {
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
playerView.useController = !isInPictureInPictureMode
if (isInPictureInPictureMode) {
- playbackMenus?.dismissPlaybackInfo()
+ playerMenus?.dismissPlaybackInfo()
playerLockScreenHelper.hideUnlockButton()
}
}
@@ -344,7 +346,7 @@ class PlayerFragment : Fragment() {
// Set binding references to null
_playerBinding = null
_playerControlsBinding = null
- playbackMenus = null
+ playerMenus = null
}
override fun onDestroy() {
diff --git a/app/src/main/java/org/jellyfin/mobile/player/PlayerGestureHelper.kt b/app/src/main/java/org/jellyfin/mobile/player/ui/PlayerGestureHelper.kt
similarity index 99%
rename from app/src/main/java/org/jellyfin/mobile/player/PlayerGestureHelper.kt
rename to app/src/main/java/org/jellyfin/mobile/player/ui/PlayerGestureHelper.kt
index fce94194..8ef9aa25 100644
--- a/app/src/main/java/org/jellyfin/mobile/player/PlayerGestureHelper.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/ui/PlayerGestureHelper.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.player
+package org.jellyfin.mobile.player.ui
import android.content.res.Configuration
import android.media.AudioManager
@@ -16,7 +16,7 @@ import androidx.core.view.isVisible
import androidx.core.view.postDelayed
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout
import com.google.android.exoplayer2.ui.PlayerView
-import org.jellyfin.mobile.AppPreferences
+import org.jellyfin.mobile.app.AppPreferences
import org.jellyfin.mobile.databinding.FragmentPlayerBinding
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.mobile.utils.brightness
diff --git a/app/src/main/java/org/jellyfin/mobile/player/PlayerLockScreenHelper.kt b/app/src/main/java/org/jellyfin/mobile/player/ui/PlayerLockScreenHelper.kt
similarity index 95%
rename from app/src/main/java/org/jellyfin/mobile/player/PlayerLockScreenHelper.kt
rename to app/src/main/java/org/jellyfin/mobile/player/ui/PlayerLockScreenHelper.kt
index d7d82033..85a79fae 100644
--- a/app/src/main/java/org/jellyfin/mobile/player/PlayerLockScreenHelper.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/ui/PlayerLockScreenHelper.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.player
+package org.jellyfin.mobile.player.ui
import android.content.pm.ActivityInfo
import android.os.Build
@@ -9,7 +9,7 @@ import com.google.android.exoplayer2.ui.PlayerView
import org.jellyfin.mobile.databinding.FragmentPlayerBinding
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.mobile.utils.isAutoRotateOn
-import org.jellyfin.mobile.utils.lockOrientation
+import org.jellyfin.mobile.utils.extensions.lockOrientation
class PlayerLockScreenHelper(
private val playerFragment: PlayerFragment,
diff --git a/app/src/main/java/org/jellyfin/mobile/player/PlaybackMenus.kt b/app/src/main/java/org/jellyfin/mobile/player/ui/PlayerMenus.kt
similarity index 96%
rename from app/src/main/java/org/jellyfin/mobile/player/PlaybackMenus.kt
rename to app/src/main/java/org/jellyfin/mobile/player/ui/PlayerMenus.kt
index 3b31f565..36888e9b 100644
--- a/app/src/main/java/org/jellyfin/mobile/player/PlaybackMenus.kt
+++ b/app/src/main/java/org/jellyfin/mobile/player/ui/PlayerMenus.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.player
+package org.jellyfin.mobile.player.ui
import android.view.Menu
import android.view.MenuItem
@@ -12,14 +12,14 @@ import androidx.core.view.isVisible
import org.jellyfin.mobile.R
import org.jellyfin.mobile.databinding.ExoPlayerControlViewBinding
import org.jellyfin.mobile.databinding.FragmentPlayerBinding
-import org.jellyfin.mobile.player.source.MediaQueueManager
+import org.jellyfin.mobile.player.queue.QueueManager
import org.jellyfin.sdk.model.api.MediaStream
import java.util.Locale
/**
* Provides a menu UI for audio, subtitle and video stream selection
*/
-class PlaybackMenus(
+class PlayerMenus(
private val fragment: PlayerFragment,
private val playerBinding: FragmentPlayerBinding,
private val playerControlsBinding: ExoPlayerControlViewBinding
@@ -79,7 +79,7 @@ class PlaybackMenus(
}
}
- fun onQueueItemChanged(queueItem: MediaQueueManager.QueueItem.Loaded) {
+ fun onQueueItemChanged(queueItem: QueueManager.QueueItem.Loaded) {
nextButton.isEnabled = queueItem.hasNext()
val mediaSource = queueItem.jellyfinMediaSource
@@ -152,7 +152,7 @@ class PlaybackMenus(
}
}
}
- setOnDismissListener(this@PlaybackMenus)
+ setOnDismissListener(this@PlayerMenus)
}
private fun createAudioStreamsMenu() = PopupMenu(context, audioStreamsButton).apply {
@@ -167,7 +167,7 @@ class PlaybackMenus(
}
}
}
- setOnDismissListener(this@PlaybackMenus)
+ setOnDismissListener(this@PlayerMenus)
}
private fun createSpeedMenu() = PopupMenu(context, speedButton).apply {
@@ -186,7 +186,7 @@ class PlaybackMenus(
}
}
}
- setOnDismissListener(this@PlaybackMenus)
+ setOnDismissListener(this@PlayerMenus)
}
private fun buildMenuItems(menu: Menu, groupId: Int, mediaStreams: List, selectedStream: MediaStream?, showNone: Boolean = false) {
diff --git a/app/src/main/java/org/jellyfin/mobile/settings/SettingsFragment.kt b/app/src/main/java/org/jellyfin/mobile/settings/SettingsFragment.kt
index cae79cc8..908aa4cd 100644
--- a/app/src/main/java/org/jellyfin/mobile/settings/SettingsFragment.kt
+++ b/app/src/main/java/org/jellyfin/mobile/settings/SettingsFragment.kt
@@ -16,14 +16,14 @@ import de.Maxr1998.modernpreferences.helpers.screen
import de.Maxr1998.modernpreferences.helpers.singleChoice
import de.Maxr1998.modernpreferences.preferences.CheckBoxPreference
import de.Maxr1998.modernpreferences.preferences.choice.SelectionItem
-import org.jellyfin.mobile.AppPreferences
+import org.jellyfin.mobile.app.AppPreferences
import org.jellyfin.mobile.R
import org.jellyfin.mobile.databinding.FragmentSettingsBinding
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.mobile.utils.applyWindowInsetsAsMargins
import org.jellyfin.mobile.utils.getDownloadsPaths
import org.jellyfin.mobile.utils.isPackageInstalled
-import org.jellyfin.mobile.utils.requireMainActivity
+import org.jellyfin.mobile.utils.extensions.requireMainActivity
import org.jellyfin.mobile.utils.withThemedContext
import org.koin.android.ext.android.inject
diff --git a/app/src/main/java/org/jellyfin/mobile/fragment/ConnectFragment.kt b/app/src/main/java/org/jellyfin/mobile/setup/ConnectFragment.kt
similarity index 97%
rename from app/src/main/java/org/jellyfin/mobile/fragment/ConnectFragment.kt
rename to app/src/main/java/org/jellyfin/mobile/setup/ConnectFragment.kt
index 23ca5aba..d44a38a5 100644
--- a/app/src/main/java/org/jellyfin/mobile/fragment/ConnectFragment.kt
+++ b/app/src/main/java/org/jellyfin/mobile/setup/ConnectFragment.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.fragment
+package org.jellyfin.mobile.setup
import android.app.AlertDialog
import android.os.Bundle
@@ -23,11 +23,11 @@ import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
import org.jellyfin.mobile.R
-import org.jellyfin.mobile.controller.ApiController
+import org.jellyfin.mobile.app.ApiClientController
import org.jellyfin.mobile.databinding.FragmentConnectBinding
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.mobile.utils.applyWindowInsetsAsMargins
-import org.jellyfin.mobile.viewmodel.MainViewModel
+import org.jellyfin.mobile.MainViewModel
import org.jellyfin.sdk.Jellyfin
import org.jellyfin.sdk.discovery.LocalServerDiscovery
import org.jellyfin.sdk.discovery.RecommendedServerInfo
@@ -40,7 +40,7 @@ import timber.log.Timber
class ConnectFragment : Fragment() {
private val mainViewModel: MainViewModel by sharedViewModel()
private val jellyfin: Jellyfin by inject()
- private val apiController: ApiController by inject()
+ private val apiClientController: ApiClientController by inject()
// UI
private var _connectServerBinding: FragmentConnectBinding? = null
@@ -118,7 +118,7 @@ class ConnectFragment : Fragment() {
val httpUrl = checkServerUrlAndConnection(enteredUrl)
if (httpUrl != null) {
serverList.clear()
- apiController.setupServer(httpUrl)
+ apiClientController.setupServer(httpUrl)
mainViewModel.refreshServer()
}
hostInput.isEnabled = true
diff --git a/app/src/main/java/org/jellyfin/mobile/utils/MediaExtensions.kt b/app/src/main/java/org/jellyfin/mobile/utils/MediaExtensions.kt
index 7ccd1cc7..4b4918f7 100644
--- a/app/src/main/java/org/jellyfin/mobile/utils/MediaExtensions.kt
+++ b/app/src/main/java/org/jellyfin/mobile/utils/MediaExtensions.kt
@@ -13,6 +13,7 @@ import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.analytics.AnalyticsCollector
import org.jellyfin.mobile.player.source.JellyfinMediaSource
+import org.jellyfin.mobile.utils.extensions.width
import com.google.android.exoplayer2.audio.AudioAttributes as ExoPlayerAudioAttributes
inline fun MediaSession.applyDefaultLocalAudioAttributes(contentType: Int) {
diff --git a/app/src/main/java/org/jellyfin/mobile/utils/SystemUtils.kt b/app/src/main/java/org/jellyfin/mobile/utils/SystemUtils.kt
index c4c6d095..b65a59be 100644
--- a/app/src/main/java/org/jellyfin/mobile/utils/SystemUtils.kt
+++ b/app/src/main/java/org/jellyfin/mobile/utils/SystemUtils.kt
@@ -24,10 +24,10 @@ import androidx.core.content.getSystemService
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeout
-import org.jellyfin.mobile.AppPreferences
+import org.jellyfin.mobile.app.AppPreferences
import org.jellyfin.mobile.BuildConfig
import org.jellyfin.mobile.R
-import org.jellyfin.mobile.fragment.WebViewFragment
+import org.jellyfin.mobile.webapp.WebViewFragment
import org.jellyfin.mobile.settings.ExternalPlayerPackage
import org.koin.android.ext.android.get
import timber.log.Timber
diff --git a/app/src/main/java/org/jellyfin/mobile/utils/ActivityExtensions.kt b/app/src/main/java/org/jellyfin/mobile/utils/extensions/Activity.kt
similarity index 97%
rename from app/src/main/java/org/jellyfin/mobile/utils/ActivityExtensions.kt
rename to app/src/main/java/org/jellyfin/mobile/utils/extensions/Activity.kt
index 27e53fa5..e88c752a 100644
--- a/app/src/main/java/org/jellyfin/mobile/utils/ActivityExtensions.kt
+++ b/app/src/main/java/org/jellyfin/mobile/utils/extensions/Activity.kt
@@ -1,6 +1,6 @@
@file:Suppress("DEPRECATION")
-package org.jellyfin.mobile.utils
+package org.jellyfin.mobile.utils.extensions
import android.app.Activity
import android.content.pm.ActivityInfo
diff --git a/app/src/main/java/org/jellyfin/mobile/utils/extensions/Fragment.kt b/app/src/main/java/org/jellyfin/mobile/utils/extensions/Fragment.kt
new file mode 100644
index 00000000..2c3eb46e
--- /dev/null
+++ b/app/src/main/java/org/jellyfin/mobile/utils/extensions/Fragment.kt
@@ -0,0 +1,8 @@
+@file:Suppress("NOTHING_TO_INLINE")
+
+package org.jellyfin.mobile.utils.extensions
+
+import androidx.fragment.app.Fragment
+import org.jellyfin.mobile.MainActivity
+
+inline fun Fragment.requireMainActivity(): MainActivity = requireActivity() as MainActivity
diff --git a/app/src/main/java/org/jellyfin/mobile/utils/FragmentExtensions.kt b/app/src/main/java/org/jellyfin/mobile/utils/extensions/FragmentManager.kt
similarity index 78%
rename from app/src/main/java/org/jellyfin/mobile/utils/FragmentExtensions.kt
rename to app/src/main/java/org/jellyfin/mobile/utils/extensions/FragmentManager.kt
index 8364d354..22be9e8b 100644
--- a/app/src/main/java/org/jellyfin/mobile/utils/FragmentExtensions.kt
+++ b/app/src/main/java/org/jellyfin/mobile/utils/extensions/FragmentManager.kt
@@ -1,13 +1,12 @@
@file:Suppress("NOTHING_TO_INLINE")
-package org.jellyfin.mobile.utils
+package org.jellyfin.mobile.utils.extensions
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.add
import androidx.fragment.app.replace
-import org.jellyfin.mobile.MainActivity
import org.jellyfin.mobile.R
inline fun FragmentManager.addFragment() {
@@ -20,5 +19,3 @@ inline fun FragmentManager.addFragment() {
inline fun FragmentManager.replaceFragment(args: Bundle? = null) {
beginTransaction().replace(R.id.fragment_container, args = args).commit()
}
-
-inline fun Fragment.requireMainActivity(): MainActivity = requireActivity() as MainActivity
diff --git a/app/src/main/java/org/jellyfin/mobile/utils/StdlibExtensions.kt b/app/src/main/java/org/jellyfin/mobile/utils/extensions/Int.kt
similarity index 55%
rename from app/src/main/java/org/jellyfin/mobile/utils/StdlibExtensions.kt
rename to app/src/main/java/org/jellyfin/mobile/utils/extensions/Int.kt
index 1cfb15ac..e602db7b 100644
--- a/app/src/main/java/org/jellyfin/mobile/utils/StdlibExtensions.kt
+++ b/app/src/main/java/org/jellyfin/mobile/utils/extensions/Int.kt
@@ -1,6 +1,6 @@
@file:Suppress("NOTHING_TO_INLINE")
-package org.jellyfin.mobile.utils
+package org.jellyfin.mobile.utils.extensions
import androidx.annotation.CheckResult
@@ -12,12 +12,3 @@ inline fun Int.withFlag(flag: Int) = this or flag
@CheckResult
inline fun Int.withoutFlag(flag: Int) = this and flag.inv()
-
-@get:CheckResult
-val IntRange.width: Int
- get() = endInclusive - start
-
-@CheckResult
-fun IntRange.scaleInRange(percent: Int): Int {
- return start + width * percent / Constants.PERCENT_MAX
-}
diff --git a/app/src/main/java/org/jellyfin/mobile/utils/extensions/IntRange.kt b/app/src/main/java/org/jellyfin/mobile/utils/extensions/IntRange.kt
new file mode 100644
index 00000000..daf5c485
--- /dev/null
+++ b/app/src/main/java/org/jellyfin/mobile/utils/extensions/IntRange.kt
@@ -0,0 +1,15 @@
+@file:Suppress("NOTHING_TO_INLINE")
+
+package org.jellyfin.mobile.utils.extensions
+
+import androidx.annotation.CheckResult
+import org.jellyfin.mobile.utils.Constants
+
+@get:CheckResult
+val IntRange.width: Int
+ get() = endInclusive - start
+
+@CheckResult
+fun IntRange.scaleInRange(percent: Int): Int {
+ return start + width * percent / Constants.PERCENT_MAX
+}
diff --git a/app/src/main/java/org/jellyfin/mobile/utils/JSONExtensions.kt b/app/src/main/java/org/jellyfin/mobile/utils/extensions/JSONArray.kt
similarity index 60%
rename from app/src/main/java/org/jellyfin/mobile/utils/JSONExtensions.kt
rename to app/src/main/java/org/jellyfin/mobile/utils/extensions/JSONArray.kt
index 81a0ca15..ce6b01a8 100644
--- a/app/src/main/java/org/jellyfin/mobile/utils/JSONExtensions.kt
+++ b/app/src/main/java/org/jellyfin/mobile/utils/extensions/JSONArray.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.utils
+package org.jellyfin.mobile.utils.extensions
import org.json.JSONArray
diff --git a/app/src/main/java/org/jellyfin/mobile/media/MediaExtensions.kt b/app/src/main/java/org/jellyfin/mobile/utils/extensions/MediaMetadataCompat.kt
similarity index 98%
rename from app/src/main/java/org/jellyfin/mobile/media/MediaExtensions.kt
rename to app/src/main/java/org/jellyfin/mobile/utils/extensions/MediaMetadataCompat.kt
index 23397826..7e43eafb 100644
--- a/app/src/main/java/org/jellyfin/mobile/media/MediaExtensions.kt
+++ b/app/src/main/java/org/jellyfin/mobile/utils/extensions/MediaMetadataCompat.kt
@@ -1,15 +1,12 @@
@file:Suppress("NOTHING_TO_INLINE")
-package org.jellyfin.mobile.media
+package org.jellyfin.mobile.utils.extensions
import android.graphics.Bitmap
import android.net.Uri
import android.support.v4.media.MediaMetadataCompat
import androidx.core.net.toUri
-/**
- * Useful extensions for [MediaMetadataCompat].
- */
inline val MediaMetadataCompat.mediaId: String?
get() = getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID)
diff --git a/app/src/main/java/org/jellyfin/mobile/api/Extensions.kt b/app/src/main/java/org/jellyfin/mobile/utils/extensions/MediaStream.kt
similarity index 87%
rename from app/src/main/java/org/jellyfin/mobile/api/Extensions.kt
rename to app/src/main/java/org/jellyfin/mobile/utils/extensions/MediaStream.kt
index e3c72374..ca71bedd 100644
--- a/app/src/main/java/org/jellyfin/mobile/api/Extensions.kt
+++ b/app/src/main/java/org/jellyfin/mobile/utils/extensions/MediaStream.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.api
+package org.jellyfin.mobile.utils.extensions
import android.util.Rational
import org.jellyfin.sdk.model.api.MediaStream
diff --git a/app/src/main/java/org/jellyfin/mobile/webapp/RemotePlayerService.kt b/app/src/main/java/org/jellyfin/mobile/webapp/RemotePlayerService.kt
index 04684c84..167f050a 100644
--- a/app/src/main/java/org/jellyfin/mobile/webapp/RemotePlayerService.kt
+++ b/app/src/main/java/org/jellyfin/mobile/webapp/RemotePlayerService.kt
@@ -31,7 +31,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
-import org.jellyfin.mobile.AppPreferences
+import org.jellyfin.mobile.app.AppPreferences
import org.jellyfin.mobile.MainActivity
import org.jellyfin.mobile.R
import org.jellyfin.mobile.utils.Constants
diff --git a/app/src/main/java/org/jellyfin/mobile/fragment/WebViewFragment.kt b/app/src/main/java/org/jellyfin/mobile/webapp/WebViewFragment.kt
similarity index 96%
rename from app/src/main/java/org/jellyfin/mobile/fragment/WebViewFragment.kt
rename to app/src/main/java/org/jellyfin/mobile/webapp/WebViewFragment.kt
index 78d22560..b318ae78 100644
--- a/app/src/main/java/org/jellyfin/mobile/fragment/WebViewFragment.kt
+++ b/app/src/main/java/org/jellyfin/mobile/webapp/WebViewFragment.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.fragment
+package org.jellyfin.mobile.webapp
import android.content.Intent
import android.graphics.Rect
@@ -36,20 +36,21 @@ import androidx.webkit.WebViewCompat
import androidx.webkit.WebViewFeature
import io.ktor.http.HttpStatusCode
import kotlinx.coroutines.launch
-import org.jellyfin.mobile.AppPreferences
+import org.jellyfin.mobile.app.AppPreferences
import org.jellyfin.mobile.R
import org.jellyfin.mobile.bridge.ExternalPlayer
import org.jellyfin.mobile.bridge.NativeInterface
import org.jellyfin.mobile.bridge.NativePlayer
import org.jellyfin.mobile.bridge.NativePlayerHost
-import org.jellyfin.mobile.bridge.PlayOptions
-import org.jellyfin.mobile.controller.ApiController
+import org.jellyfin.mobile.player.interaction.PlayOptions
+import org.jellyfin.mobile.app.ApiClientController
import org.jellyfin.mobile.databinding.FragmentWebviewBinding
-import org.jellyfin.mobile.model.sql.entity.ServerEntity
-import org.jellyfin.mobile.player.PlayerFragment
+import org.jellyfin.mobile.setup.ConnectFragment
+import org.jellyfin.mobile.data.entity.ServerEntity
+import org.jellyfin.mobile.player.ui.PlayerFragment
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.mobile.utils.Constants.FRAGMENT_WEB_VIEW_EXTRA_SERVER
-import org.jellyfin.mobile.utils.addFragment
+import org.jellyfin.mobile.utils.extensions.addFragment
import org.jellyfin.mobile.utils.applyDefault
import org.jellyfin.mobile.utils.applyWindowInsetsAsMargins
import org.jellyfin.mobile.utils.dip
@@ -57,10 +58,9 @@ import org.jellyfin.mobile.utils.fadeIn
import org.jellyfin.mobile.utils.initLocale
import org.jellyfin.mobile.utils.inject
import org.jellyfin.mobile.utils.isOutdated
-import org.jellyfin.mobile.utils.replaceFragment
+import org.jellyfin.mobile.utils.extensions.replaceFragment
import org.jellyfin.mobile.utils.requestNoBatteryOptimizations
import org.jellyfin.mobile.utils.runOnUiThread
-import org.jellyfin.mobile.webapp.WebappFunctionChannel
import org.json.JSONException
import org.json.JSONObject
import org.koin.android.ext.android.inject
@@ -73,7 +73,7 @@ import kotlin.coroutines.suspendCoroutine
class WebViewFragment : Fragment(), NativePlayerHost {
val appPreferences: AppPreferences by inject()
- private val apiController: ApiController by inject()
+ private val apiClientController: ApiClientController by inject()
private val webappFunctionChannel: WebappFunctionChannel by inject()
private lateinit var assetsPathHandler: AssetsPathHandler
private lateinit var externalPlayer: ExternalPlayer
@@ -194,7 +194,7 @@ class WebViewFragment : Fragment(), NativePlayerHost {
val storedServer = credentials.getJSONArray("Servers").getJSONObject(0)
val user = storedServer.getString("UserId")
val token = storedServer.getString("AccessToken")
- apiController.setupUser(server.id, user, token)
+ apiClientController.setupUser(server.id, user, token)
webView.initLocale(user)
}
null
diff --git a/app/src/proprietary/java/org/jellyfin/mobile/cast/CastOptionsProvider.kt b/app/src/proprietary/java/org/jellyfin/mobile/player/cast/CastOptionsProvider.kt
similarity index 95%
rename from app/src/proprietary/java/org/jellyfin/mobile/cast/CastOptionsProvider.kt
rename to app/src/proprietary/java/org/jellyfin/mobile/player/cast/CastOptionsProvider.kt
index 4fe633e5..461836bb 100644
--- a/app/src/proprietary/java/org/jellyfin/mobile/cast/CastOptionsProvider.kt
+++ b/app/src/proprietary/java/org/jellyfin/mobile/player/cast/CastOptionsProvider.kt
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.cast
+package org.jellyfin.mobile.player.cast
import android.content.Context
import com.google.android.gms.cast.framework.CastOptions
diff --git a/app/src/proprietary/java/org/jellyfin/mobile/cast/CastPlayerProvider.kt b/app/src/proprietary/java/org/jellyfin/mobile/player/cast/CastPlayerProvider.kt
similarity index 91%
rename from app/src/proprietary/java/org/jellyfin/mobile/cast/CastPlayerProvider.kt
rename to app/src/proprietary/java/org/jellyfin/mobile/player/cast/CastPlayerProvider.kt
index c86236ef..ca0df00c 100644
--- a/app/src/proprietary/java/org/jellyfin/mobile/cast/CastPlayerProvider.kt
+++ b/app/src/proprietary/java/org/jellyfin/mobile/player/cast/CastPlayerProvider.kt
@@ -1,10 +1,10 @@
-package org.jellyfin.mobile.cast
+package org.jellyfin.mobile.player.cast
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.ext.cast.CastPlayer
import com.google.android.exoplayer2.ext.cast.SessionAvailabilityListener
import com.google.android.gms.cast.framework.CastContext
-import org.jellyfin.mobile.media.MediaService
+import org.jellyfin.mobile.player.audio.MediaService
class CastPlayerProvider(private val mediaService: MediaService) : ICastPlayerProvider, SessionAvailabilityListener {
private val castPlayer: CastPlayer? = try {
diff --git a/app/src/proprietary/java/org/jellyfin/mobile/cast/Chromecast.java b/app/src/proprietary/java/org/jellyfin/mobile/player/cast/Chromecast.java
similarity index 99%
rename from app/src/proprietary/java/org/jellyfin/mobile/cast/Chromecast.java
rename to app/src/proprietary/java/org/jellyfin/mobile/player/cast/Chromecast.java
index 1b405dd3..1966c03b 100644
--- a/app/src/proprietary/java/org/jellyfin/mobile/cast/Chromecast.java
+++ b/app/src/proprietary/java/org/jellyfin/mobile/player/cast/Chromecast.java
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.cast;
+package org.jellyfin.mobile.player.cast;
import android.app.Activity;
diff --git a/app/src/proprietary/java/org/jellyfin/mobile/cast/ChromecastConnection.java b/app/src/proprietary/java/org/jellyfin/mobile/player/cast/ChromecastConnection.java
similarity index 99%
rename from app/src/proprietary/java/org/jellyfin/mobile/cast/ChromecastConnection.java
rename to app/src/proprietary/java/org/jellyfin/mobile/player/cast/ChromecastConnection.java
index 6ccbcaf7..aaaa57d6 100644
--- a/app/src/proprietary/java/org/jellyfin/mobile/cast/ChromecastConnection.java
+++ b/app/src/proprietary/java/org/jellyfin/mobile/player/cast/ChromecastConnection.java
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.cast;
+package org.jellyfin.mobile.player.cast;
import android.app.Activity;
import android.app.AlertDialog;
@@ -24,6 +24,7 @@ import com.google.android.gms.cast.framework.SessionManagerListener;
import org.jellyfin.mobile.R;
import org.jellyfin.mobile.bridge.JavascriptCallback;
+import org.jellyfin.mobile.player.cast.CastOptionsProvider;
import org.json.JSONObject;
import java.util.ArrayList;
diff --git a/app/src/proprietary/java/org/jellyfin/mobile/cast/ChromecastSession.java b/app/src/proprietary/java/org/jellyfin/mobile/player/cast/ChromecastSession.java
similarity index 99%
rename from app/src/proprietary/java/org/jellyfin/mobile/cast/ChromecastSession.java
rename to app/src/proprietary/java/org/jellyfin/mobile/player/cast/ChromecastSession.java
index aedfd78e..93d00d15 100644
--- a/app/src/proprietary/java/org/jellyfin/mobile/cast/ChromecastSession.java
+++ b/app/src/proprietary/java/org/jellyfin/mobile/player/cast/ChromecastSession.java
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.cast;
+package org.jellyfin.mobile.player.cast;
import android.app.Activity;
diff --git a/app/src/proprietary/java/org/jellyfin/mobile/cast/ChromecastUtilities.java b/app/src/proprietary/java/org/jellyfin/mobile/player/cast/ChromecastUtilities.java
similarity index 99%
rename from app/src/proprietary/java/org/jellyfin/mobile/cast/ChromecastUtilities.java
rename to app/src/proprietary/java/org/jellyfin/mobile/player/cast/ChromecastUtilities.java
index 171c0e1c..bbdf8a21 100644
--- a/app/src/proprietary/java/org/jellyfin/mobile/cast/ChromecastUtilities.java
+++ b/app/src/proprietary/java/org/jellyfin/mobile/player/cast/ChromecastUtilities.java
@@ -1,4 +1,4 @@
-package org.jellyfin.mobile.cast;
+package org.jellyfin.mobile.player.cast;
import android.annotation.SuppressLint;
import android.graphics.Color;