diff --git a/.idea/appInsightsSettings.xml b/.idea/appInsightsSettings.xml
new file mode 100644
index 0000000..371f2e2
--- /dev/null
+++ b/.idea/appInsightsSettings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml
index 2364733..d66adbb 100644
--- a/.idea/assetWizardSettings.xml
+++ b/.idea/assetWizardSettings.xml
@@ -328,7 +328,7 @@
@@ -338,8 +338,8 @@
diff --git a/.idea/caches/deviceStreaming.xml b/.idea/caches/deviceStreaming.xml
new file mode 100644
index 0000000..406736c
--- /dev/null
+++ b/.idea/caches/deviceStreaming.xml
@@ -0,0 +1,340 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index b589d56..b86273d 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 0000000..93fe930
--- /dev/null
+++ b/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..0aa8c98
--- /dev/null
+++ b/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 0897082..7b3006b 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -4,6 +4,7 @@
+
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..0987750
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index fdf8d99..bb44937 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 8978d23..b2c751a 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/.idea/navEditor.xml b/.idea/navEditor.xml
index 6283eaa..461d98b 100644
--- a/.idea/navEditor.xml
+++ b/.idea/navEditor.xml
@@ -323,6 +323,75 @@
+
+
+
+
+
+
+
+
+
@@ -384,6 +453,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -517,11 +598,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index bd0a9c1..bcc6c0a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,7 +2,6 @@ plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-android'
- id 'kotlin-kapt'
id 'com.google.dagger.hilt.android'
id 'org.jetbrains.kotlin.plugin.serialization' version '1.8.0'
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
@@ -10,6 +9,8 @@ plugins {
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
id 'com.google.android.gms.oss-licenses-plugin'
+ id 'org.jetbrains.kotlin.plugin.compose' version '2.1.0'
+ id 'com.google.devtools.ksp'
}
android {
@@ -23,10 +24,6 @@ android {
compose true
}
- composeOptions {
- kotlinCompilerExtensionVersion = "1.5.2"
- }
-
defaultConfig {
applicationId "com.isolaatti"
minSdk 24
@@ -54,7 +51,7 @@ android {
}
dependencies {
- coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.3'
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
@@ -73,8 +70,8 @@ dependencies {
implementation "androidx.datastore:datastore-preferences:1.0.0"
// Hilt
- implementation "com.google.dagger:hilt-android:2.47"
- kapt "com.google.dagger:hilt-compiler:2.47"
+ implementation "com.google.dagger:hilt-android:2.53.1"
+ ksp "com.google.dagger:hilt-compiler:2.53.1"
// Retrofit
@@ -120,11 +117,10 @@ dependencies {
}
// Room Database
- def room_version = "2.5.2"
+ def room_version = "2.6.1"
implementation "androidx.room:room-runtime:$room_version"
- annotationProcessor "androidx.room:room-compiler:$room_version"
- kapt("androidx.room:room-compiler:$room_version")
- implementation "androidx.room:room-ktx:2.5.2"
+ ksp("androidx.room:room-compiler:$room_version")
+ implementation "androidx.room:room-ktx:$room_version"
// Image viewer
implementation 'com.github.MikeOrtiz:TouchImageView:3.5'
@@ -138,7 +134,7 @@ dependencies {
implementation 'com.github.androidmads:QRGenerator:1.0.1'
// Firebase
- implementation(platform("com.google.firebase:firebase-bom:32.7.3"))
+ implementation(platform("com.google.firebase:firebase-bom:33.7.0"))
implementation("com.google.firebase:firebase-crashlytics")
implementation("com.google.firebase:firebase-analytics")
implementation("com.google.firebase:firebase-messaging")
@@ -146,7 +142,7 @@ dependencies {
// OSS screen
implementation 'com.google.android.gms:play-services-oss-licenses:17.1.0'
- def composeBom = platform('androidx.compose:compose-bom:2024.10.01')
+ def composeBom = platform('androidx.compose:compose-bom:2024.12.01')
implementation composeBom
androidTestImplementation composeBom
implementation 'androidx.compose.material3:material3'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 703092e..b60f867 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,10 +49,7 @@
-
-
-
AudiosListSelectorFragment.getInstance()
- 1 -> AudiosListSelectorFragment.getInstanceForDrafts()
- else -> Fragment()
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/isolaatti/audio/audio_selector/presentation/AudioSelectorViewModel.kt b/app/src/main/java/com/isolaatti/audio/audio_selector/presentation/AudioSelectorViewModel.kt
deleted file mode 100644
index 8b5cf7c..0000000
--- a/app/src/main/java/com/isolaatti/audio/audio_selector/presentation/AudioSelectorViewModel.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.isolaatti.audio.audio_selector.presentation
-
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewModelScope
-import com.isolaatti.audio.common.domain.Audio
-import com.isolaatti.audio.common.domain.AudiosRepository
-import com.isolaatti.audio.common.domain.Playable
-import com.isolaatti.audio.drafts.domain.AudioDraft
-import com.isolaatti.audio.drafts.domain.repository.AudioDraftsRepository
-import com.isolaatti.auth.domain.AuthRepository
-import com.isolaatti.common.SortingEnum
-import com.isolaatti.utils.Resource
-import dagger.hilt.android.lifecycle.HiltViewModel
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.flow.flowOn
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.launch
-import javax.inject.Inject
-
-@HiltViewModel
-class AudioSelectorViewModel @Inject constructor(
- private val audiosRepository: AudiosRepository,
- private val audioDraftsRepository: AudioDraftsRepository
-) : ViewModel() {
- val audios: MutableLiveData> = MutableLiveData()
- val drafts: MutableLiveData> = MutableLiveData()
- val sorting: MutableLiveData = MutableLiveData()
- var squadId: String? = null
- val error: MutableLiveData = MutableLiveData(null)
- val loading: MutableLiveData = MutableLiveData()
- fun setSorting(sort: SortingEnum) {
- sorting.value = sort
- }
-
- fun getAudioDrafts() {
- viewModelScope.launch {
- audioDraftsRepository.getAudioDrafts().onEach {
- drafts.postValue(it)
- }
- }
- }
-
- fun getAudios() {
- if(squadId == null) {
- viewModelScope.launch {
- audiosRepository.getMyAudios(audios.value?.lastOrNull()?.id).onEach { resource ->
- when(resource) {
- is Resource.Error -> {
- loading.postValue(false)
- error.postValue(resource.errorType)
- }
- is Resource.Loading -> {
- loading.postValue(true)
- }
- is Resource.Success -> {
- loading.postValue(false)
- audios.postValue(resource.data ?: listOf())
- }
- }
- }.flowOn(Dispatchers.IO).launchIn(this)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/isolaatti/audio/audio_selector/ui/AudioSelectorActivity.kt b/app/src/main/java/com/isolaatti/audio/audio_selector/ui/AudioSelectorActivity.kt
deleted file mode 100644
index 14ae1ea..0000000
--- a/app/src/main/java/com/isolaatti/audio/audio_selector/ui/AudioSelectorActivity.kt
+++ /dev/null
@@ -1,91 +0,0 @@
-package com.isolaatti.audio.audio_selector.ui
-
-import android.os.Bundle
-import androidx.activity.viewModels
-import androidx.appcompat.widget.PopupMenu
-import androidx.navigation.findNavController
-import androidx.viewpager2.widget.ViewPager2
-import com.google.android.material.tabs.TabLayoutMediator
-import com.isolaatti.R
-import com.isolaatti.audio.audio_selector.presentation.AudioSelectorFragmentAdapter
-import com.isolaatti.audio.audio_selector.presentation.AudioSelectorViewModel
-import com.isolaatti.audio.recorder.ui.AudioRecorderContract
-import com.isolaatti.common.IsolaattiBaseActivity
-import com.isolaatti.common.SortingEnum
-import com.isolaatti.databinding.ActivityAudioSelectorBinding
-
-class AudioSelectorActivity : IsolaattiBaseActivity() {
- companion object {
- const val EXTRA_ID = "id"
- const val EXTRA_FOR_SQUAD = "forSquad"
- const val OUT_EXTRA_PLAYABLE = "playable"
- }
-
- private lateinit var binding: ActivityAudioSelectorBinding
- private val viewModel: AudioSelectorViewModel by viewModels()
-
- private val audioRecorderLauncher = registerForActivityResult(AudioRecorderContract()) {
-
- }
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
-
- binding = ActivityAudioSelectorBinding.inflate(layoutInflater)
-
- setContentView(binding.root)
-
- binding.viewpager.adapter = AudioSelectorFragmentAdapter(this)
-
- TabLayoutMediator(binding.tabLayout, binding.viewpager) {tab, position ->
- when(position) {
- 0 -> tab.text = getString(R.string.audios)
- 1 -> tab.text = getString(R.string.drafts)
- }
- }.attach()
-
- binding.sort.setText(R.string.descending_by_name)
-
- setupListeners()
-
- }
-
- private fun setupListeners() {
- binding.toolbar.setNavigationOnClickListener {
- finish()
- }
- binding.newAudio.setOnClickListener {
- audioRecorderLauncher.launch(null)
- }
-
- binding.sort.setOnClickListener {
- val popupMenu = PopupMenu(this, it)
- popupMenu.inflate(R.menu.audios_sort_menu)
-
- popupMenu.setOnMenuItemClickListener { menuItem ->
- binding.sort.text = menuItem.title
- when(menuItem.itemId) {
- R.id.desc_by_name -> {
- viewModel.setSorting(SortingEnum.DescendingByName)
- true
- }
- R.id.asc_by_name -> {
- viewModel.setSorting(SortingEnum.AscendingByName)
- true
- }
- R.id.asc_by_creation_date -> {
- viewModel.setSorting(SortingEnum.AscendingByCreationDate)
- true
- }
- R.id.desc_by_creation_date -> {
- viewModel.setSorting(SortingEnum.DescendingByCreationDate)
- true
- }
- else -> false
- }
- }
- popupMenu.show()
- }
- }
-
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/isolaatti/audio/audio_selector/ui/AudioSelectorContract.kt b/app/src/main/java/com/isolaatti/audio/audio_selector/ui/AudioSelectorContract.kt
deleted file mode 100644
index 66bdbb4..0000000
--- a/app/src/main/java/com/isolaatti/audio/audio_selector/ui/AudioSelectorContract.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.isolaatti.audio.audio_selector.ui
-
-import android.app.Activity
-import android.content.Context
-import android.content.Intent
-import androidx.activity.result.contract.ActivityResultContract
-import com.isolaatti.audio.common.domain.Audio
-import com.isolaatti.audio.common.domain.Playable
-import java.io.Serializable
-
-/**
- * Contract to select audio. Use SelectorConfig class to specify the context to use to select audio.
- * Output: if user selected an audio or draft, it will be returned as result. Check type as convenient. Null if user cancelled
- */
-class AudioSelectorContract : ActivityResultContract() {
-
- /**
- * @param forSquad audios source will be a specified squad in the id param
- * @param id squad id, should be non null if forSquad is true
- */
- data class SelectorConfig(val forSquad: Boolean, val id: String?): Serializable
-
- override fun createIntent(context: Context, input: SelectorConfig): Intent {
- val intent = Intent(context, AudioSelectorActivity::class.java)
- intent.apply {
- putExtra(AudioSelectorActivity.EXTRA_FOR_SQUAD, input.forSquad)
- if(input.forSquad) {
- putExtra(AudioSelectorActivity.EXTRA_ID, input.id as String)
- }
-
- }
-
- return intent
- }
-
- override fun parseResult(resultCode: Int, intent: Intent?): Playable? {
- if(resultCode == Activity.RESULT_OK) {
- return intent?.extras?.getSerializable(AudioSelectorActivity.OUT_EXTRA_PLAYABLE) as? Playable
- }
-
- return null
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/isolaatti/audio/audio_selector/ui/AudiosListSelectorFragment.kt b/app/src/main/java/com/isolaatti/audio/audio_selector/ui/AudiosListSelectorFragment.kt
deleted file mode 100644
index cf97c9b..0000000
--- a/app/src/main/java/com/isolaatti/audio/audio_selector/ui/AudiosListSelectorFragment.kt
+++ /dev/null
@@ -1,105 +0,0 @@
-package com.isolaatti.audio.audio_selector.ui
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
-import com.isolaatti.audio.audio_selector.presentation.AudioSelectorViewModel
-import com.isolaatti.audio.audios_list.presentation.AudiosAdapter
-import com.isolaatti.databinding.FragmentAudiosListSelectorBinding
-import dagger.hilt.android.AndroidEntryPoint
-
-@AndroidEntryPoint
-class AudiosListSelectorFragment : Fragment() {
- private lateinit var binding: FragmentAudiosListSelectorBinding
- private val viewModel: AudioSelectorViewModel by activityViewModels()
-
- private var mode: Int = ARG_VAL_MODE_AUDIOS
- private var squadId: String? = null
-
- private lateinit var adapter: AudiosAdapter
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
-
- arguments?.getInt(ARG_MODE)?.let { mode = it }
- arguments?.getString(ARG_SQUAD_ID)?.let { squadId = it }
- viewModel.squadId = squadId
-
- when(mode) {
- ARG_VAL_MODE_AUDIOS -> {
- viewModel.getAudios()
- }
- ARG_VAL_MODE_DRAFTS -> {
- viewModel.getAudioDrafts()
- }
- }
-
- }
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- binding = FragmentAudiosListSelectorBinding.inflate(inflater, container, false)
- return binding.root
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- adapter = AudiosAdapter(
- onPlayClick = {
-
- },
- onOptionsClick = {audio, button ->
- false
- }
- )
- binding.recycler.adapter = adapter
-
- when(mode) {
- ARG_VAL_MODE_AUDIOS -> {
- viewModel.audios.observe(viewLifecycleOwner) {
- adapter.setData(it)
- }
- }
- ARG_VAL_MODE_DRAFTS -> {
- viewModel.drafts.observe(viewLifecycleOwner) {
-
- }
- }
- }
- }
-
- companion object {
- private const val ARG_MODE = "mode"
- private const val ARG_SQUAD_ID = "squadId"
- private const val ARG_VAL_MODE_DRAFTS = 0
- private const val ARG_VAL_MODE_AUDIOS = 1
- fun getInstance(): AudiosListSelectorFragment {
- return AudiosListSelectorFragment().apply {
- arguments = Bundle().apply {
- putInt(ARG_MODE, ARG_VAL_MODE_AUDIOS)
- }
- }
- }
-
- fun getInstanceForDrafts(): AudiosListSelectorFragment {
- return AudiosListSelectorFragment().apply {
- arguments = Bundle().apply {
- putInt(ARG_MODE, ARG_VAL_MODE_DRAFTS)
- }
- }
- }
- fun getInstanceForSquad(squadId: String): AudiosListSelectorFragment {
- return AudiosListSelectorFragment().apply {
- arguments = Bundle().apply {
- putString(ARG_SQUAD_ID, squadId)
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/isolaatti/audio/audios_list/presentation/AudiosAdapter.kt b/app/src/main/java/com/isolaatti/audio/audios_list/presentation/AudiosAdapter.kt
deleted file mode 100644
index a412ce9..0000000
--- a/app/src/main/java/com/isolaatti/audio/audios_list/presentation/AudiosAdapter.kt
+++ /dev/null
@@ -1,154 +0,0 @@
-package com.isolaatti.audio.audios_list.presentation
-
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.core.content.res.ResourcesCompat
-import androidx.recyclerview.widget.RecyclerView
-import androidx.recyclerview.widget.RecyclerView.ViewHolder
-import coil.load
-import com.isolaatti.R
-import com.isolaatti.audio.common.domain.Audio
-import com.isolaatti.databinding.AudioListItemBinding
-
-class AudiosAdapter(
- private val onPlayClick: ((audio: Audio) -> Unit),
- private val onOptionsClick: ((audio: Audio, button: View) -> Boolean)
-) : RecyclerView.Adapter() {
-
- enum class Payload {
- PlayStateChanged, IsLoadingChanged
- }
-
- private var data: List