From a1b67584f84d3e95dccb000787ef6b047152519f Mon Sep 17 00:00:00 2001 From: Nguyen Duc Tuan Minh Date: Mon, 9 Dec 2024 23:06:23 +0700 Subject: [PATCH] Done SettingScreen --- app/build.gradle.kts | 1 + .../com/maxrave/simpmusic/common/Config.kt | 49 +- .../data/dataStore/DataStoreManager.kt | 5 + .../ui/fragment/home/SettingsFragment.kt | 1020 +----------- .../simpmusic/ui/screen/home/SettingScreen.kt | 506 +++++- .../com/maxrave/simpmusic/ui/theme/Theme.kt | 2 +- .../simpmusic/viewModel/SettingsViewModel.kt | 102 +- app/src/main/res/raw/aboutlibraries.json | 1401 +++++++++++------ app/src/main/res/values/strings.xml | 1 + gradle/libs.versions.toml | 1 + .../extension/StringExt.kt | 5 + 11 files changed, 1518 insertions(+), 1575 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index cf8ab4a2..4c1905ce 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -289,6 +289,7 @@ dependencies { implementation(libs.ssp.android) implementation(libs.aboutlibraries) + implementation(libs.aboutlibraries.compose.m3) implementation(libs.flexbox) implementation(libs.balloon) diff --git a/app/src/main/java/com/maxrave/simpmusic/common/Config.kt b/app/src/main/java/com/maxrave/simpmusic/common/Config.kt index f9de11b8..f72448a6 100644 --- a/app/src/main/java/com/maxrave/simpmusic/common/Config.kt +++ b/app/src/main/java/com/maxrave/simpmusic/common/Config.kt @@ -1,5 +1,7 @@ package com.maxrave.simpmusic.common +import android.content.Context +import android.util.Log import com.maxrave.simpmusic.R import java.time.LocalDateTime import java.time.Month @@ -25,7 +27,7 @@ object Config { const val CANVAS_CACHE = "canvasCache" const val SERVICE_SCOPE = "serviceScope" - val REMOVED_SONG_DATE_TIME = LocalDateTime.of(2003, Month.AUGUST, 26, 3, 0) + val REMOVED_SONG_DATE_TIME: LocalDateTime = LocalDateTime.of(2003, Month.AUGUST, 26, 3, 0) val listOfHomeChip = listOf( @@ -217,6 +219,24 @@ object SUPPORTED_LANGUAGE { "hi-IN", "th-TH" ) + fun getLanguageFromCode(code: String?): String { + val index = codes.indexOf(code) + Log.d("Config", "getLanguageFromCode: $index") + if (index == -1) { + return "English" + } + Log.w("Config", "getLanguageFromCode: ${items.get(index)}") + return (items.getOrNull(index) ?: "English").toString() + } + fun getCodeFromLanguage(language: String?): String { + val index = items.indexOf(language ?: "English") + Log.d("Config", "getCodeFromLanguage: $index") + if (index == -1) { + return "en-US" + } + Log.w("Config", "getCodeFromLanguage: ${codes.getOrNull(index)}") + return (codes.getOrNull(index) ?: "en-US").toString() + } } object QUALITY { @@ -236,6 +256,15 @@ object LYRICS_PROVIDER { object LIMIT_CACHE_SIZE { val items: Array = arrayOf("100MB", "250MB", "500MB", "1GB", "2GB", "5GB", "8GB", "∞") val data: Array = arrayOf(100, 250, 500, 1000, 2000, 5000, 8000, -1) + + fun getDataFromItem(item: CharSequence?): Int { + val index = items.indexOf(item) + return data.getOrNull(index) ?: -1 + } + fun getItemFromData(input: Int?): CharSequence { + val index = data.indexOf(input) + return items.getOrNull(index) ?: "∞" + } } object SPONSOR_BLOCK { @@ -253,6 +282,24 @@ object SPONSOR_BLOCK { R.string.poi_highlight, R.string.filter, ) + fun fromDbToName(context: Context, list: List): List { + val result = mutableListOf() + for (item in list) { + val index = list.indexOf(item) + result.add(context.getString(listName[index])) + } + return result + } + fun fromNameToDb(context: Context, input: List): List { + val allString = fromDbToName(context, list.toList()) + val listIndex = allString.map { + allString.indexOf(it) + } + val result = listIndex.mapNotNull { + list.getOrNull(it) + } + return result + } } object CHART_SUPPORTED_COUNTRY { diff --git a/app/src/main/java/com/maxrave/simpmusic/data/dataStore/DataStoreManager.kt b/app/src/main/java/com/maxrave/simpmusic/data/dataStore/DataStoreManager.kt index 5984bc17..6f8afe0a 100644 --- a/app/src/main/java/com/maxrave/simpmusic/data/dataStore/DataStoreManager.kt +++ b/app/src/main/java/com/maxrave/simpmusic/data/dataStore/DataStoreManager.kt @@ -297,6 +297,11 @@ class DataStoreManager(private val settingsDataStore: DataStore) { settings[stringPreferencesKey(category)] = TRUE } } + SPONSOR_BLOCK.list.filter { !categories.contains(it) }.forEach { category -> + settingsDataStore.edit { settings -> + settings[stringPreferencesKey(category.toString())] = FALSE + } + } } } diff --git a/app/src/main/java/com/maxrave/simpmusic/ui/fragment/home/SettingsFragment.kt b/app/src/main/java/com/maxrave/simpmusic/ui/fragment/home/SettingsFragment.kt index 020803a3..b335f1a4 100644 --- a/app/src/main/java/com/maxrave/simpmusic/ui/fragment/home/SettingsFragment.kt +++ b/app/src/main/java/com/maxrave/simpmusic/ui/fragment/home/SettingsFragment.kt @@ -44,1022 +44,4 @@ class SettingsFragment : Fragment() { } } } - -} - -// override fun onCreateView( -// inflater: LayoutInflater, -// container: ViewGroup?, -// savedInstanceState: Bundle?, -// ): View { -// _binding = FragmentSettingsBinding.inflate(inflater, container, false) -// binding.topAppBarLayout.applyInsetter { -// type(statusBars = true) { -// margin() -// } -// } -// return binding.root -// } -// -// override fun onResume() { -// super.onResume() -// viewModel.getLoggedIn() -// } -// -// private var resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {} -// -// @UnstableApi -// override fun onViewCreated( -// view: View, -// savedInstanceState: Bundle?, -// ) { -// super.onViewCreated(view, savedInstanceState) -// -// viewModel.getLocation() -// viewModel.getLanguage() -// viewModel.getQuality() -// viewModel.getPlayerCacheSize() -// viewModel.getDownloadedCacheSize() -// viewModel.getPlayerCacheLimit() -// viewModel.getLoggedIn() -// viewModel.getNormalizeVolume() -// viewModel.getSkipSilent() -// viewModel.getSavedPlaybackState() -// viewModel.getSendBackToGoogle() -// viewModel.getSaveRecentSongAndQueue() -// viewModel.getLastCheckForUpdate() -// viewModel.getSponsorBlockEnabled() -// viewModel.getSponsorBlockCategories() -// viewModel.getTranslationLanguage() // -// viewModel.getLyricsProvider() // -// viewModel.getUseTranslation() // -// viewModel.getMusixmatchLoggedIn() // -// viewModel.getHomeLimit() -// viewModel.getPlayVideoInsteadOfAudio() -// viewModel.getVideoQuality() -// viewModel.getThumbCacheSize() -// viewModel.getSpotifyLogIn() -// viewModel.getSpotifyLyrics() -// viewModel.getSpotifyCanvas() -// viewModel.getTranslucentBottomBar() -// -// lifecycleScope.launch { -// viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) { -// val job1 = -// launch { -// viewModel.musixmatchLoggedIn.collect { -// if (it != null) { -// if (it == DataStoreManager.TRUE) { -// binding.tvMusixmatchLoginTitle.text = -// getString(R.string.log_out_from_musixmatch) -// binding.tvMusixmatchLogin.text = getString(R.string.logged_in) -// setEnabledAll(binding.swUseMusixmatchTranslation, true) -// setEnabledAll(binding.btTranslationLanguage, true) -// } else if (it == DataStoreManager.FALSE) { -// binding.tvMusixmatchLoginTitle.text = -// getString(R.string.log_in_to_Musixmatch) -// binding.tvMusixmatchLogin.text = -// getString(R.string.only_support_email_and_password_type) -// setEnabledAll(binding.swUseMusixmatchTranslation, false) -// setEnabledAll(binding.btTranslationLanguage, false) -// } -// } -// } -// } -// val job2 = -// launch { -// viewModel.playVideoInsteadOfAudio.collect { -// if (it == DataStoreManager.TRUE) { -// binding.swEnableVideo.isChecked = true -// setEnabledAll(binding.btVideoQuality, true) -// } else if (it == DataStoreManager.FALSE) { -// binding.swEnableVideo.isChecked = false -// setEnabledAll(binding.btVideoQuality, false) -// } -// } -// } -// -// val job3 = -// launch { -// viewModel.videoQuality.collect { -// binding.tvVideoQuality.text = it -// } -// } -// val job4 = -// launch { -// viewModel.mainLyricsProvider.collect { -// if (it == DataStoreManager.YOUTUBE) { -// binding.tvMainLyricsProvider.text = LYRICS_PROVIDER.items.get(1) -// } else if (it == DataStoreManager.MUSIXMATCH) { -// binding.tvMainLyricsProvider.text = LYRICS_PROVIDER.items.get(0) -// } -// } -// } -// val job5 = -// launch { -// viewModel.translationLanguage.collect { -// binding.tvTranslationLanguage.text = it -// } -// } -// val job6 = -// launch { -// viewModel.useTranslation.collect { -// binding.swUseMusixmatchTranslation.isChecked = it == DataStoreManager.TRUE -// } -// } -// val job7 = -// launch { -// viewModel.sendBackToGoogle.collect { -// binding.swSaveHistory.isChecked = it == DataStoreManager.TRUE -// } -// } -// val job8 = -// launch { -// viewModel.location.collect { -// binding.tvContentCountry.text = it -// } -// } -// val job9 = -// launch { -// viewModel.language.collect { -// Log.w("Language", it.toString()) -// if (it != null) { -// if (it.contains("id") || it.contains("in")) { -// binding.tvLanguage.text = "Bahasa Indonesia" -// } else { -// val temp = -// SUPPORTED_LANGUAGE.items.getOrNull( -// SUPPORTED_LANGUAGE.codes.indexOf( -// it, -// ), -// ) -// binding.tvLanguage.text = temp -// } -// } else { -// binding.tvLanguage.text = "Automatic" -// } -// } -// } -// val job10 = -// launch { -// viewModel.quality.collect { -// binding.tvQuality.text = it -// } -// } -// val job11 = -// launch { -// viewModel.cacheSize.collect { -// if (it != null) { -// drawDataStat() -// binding.tvPlayerCache.text = -// getString(R.string.cache_size, bytesToMB(it).toString()) -// } -// } -// } -// val job12 = -// launch { -// viewModel.downloadedCacheSize.collect { -// if (it != null) { -// drawDataStat() -// binding.tvDownloadedCache.text = -// getString(R.string.cache_size, bytesToMB(it).toString()) -// } -// } -// } -// val job13 = -// launch { -// viewModel.normalizeVolume.collect { -// binding.swNormalizeVolume.isChecked = it == DataStoreManager.TRUE -// } -// } -// val job14 = -// launch { -// viewModel.skipSilent.collect { -// binding.swSkipSilent.isChecked = it == DataStoreManager.TRUE -// } -// } -// val job15 = -// launch { -// viewModel.savedPlaybackState.collect { -// binding.swSavePlaybackState.isChecked = it == DataStoreManager.TRUE -// } -// } -// val job16 = -// launch { -// viewModel.saveRecentSongAndQueue.collect { -// binding.swSaveLastPlayed.isChecked = it == DataStoreManager.TRUE -// } -// } -// val job17 = -// launch { -// viewModel.saveRecentSongAndQueue.collect { -// binding.swSaveLastPlayed.isChecked = it == DataStoreManager.TRUE -// } -// } -// val job18 = -// launch { -// viewModel.sponsorBlockEnabled.collect { -// binding.swEnableSponsorBlock.isChecked = it == DataStoreManager.TRUE -// } -// } -// val job19 = -// launch { -// viewModel.lastCheckForUpdate.collect { -// if (it != null) { -// binding.tvCheckForUpdate.text = -// getString( -// R.string.last_checked_at, -// DateTimeFormatter -// .ofPattern("yyyy-MM-dd HH:mm:ss") -// .withZone(ZoneId.systemDefault()) -// .format(Instant.ofEpochMilli(it.toLong())), -// ) -// } -// } -// } -// val job20 = -// launch { -// viewModel.playerCacheLimit.collect { -// binding.tvLimitPlayerCache.text = -// if (it != -1) "$it MB" else getString(R.string.unlimited) -// } -// } -// val job21 = -// launch { -// viewModel.githubResponse.collect { response -> -// if (response != null) { -// if (response.tagName != getString(R.string.version_name)) { -// binding.tvCheckForUpdate.text = -// getString( -// R.string.last_checked_at, -// DateTimeFormatter -// .ofPattern("yyyy-MM-dd HH:mm:ss") -// .withZone(ZoneId.systemDefault()) -// .format(Instant.ofEpochMilli(System.currentTimeMillis())), -// ) -// val inputFormat = -// SimpleDateFormat( -// "yyyy-MM-dd'T'HH:mm:ss'Z'", -// Locale.getDefault(), -// ) -// val outputFormat = -// SimpleDateFormat("dd MMM yyyy HH:mm:ss", Locale.getDefault()) -// val formatted = -// response.publishedAt?.let { input -> -// inputFormat -// .parse(input) -// ?.let { outputFormat.format(it) } -// } -// MaterialAlertDialogBuilder(requireContext()) -// .setTitle(getString(R.string.update_available)) -// .setMessage( -// getString( -// R.string.update_message, -// response.tagName, -// formatted, -// response.body, -// ), -// ).setPositiveButton(getString(R.string.download)) { _, _ -> -// val browserIntent = -// Intent( -// Intent.ACTION_VIEW, -// Uri.parse(response.assets?.firstOrNull()?.browserDownloadUrl), -// ) -// startActivity(browserIntent) -// }.setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// dialog.dismiss() -// }.show() -// } else { -// Toast -// .makeText( -// requireContext(), -// getString(R.string.no_update), -// Toast.LENGTH_SHORT, -// ).show() -// viewModel.getLastCheckForUpdate() -// viewModel.lastCheckForUpdate.collect { -// if (it != null) { -// binding.tvCheckForUpdate.text = -// getString( -// R.string.last_checked_at, -// DateTimeFormatter -// .ofPattern("yyyy-MM-dd HH:mm:ss") -// .withZone(ZoneId.systemDefault()) -// .format(Instant.ofEpochMilli(it.toLong())), -// ) -// } -// } -// } -// } -// } -// } -// val job22 = -// launch { -// viewModel.thumbCacheSize.collect { -// binding.tvThumbnailCache.text = -// getString( -// R.string.cache_size, -// if (it != null) { -// bytesToMB(it) -// } else { -// 0 -// }.toString(), -// ) -// } -// } -// -// val job23 = -// launch { -// viewModel.spotifyLogIn.collect { -// if (it) { -// binding.tvSpotifyLogin.text = getString(R.string.logged_in) -// setEnabledAll(binding.btEnableCanvas, true) -// setEnabledAll(binding.btEnableSpotifyLyrics, true) -// } else { -// binding.tvSpotifyLogin.text = getString(R.string.intro_login_to_spotify) -// setEnabledAll(binding.btEnableCanvas, false) -// setEnabledAll(binding.btEnableSpotifyLyrics, false) -// } -// } -// } -// -// val job24 = -// launch { -// viewModel.spotifyLyrics.collect { -// if (it) { -// binding.swEnableSpotifyLyrics.isChecked = true -// } else { -// binding.swEnableSpotifyLyrics.isChecked = false -// } -// } -// } -// -// val job25 = -// launch { -// viewModel.spotifyCanvas.collect { -// if (it) { -// binding.swEnableCanvas.isChecked = true -// } else { -// binding.swEnableCanvas.isChecked = false -// } -// } -// } -// val job26 = -// launch { -// viewModel.homeLimit.collect { -// binding.tvHomeLimit.text = it.toString() -// if (it != null) { -// binding.sliderHomeLimit.value = it.toFloat() -// } -// } -// } -// val job27 = -// launch { -// viewModel.translucentBottomBar.collectLatest { translucent -> -// binding.swEnableTranslucentNavBar.isChecked = if (translucent == DataStoreManager.TRUE) true else false -// } -// } -// job1.join() -// job2.join() -// job3.join() -// job4.join() -// job5.join() -// job6.join() -// job7.join() -// job8.join() -// job9.join() -// job10.join() -// job11.join() -// job12.join() -// job13.join() -// job14.join() -// job15.join() -// job16.join() -// job17.join() -// job18.join() -// job19.join() -// job20.join() -// job21.join() -// job22.join() -// job23.join() -// job24.join() -// job25.join() -// job26.join() -// job27.join() -// } -// } -// binding.sliderHomeLimit.addOnSliderTouchListener( -// object : Slider.OnSliderTouchListener { -// override fun onStartTrackingTouch(slider: Slider) { -// // Responds to when slider's touch event is being started -// } -// -// override fun onStopTrackingTouch(slider: Slider) { -// viewModel.setHomeLimit(slider.value.toInt()) -// } -// }, -// ) -// binding.btLimitPlayerCache.setOnClickListener { -// var checkedIndex = -1 -// val dialog = -// MaterialAlertDialogBuilder(requireContext()) -// .setSingleChoiceItems(LIMIT_CACHE_SIZE.items, -1) { _, which -> -// checkedIndex = which -// }.setTitle(getString(R.string.limit_player_cache)) -// .setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// dialog.dismiss() -// }.setPositiveButton(getString(R.string.change)) { dialog, _ -> -// if (checkedIndex != -1) { -// viewModel.setPlayerCacheLimit(LIMIT_CACHE_SIZE.data[checkedIndex]) -// Toast -// .makeText( -// requireContext(), -// getString(R.string.restart_app), -// Toast.LENGTH_SHORT, -// ).show() -// } -// dialog.dismiss() -// } -// dialog.show() -// } -// binding.btYouTubeAccount.setOnClickListener { -// val dialog = MaterialAlertDialogBuilder(requireContext()) -// val accountBinding = -// YoutubeAccountDialogBinding.inflate(LayoutInflater.from(requireContext())) -// val accountAdapter = AccountAdapter(arrayListOf()) -// dialog.setView(accountBinding.root) -// val alertDialog = dialog.create() -// accountBinding.rvAccount.apply { -// adapter = accountAdapter -// layoutManager = LinearLayoutManager(requireContext()) -// } -// accountAdapter.setOnAccountClickListener( -// object : -// AccountAdapter.OnAccountClickListener { -// override fun onAccountClick(pos: Int) { -// Log.w("Account", accountAdapter.getAccountList().getOrNull(pos).toString()) -// if (accountAdapter.getAccountList().getOrNull(pos) != null) { -// viewModel.setUsedAccount(accountAdapter.getAccountList().get(pos)) -// } -// } -// }, -// ) -// accountBinding.btAddAccount.setOnClickListener { -// findNavController().navigateSafe(R.id.action_global_logInFragment) -// alertDialog.dismiss() -// } -// accountBinding.btClose.setOnClickListener { -// alertDialog.dismiss() -// } -// accountBinding.btGuest.setOnClickListener { -// viewModel.setUsedAccount(null) -// alertDialog.dismiss() -// } -// accountBinding.btLogOut.setOnClickListener { -// val subAlertDialogBuilder = -// MaterialAlertDialogBuilder(requireContext()) -// .setTitle(getString(R.string.warning)) -// .setMessage(getString(R.string.log_out_warning)) -// .setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// dialog.dismiss() -// }.setPositiveButton(getString(R.string.log_out)) { dialog, _ -> -// viewModel.logOutAllYouTube() -// } -// subAlertDialogBuilder.show() -// } -// viewModel.getAllGoogleAccount() -// accountBinding.loadingLayout.visibility = View.VISIBLE -// lifecycleScope.launch { -// val job2 = -// launch { -// viewModel.loading.collectLatest { -// if (it) { -// accountBinding.loadingLayout.visibility = View.VISIBLE -// accountBinding.apply { -// setEnabledAll(btAddAccount, false) -// setEnabledAll(btLogOut, false) -// setEnabledAll(btGuest, false) -// } -// } else { -// accountBinding.loadingLayout.visibility = View.GONE -// accountBinding.apply { -// setEnabledAll(btAddAccount, true) -// setEnabledAll(btLogOut, true) -// setEnabledAll(btGuest, true) -// } -// } -// } -// } -// val job1 = -// launch { -// viewModel.googleAccounts.collect { -// if (it != null) { -// accountBinding.tvNoAccount.visibility = View.GONE -// accountBinding.rvAccount.visibility = View.VISIBLE -// accountAdapter.updateAccountList(it) -// } else { -// accountAdapter.updateAccountList(arrayListOf()) -// accountBinding.tvNoAccount.visibility = View.VISIBLE -// accountBinding.rvAccount.visibility = View.GONE -// } -// } -// } -// job1.join() -// job2.join() -// } -// alertDialog.show() -// } -// binding.btCheckForUpdate.setOnClickListener { -// binding.tvCheckForUpdate.text = getString(R.string.checking) -// viewModel.checkForUpdate() -// } -// -// binding.btVersion.setOnClickListener { -// findNavController().navigateSafe(R.id.action_global_creditFragment) -// } -// -// binding.btMusixmatchLogin.setOnClickListener { -// if (viewModel.musixmatchLoggedIn.value == DataStoreManager.TRUE) { -// viewModel.clearMusixmatchCookie() -// Toast.makeText(requireContext(), getString(R.string.logged_out), Toast.LENGTH_SHORT).show() -// } else if (viewModel.musixmatchLoggedIn.value == DataStoreManager.FALSE) { -// findNavController().navigateSafe(R.id.action_global_musixmatchFragment) -// } -// } -// -// binding.btEqualizer.setOnClickListener { -// val eqIntent = Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL) -// eqIntent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, requireContext().packageName) -// eqIntent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, viewModel.getAudioSessionId()) -// eqIntent.putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC) -// val packageManager = requireContext().packageManager -// val resolveInfo: List<*> = packageManager.queryIntentActivities(eqIntent, 0) -// Log.d("EQ", resolveInfo.toString()) -// if (resolveInfo.isEmpty()) { -// Toast.makeText(requireContext(), getString(R.string.no_equalizer), Toast.LENGTH_SHORT).show() -// } else { -// resultLauncher.launch(eqIntent) -// } -// } -// binding.btGithub.setOnClickListener { -// val urlIntent = -// Intent( -// Intent.ACTION_VIEW, -// Uri.parse("https://github.com/maxrave-dev/"), -// ) -// startActivity(urlIntent) -// } -// binding.btDonate.setOnClickListener { -// val urlIntent = -// Intent( -// Intent.ACTION_VIEW, -// Uri.parse("https://buymeacoffee.com/maxrave"), -// ) -// startActivity(urlIntent) -// } -// binding.btStoragePlayerCache.setOnClickListener { -// val dialog = -// MaterialAlertDialogBuilder(requireContext()) -// .setTitle(getString(R.string.clear_player_cache)) -// .setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// dialog.dismiss() -// }.setPositiveButton(getString(R.string.clear)) { dialog, _ -> -// viewModel.clearPlayerCache() -// dialog.dismiss() -// } -// dialog.show() -// } -// binding.btContentCountry.setOnClickListener { -// var checkedIndex = -1 -// val dialog = -// MaterialAlertDialogBuilder(requireContext()) -// .setSingleChoiceItems(SUPPORTED_LOCATION.items, -1) { _, which -> -// checkedIndex = which -// }.setTitle(getString(R.string.content_country)) -// .setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// dialog.dismiss() -// }.setPositiveButton(getString(R.string.change)) { dialog, _ -> -// if (checkedIndex != -1) { -// viewModel.changeLocation(SUPPORTED_LOCATION.items[checkedIndex].toString()) -// } -// dialog.dismiss() -// } -// dialog.show() -// } -// binding.btLanguage.setOnClickListener { -// var checkedIndex = -1 -// val dialog = -// MaterialAlertDialogBuilder(requireContext()) -// .setSingleChoiceItems(SUPPORTED_LANGUAGE.items, -1) { _, which -> -// checkedIndex = which -// }.setTitle(getString(R.string.language)) -// .setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// dialog.dismiss() -// }.setPositiveButton(getString(R.string.change)) { dialog, _ -> -// if (checkedIndex != -1) { -// val alertDialog = -// MaterialAlertDialogBuilder(requireContext()) -// .setTitle(R.string.warning) -// .setMessage(R.string.change_language_warning) -// .setNegativeButton(getString(R.string.cancel)) { d, _ -> -// d.dismiss() -// dialog.dismiss() -// }.setPositiveButton(getString(R.string.change)) { d, _ -> -// viewModel.changeLanguage(SUPPORTED_LANGUAGE.codes[checkedIndex]) -// if (SUPPORTED_LANGUAGE.codes.getOrNull(checkedIndex) != null) { -// runCatching { -// SUPPORTED_LANGUAGE.items[ -// SUPPORTED_LANGUAGE.codes.indexOf( -// SUPPORTED_LANGUAGE.codes[checkedIndex], -// ), -// ] -// }.onSuccess { temp -> -// binding.tvLanguage.text = temp -// val code = SUPPORTED_LANGUAGE.codes.getOrNull(checkedIndex) -// val localeList = -// LocaleListCompat.forLanguageTags( -// if (code == "id-ID") { -// if (Build.VERSION.SDK_INT >= 35) { -// "id-ID" -// } else { -// "in-ID" -// } -// } else { -// code -// }, -// ) -// Log.d("Language", localeList.toString()) -// sharedViewModel.activityRecreate() -// AppCompatDelegate.setApplicationLocales(localeList) -// }.onFailure { -// Toast -// .makeText( -// requireContext(), -// getString(R.string.invalid_language_code), -// Toast.LENGTH_SHORT, -// ).show() -// } -// } -// d.dismiss() -// dialog.dismiss() -// } -// alertDialog.show() -// } -// dialog.dismiss() -// } -// dialog.show() -// } -// binding.btQuality.setOnClickListener { -// var checkedIndex = -1 -// val dialog = -// MaterialAlertDialogBuilder(requireContext()) -// .setSingleChoiceItems(QUALITY.items, -1) { _, which -> -// checkedIndex = which -// }.setTitle(getString(R.string.quality)) -// .setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// dialog.dismiss() -// }.setPositiveButton(getString(R.string.change)) { dialog, _ -> -// if (checkedIndex != -1) { -// viewModel.changeQuality(checkedIndex) -// } -// dialog.dismiss() -// } -// dialog.show() -// } -// binding.btVideoQuality.setOnClickListener { -// var checkedIndex = -1 -// val dialog = -// MaterialAlertDialogBuilder(requireContext()) -// .setSingleChoiceItems(VIDEO_QUALITY.items, -1) { _, which -> -// checkedIndex = which -// }.setTitle(getString(R.string.quality_video)) -// .setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// dialog.dismiss() -// }.setPositiveButton(getString(R.string.change)) { dialog, _ -> -// if (checkedIndex != -1) { -// viewModel.changeVideoQuality(checkedIndex) -// } -// dialog.dismiss() -// } -// dialog.show() -// } -// binding.btMainLyricsProvider.setOnClickListener { -// var checkedIndex = -1 -// val dialog = -// MaterialAlertDialogBuilder(requireContext()) -// .setTitle(getString(R.string.main_lyrics_provider)) -// .setSingleChoiceItems(LYRICS_PROVIDER.items, -1) { _, which -> -// checkedIndex = which -// }.setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// dialog.dismiss() -// }.setPositiveButton(getString(R.string.change)) { dialog, _ -> -// if (checkedIndex != -1) { -// if (checkedIndex == 0) { -// viewModel.setLyricsProvider(DataStoreManager.MUSIXMATCH) -// binding.tvMainLyricsProvider.text = DataStoreManager.MUSIXMATCH -// } else if (checkedIndex == 1) { -// viewModel.setLyricsProvider(DataStoreManager.YOUTUBE) -// binding.tvMainLyricsProvider.text = DataStoreManager.YOUTUBE -// } -// } -// viewModel.getLyricsProvider() -// dialog.dismiss() -// } -// dialog.show() -// } -// -// binding.btTranslationLanguage.setOnClickListener { -// val materialAlertDialogBuilder = MaterialAlertDialogBuilder(requireContext()) -// materialAlertDialogBuilder.setTitle(getString(R.string.translation_language)) -// materialAlertDialogBuilder.setMessage(getString(R.string.translation_language_message)) -// val editText = EditText(requireContext()) -// materialAlertDialogBuilder.setView(editText) -// materialAlertDialogBuilder.setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// dialog.dismiss() -// } -// materialAlertDialogBuilder.setPositiveButton(getString(R.string.change)) { dialog, _ -> -// if (editText.text.toString().isNotEmpty()) { -// if (editText.text.toString().length == 2) { -// viewModel.setTranslationLanguage(editText.text.toString()) -// } else { -// Toast.makeText(requireContext(), getString(R.string.invalid_language_code), Toast.LENGTH_SHORT).show() -// } -// } else { -// if (viewModel.language.value != null && viewModel.language.value!!.length >= 2) { -// viewModel.language.value -// ?.slice(0..1) -// ?.let { it1 -> viewModel.setTranslationLanguage(it1) } -// } -// } -// dialog.dismiss() -// } -// materialAlertDialogBuilder.show() -// } -// -// binding.btStorageDownloadedCache.setOnClickListener { -// val dialog = -// MaterialAlertDialogBuilder(requireContext()) -// .setTitle(getString(R.string.clear_downloaded_cache)) -// .setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// dialog.dismiss() -// }.setPositiveButton(getString(R.string.clear)) { dialog, _ -> -// viewModel.clearDownloadedCache() -// dialog.dismiss() -// } -// dialog.show() -// } -// -// binding.btStorageThumbnailCache.setOnClickListener { -// val dialog = -// MaterialAlertDialogBuilder(requireContext()) -// .setTitle(getString(R.string.clear_thumbnail_cache)) -// .setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// dialog.dismiss() -// }.setPositiveButton(getString(R.string.clear)) { dialog, _ -> -// viewModel.clearThumbnailCache() -// dialog.dismiss() -// } -// dialog.show() -// } -// binding.btCategoriesSponsorBlock.setOnClickListener { -// Log.d("Check category", viewModel.sponsorBlockCategories.value.toString()) -// val selectedItem: ArrayList = arrayListOf() -// val item: Array = -// Array(9) { i -> -// getString(SPONSOR_BLOCK.listName[i]) -// } -// -// val checked = -// BooleanArray(9) { i -> -// if (!viewModel.sponsorBlockCategories.value.isNullOrEmpty()) { -// viewModel.sponsorBlockCategories.value!!.contains(SPONSOR_BLOCK.list[i].toString()) -// } else { -// false -// } -// } -// -// val dialog = -// MaterialAlertDialogBuilder(requireContext()) -// .setTitle("Category") -// .setMultiChoiceItems(item, checked) { _, i, b -> -// if (b) { -// if (!selectedItem.contains(SPONSOR_BLOCK.list[i].toString())) { -// selectedItem.add(SPONSOR_BLOCK.list[i].toString()) -// } -// } else { -// if (selectedItem.contains(SPONSOR_BLOCK.list[i].toString())) { -// selectedItem.remove(SPONSOR_BLOCK.list[i].toString()) -// } -// } -// }.setPositiveButton(getString(R.string.save)) { dialog, _ -> -// viewModel.setSponsorBlockCategories(selectedItem) -// Log.d("Check category", selectedItem.toString()) -// viewModel.getSponsorBlockCategories() -// }.setNegativeButton(R.string.cancel) { dialog, _ -> -// dialog.dismiss() -// } -// dialog.show() -// } -// -// binding.topAppBar.setNavigationOnClickListener { -// findNavController().popBackStack() -// } -// -// binding.btBackup.setOnClickListener { -// val formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss") -// backupLauncher.launch("${getString(R.string.app_name)}_${LocalDateTime.now().format(formatter)}.backup") -// } -// -// binding.btRestore.setOnClickListener { -// restoreLauncher.launch(arrayOf("application/octet-stream")) -// } -// binding.swNormalizeVolume.setOnCheckedChangeListener { _, checked -> -// if (checked) { -// viewModel.setNormalizeVolume(true) -// } else { -// viewModel.setNormalizeVolume(false) -// } -// } -// binding.swEnableTranslucentNavBar.setOnCheckedChangeListener { _, isChecked -> -// if (isChecked) { -// viewModel.setTranslucentBottomBar(true) -// } else { -// viewModel.setTranslucentBottomBar(false) -// } -// } -// binding.swEnableVideo.setOnCheckedChangeListener { _, checked -> -// val test = viewModel.playVideoInsteadOfAudio.value -// val checkReal = (test == DataStoreManager.TRUE) != checked -// if (checkReal) { -// val dialog = -// MaterialAlertDialogBuilder(requireContext()) -// .setTitle(getString(R.string.warning)) -// .setMessage(getString(R.string.play_video_instead_of_audio_warning)) -// .setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// binding.swEnableVideo.isChecked = false -// dialog.dismiss() -// }.setPositiveButton(getString(R.string.change)) { dialog, _ -> -// viewModel.clearPlayerCache() -// if (checked) { -// viewModel.setPlayVideoInsteadOfAudio(true) -// } else { -// viewModel.setPlayVideoInsteadOfAudio(false) -// } -// dialog.dismiss() -// } -// dialog.show() -// } -// } -// binding.swSkipSilent.setOnCheckedChangeListener { _, checked -> -// if (checked) { -// viewModel.setSkipSilent(true) -// } else { -// viewModel.setSkipSilent(false) -// } -// } -// binding.swSavePlaybackState.setOnCheckedChangeListener { _, checked -> -// if (checked) { -// viewModel.setSavedPlaybackState(true) -// } else { -// viewModel.setSavedPlaybackState(false) -// } -// } -// binding.swSaveLastPlayed.setOnCheckedChangeListener { _, checked -> -// if (checked) { -// viewModel.setSaveLastPlayed(true) -// } else { -// viewModel.setSaveLastPlayed(false) -// } -// } -// binding.swEnableSponsorBlock.setOnCheckedChangeListener { _, checked -> -// if (checked) { -// viewModel.setSponsorBlockEnabled(true) -// } else { -// viewModel.setSponsorBlockEnabled(false) -// } -// } -// binding.swSaveHistory.setOnCheckedChangeListener { _, checked -> -// if (checked) { -// viewModel.setSendBackToGoogle(true) -// } else { -// viewModel.setSendBackToGoogle(false) -// } -// } -// binding.swUseMusixmatchTranslation.setOnCheckedChangeListener { _, checked -> -// if (checked) { -// viewModel.setUseTranslation(true) -// } else { -// viewModel.setUseTranslation(false) -// } -// } -// binding.btSpotifyLogin.setOnClickListener { -// if (runBlocking { viewModel.spotifyLogIn.value }) { -// val subAlertDialogBuilder = -// MaterialAlertDialogBuilder(requireContext()) -// .setTitle(getString(R.string.warning)) -// .setMessage(getString(R.string.log_out_warning)) -// .setNegativeButton(getString(R.string.cancel)) { dialog, _ -> -// dialog.dismiss() -// }.setPositiveButton(getString(R.string.log_out_from_spotify)) { dialog, _ -> -// viewModel.setSpotifyLogIn(false) -// } -// subAlertDialogBuilder.show() -// } else { -// findNavController().navigateSafe(R.id.action_global_spotifyLogInFragment) -// } -// } -// binding.swEnableSpotifyLyrics.setOnCheckedChangeListener { _, checked -> -// if (checked) { -// viewModel.setSpotifyLyrics(true) -// } else { -// viewModel.setSpotifyLyrics(false) -// } -// } -// binding.swEnableCanvas.setOnCheckedChangeListener { _, checked -> -// if (checked) { -// viewModel.setSpotifyCanvas(true) -// } else { -// viewModel.setSpotifyCanvas(false) -// } -// } -// binding.bt3rdPartyLibraries.setOnClickListener { -// val inputStream = requireContext().resources.openRawResource(R.raw.aboutlibraries) -// val scanner = Scanner(inputStream).useDelimiter("\\A") -// val stringBuilder = StringBuilder() -// while (scanner.hasNextLine()) { -// stringBuilder.append(scanner.nextLine()) -// } -// Log.w("AboutLibraries", stringBuilder.toString()) -// val localLib = Libs.Builder().withJson(stringBuilder.toString()).build() -// val intent = -// LibsBuilder() -// .withLicenseShown(true) -// .withVersionShown(true) -// .withActivityTitle(getString(R.string.third_party_libraries)) -// .withSearchEnabled(true) -// .withEdgeToEdge(true) -// .withLibs( -// localLib, -// ).intent(requireContext()) -// startActivity(intent) -// } -// } -// -// private fun browseFiles(dir: File): Long { -// var dirSize: Long = 0 -// if (!dir.listFiles().isNullOrEmpty()) { -// for (f in dir.listFiles()!!) { -// dirSize += f.length() -// if (f.isDirectory) { -// dirSize += browseFiles(f) -// } -// } -// } -// return dirSize -// } -// -// private fun drawDataStat() { -// lifecycleScope.launch { -// repeatOnLifecycle(Lifecycle.State.CREATED) { -// launch { -// val mStorageStatsManager = -// getSystemService(requireContext(), StorageStatsManager::class.java) -// if (mStorageStatsManager != null) { -// val totalByte = -// mStorageStatsManager.getTotalBytes(StorageManager.UUID_DEFAULT) -// val freeSpace = -// mStorageStatsManager.getFreeBytes(StorageManager.UUID_DEFAULT) -// val usedSpace = totalByte - freeSpace -// val simpMusicSize = browseFiles(requireContext().filesDir) -// val otherApp = simpMusicSize.let { usedSpace.minus(it) } -// val databaseSize = -// simpMusicSize - viewModel.playerCache.cacheSpace - viewModel.downloadCache.cacheSpace -// if (totalByte == -// freeSpace + otherApp + databaseSize + viewModel.playerCache.cacheSpace + viewModel.downloadCache.cacheSpace -// ) { -// (binding.flexBox.getChildAt(0).layoutParams as FlexboxLayout.LayoutParams).flexBasisPercent = -// otherApp.toFloat().div(totalByte.toFloat()) -// (binding.flexBox.getChildAt(1).layoutParams as FlexboxLayout.LayoutParams).flexBasisPercent = -// viewModel.downloadCache.cacheSpace -// .toFloat() -// .div(totalByte.toFloat()) -// (binding.flexBox.getChildAt(2).layoutParams as FlexboxLayout.LayoutParams).flexBasisPercent = -// viewModel.playerCache.cacheSpace -// .toFloat() -// .div(totalByte.toFloat()) -// (binding.flexBox.getChildAt(3).layoutParams as FlexboxLayout.LayoutParams).flexBasisPercent = -// databaseSize.toFloat().div(totalByte.toFloat()) -// (binding.flexBox.getChildAt(4).layoutParams as FlexboxLayout.LayoutParams).flexBasisPercent = -// freeSpace.toFloat().div(totalByte.toFloat()) -// } -// } -// } -// } -// } -// } -// -// private fun bytesToMB(bytes: Long): Long { -// val mbInBytes = 1024 * 1024 -// return bytes / mbInBytes -// } -//} \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/java/com/maxrave/simpmusic/ui/screen/home/SettingScreen.kt b/app/src/main/java/com/maxrave/simpmusic/ui/screen/home/SettingScreen.kt index d8e67e48..85b10f5b 100644 --- a/app/src/main/java/com/maxrave/simpmusic/ui/screen/home/SettingScreen.kt +++ b/app/src/main/java/com/maxrave/simpmusic/ui/screen/home/SettingScreen.kt @@ -17,21 +17,31 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.Error +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Checkbox import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.RadioButton import androidx.compose.material3.Slider import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.TextField import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment @@ -50,29 +60,51 @@ import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.withLink import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.lifecycle.viewmodel.compose.viewModel import androidx.media3.common.util.UnstableApi import androidx.navigation.NavController +import coil3.annotation.ExperimentalCoilApi +import com.maxrave.kotlinytmusicscraper.extension.isTwoLetterCode import com.maxrave.simpmusic.R +import com.maxrave.simpmusic.common.LIMIT_CACHE_SIZE +import com.maxrave.simpmusic.common.QUALITY +import com.maxrave.simpmusic.common.SPONSOR_BLOCK +import com.maxrave.simpmusic.common.SUPPORTED_LANGUAGE +import com.maxrave.simpmusic.common.SUPPORTED_LOCATION +import com.maxrave.simpmusic.data.dataStore.DataStoreManager import com.maxrave.simpmusic.data.dataStore.DataStoreManager.Settings.TRUE import com.maxrave.simpmusic.extension.bytesToMB +import com.maxrave.simpmusic.extension.navigateSafe import com.maxrave.simpmusic.ui.component.EndOfPage import com.maxrave.simpmusic.ui.component.RippleIconButton import com.maxrave.simpmusic.ui.component.SettingItem +import com.maxrave.simpmusic.ui.theme.DarkColors import com.maxrave.simpmusic.ui.theme.md_theme_dark_primary import com.maxrave.simpmusic.ui.theme.typo +import com.maxrave.simpmusic.viewModel.SettingAlertState +import com.maxrave.simpmusic.viewModel.SettingBasicAlertState import com.maxrave.simpmusic.viewModel.SettingsViewModel +import com.maxrave.simpmusic.viewModel.SharedViewModel +import com.mikepenz.aboutlibraries.Libs +import com.mikepenz.aboutlibraries.LibsBuilder import kotlinx.coroutines.flow.map import org.koin.androidx.compose.koinViewModel +import java.text.SimpleDateFormat +import java.time.Instant import java.time.LocalDateTime +import java.time.ZoneId import java.time.format.DateTimeFormatter +import java.util.Locale +import java.util.Scanner -@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class, ExperimentalCoilApi::class) @UnstableApi @Composable fun SettingScreen( innerPadding: PaddingValues, navController: NavController, - viewModel: SettingsViewModel = koinViewModel() + viewModel: SettingsViewModel = koinViewModel(), + sharedViewModel: SharedViewModel = viewModel() ) { val context = LocalContext.current val localDensity = LocalDensity.current @@ -124,6 +156,60 @@ fun SettingScreen( val canvasCache by viewModel.canvasCacheSize.collectAsStateWithLifecycle() val limitPlayerCache by viewModel.playerCacheLimit.collectAsStateWithLifecycle() val fraction by viewModel.fraction.collectAsStateWithLifecycle() + val githubResponse by viewModel.githubResponse.collectAsStateWithLifecycle() + val lastCheckUpdate by viewModel.lastCheckForUpdate.collectAsStateWithLifecycle() + var checkForUpdateSubtitle by rememberSaveable { + mutableStateOf("") + } + var showLibrary by rememberSaveable { + mutableStateOf(false) + } + + LaunchedEffect(lastCheckUpdate) { + val lastCheckLong = lastCheckUpdate?.toLong() ?: 0L + if (lastCheckLong > 0L) { + checkForUpdateSubtitle = context.getString( + R.string.last_checked_at, + DateTimeFormatter + .ofPattern("yyyy-MM-dd HH:mm:ss") + .withZone(ZoneId.systemDefault()) + .format(Instant.ofEpochMilli(lastCheckLong)) + ) + } + } + + LaunchedEffect(githubResponse) { + val res = githubResponse + if (res != null && res.tagName != context.getString(R.string.version_name)) { + val inputFormat = + SimpleDateFormat( + "yyyy-MM-dd'T'HH:mm:ss'Z'", + Locale.getDefault(), + ) + val outputFormat = + SimpleDateFormat("dd MMM yyyy HH:mm:ss", Locale.getDefault()) + val formatted = + res.publishedAt?.let { input -> + inputFormat + .parse(input) + ?.let { outputFormat.format(it) } + } + viewModel.setBasicAlertData( + SettingBasicAlertState( + title = context.getString(R.string.update_available), + message = context.getString(R.string.update_message, res.tagName, formatted, res.body), + confirm = context.getString(R.string.download) to { + uriHandler.openUri( + res.assets?.firstOrNull()?.browserDownloadUrl + ?: "https://github.com/maxrave-dev/SimpMusic/releases" + ) + }, + dismiss = context.getString(R.string.cancel) + ) + ) + } + viewModel.getLastCheckForUpdate() + } LaunchedEffect(true) { viewModel.getData() @@ -157,19 +243,77 @@ fun SettingScreen( ) SettingItem( title = stringResource(R.string.language), - subtitle = language ?: "", - onClick = {} + subtitle = SUPPORTED_LANGUAGE.getLanguageFromCode(language ?: "en-US"), + onClick = { + viewModel.setAlertData( + SettingAlertState( + title = context.getString(R.string.language), + selectOne = SettingAlertState.SelectData( + listSelect = SUPPORTED_LANGUAGE.items.map { + (it.toString() == SUPPORTED_LANGUAGE.getLanguageFromCode(language ?: "en-US")) to it.toString() + } + ), + confirm = context.getString(R.string.change) to { state -> + val code = SUPPORTED_LANGUAGE.getCodeFromLanguage(state.selectOne?.getSelected() ?: "English") + viewModel.setBasicAlertData( + SettingBasicAlertState( + title = context.getString(R.string.warning), + message = context.getString(R.string.change_language_warning), + confirm = context.getString(R.string.change) to { + sharedViewModel.activityRecreate() + viewModel.setBasicAlertData(null) + viewModel.changeLanguage(code) + }, + dismiss = context.getString(R.string.cancel) + ) + ) + }, + dismiss = context.getString(R.string.cancel) + ) + ) + } ) SettingItem( title = stringResource(R.string.content_country), subtitle = location ?: "", - onClick = {} + onClick = { + viewModel.setAlertData( + SettingAlertState( + title = context.getString(R.string.content_country), + selectOne = SettingAlertState.SelectData( + listSelect = SUPPORTED_LOCATION.items.map { item -> + (item.toString() == location) to item.toString() + } + ), + confirm = context.getString(R.string.change) to { state -> + viewModel.changeLocation( + state.selectOne?.getSelected() ?: "US" + ) + } + ) + ) + } ) SettingItem( title = stringResource(R.string.quality), subtitle = quality ?: "", smallSubtitle = true, - onClick = {} + onClick = { + viewModel.setAlertData( + SettingAlertState( + title = context.getString(R.string.quality), + selectOne = SettingAlertState.SelectData( + listSelect = QUALITY.items.map { item -> + (item.toString() == quality) to item.toString() + } + ), + confirm = context.getString(R.string.change) to { state -> + viewModel.changeQuality(state.selectOne?.getSelected()) + }, + dismiss = context.getString(R.string.cancel) + ) + ) + } ) SettingItem( title = stringResource(R.string.home_limit), @@ -261,9 +405,32 @@ fun SettingScreen( Text(text = stringResource(R.string.lyrics), style = typo.labelMedium, modifier = Modifier.padding(vertical = 8.dp)) SettingItem( title = stringResource(R.string.main_lyrics_provider), - subtitle = mainLyricsProvider ?: "", + subtitle = when (mainLyricsProvider) { + DataStoreManager.MUSIXMATCH -> stringResource(R.string.musixmatch) + DataStoreManager.YOUTUBE -> stringResource(R.string.youtube_transcript) + else -> stringResource(R.string.unknown) + }, onClick = { - + viewModel.setAlertData( + SettingAlertState( + title = context.getString(R.string.main_lyrics_provider), + selectOne = SettingAlertState.SelectData( + listSelect = listOf( + (mainLyricsProvider == DataStoreManager.MUSIXMATCH) to context.getString(R.string.musixmatch), + (mainLyricsProvider == DataStoreManager.YOUTUBE) to context.getString(R.string.youtube_transcript) + ) + ), + confirm = context.getString(R.string.change) to { state -> + viewModel.setLyricsProvider( + when (state.selectOne?.getSelected()) { + context.getString(R.string.musixmatch) -> DataStoreManager.MUSIXMATCH + context.getString(R.string.youtube_transcript) -> DataStoreManager.YOUTUBE + else -> DataStoreManager.MUSIXMATCH + } + ) + }, + ) + ) } ) SettingItem( @@ -275,7 +442,7 @@ fun SettingScreen( if (musixmatchLoggedIn) { viewModel.clearMusixmatchCookie() } else { - //TODO: Open musixmatch login page + navController.navigateSafe(R.id.action_global_musixmatchFragment) } } ) @@ -288,7 +455,24 @@ fun SettingScreen( SettingItem( title = stringResource(R.string.translation_language), subtitle = musixmatchTranslationLanguage ?: "", - onClick = {}, + onClick = { + viewModel.setAlertData( + SettingAlertState( + title = context.getString(R.string.translation_language), + textField = SettingAlertState.TextFieldData( + label = context.getString(R.string.translation_language), + value = musixmatchTranslationLanguage ?: "", + verifyCodeBlock = { + (it.length == 2 && it.isTwoLetterCode()) to context.getString(R.string.invalid_language_code) + } + ), + message = context.getString(R.string.translation_language_message), + confirm = context.getString(R.string.change) to { state -> + viewModel.setTranslationLanguage(state.textField?.value ?: "") + }, + ) + ) + }, isEnable = useMusixmatchTranslation ) } @@ -301,7 +485,11 @@ fun SettingScreen( subtitle = if (spotifyLoggedIn) stringResource(R.string.logged_in) else stringResource(R.string.intro_login_to_spotify), onClick = { - + if (spotifyLoggedIn) { + viewModel.setSpotifyLogIn(false) + } else { + navController.navigateSafe(R.id.action_global_spotifyLogInFragment) + } } ) SettingItem( @@ -329,7 +517,38 @@ fun SettingScreen( SettingItem( title = stringResource(R.string.categories_sponsor_block), subtitle = stringResource(R.string.what_segments_will_be_skipped), - onClick = {}, + onClick = { + val listName = SPONSOR_BLOCK.listName.map { + context.getString(it) + } + viewModel.setAlertData( + SettingAlertState( + title = context.getString(R.string.categories_sponsor_block), + multipleSelect = SettingAlertState.SelectData( + listSelect = listName.mapIndexed { index, item -> + (skipSegments?.contains( + SPONSOR_BLOCK.list.getOrNull(index) + ) == true) to item + }.also { + Log.w("SettingScreen", "SettingAlertState: $skipSegments") + Log.w("SettingScreen", "SettingAlertState: $it") + } + ), + confirm = context.getString(R.string.save) to { state -> + viewModel.setSponsorBlockCategories( + state.multipleSelect?.getListSelected()?.map { selected -> + listName.indexOf(selected) + }?.mapNotNull { s -> + SPONSOR_BLOCK.list.getOrNull(s).let { + it?.toString() + } + }?.toCollection(ArrayList()) ?: arrayListOf() + ) + }, + dismiss = context.getString(R.string.cancel) + ) + ) + }, isEnable = enableSponsorBlock ) val beforeUrl = stringResource(R.string.sponsor_block_intro).substringBefore("https://sponsor.ajay.app/") @@ -359,36 +578,86 @@ fun SettingScreen( title = stringResource(R.string.player_cache), subtitle = "${playerCache.bytesToMB()} MB", onClick = { - + viewModel.setBasicAlertData( + SettingBasicAlertState( + title = context.getString(R.string.clear_player_cache), + message = null, + confirm = context.getString(R.string.clear) to { + viewModel.clearPlayerCache() + }, + dismiss = context.getString(R.string.cancel) + ) + ) } ) SettingItem( title = stringResource(R.string.downloaded_cache), subtitle = "${downloadedCache.bytesToMB()} MB", onClick = { - + viewModel.setBasicAlertData( + SettingBasicAlertState( + title = context.getString(R.string.clear_downloaded_cache), + message = null, + confirm = context.getString(R.string.clear) to { + viewModel.clearDownloadedCache() + }, + dismiss = context.getString(R.string.cancel) + ) + ) } ) SettingItem( title = stringResource(R.string.thumbnail_cache), subtitle = "${thumbnailCache.bytesToMB()} MB", onClick = { - + viewModel.setBasicAlertData( + SettingBasicAlertState( + title = context.getString(R.string.clear_thumbnail_cache), + message = null, + confirm = context.getString(R.string.clear) to { + viewModel.clearThumbnailCache() + }, + dismiss = context.getString(R.string.cancel) + ) + ) } ) SettingItem( title = stringResource(R.string.spotify_canvas_cache), subtitle = "${canvasCache.bytesToMB()} MB", onClick = { - + viewModel.setBasicAlertData( + SettingBasicAlertState( + title = context.getString(R.string.clear_canvas_cache), + message = null, + confirm = context.getString(R.string.clear) to { + viewModel.clearCanvasCache() + }, + dismiss = context.getString(R.string.cancel) + ) + ) } ) SettingItem( title = stringResource(R.string.limit_player_cache), - subtitle = if (limitPlayerCache != -1) "${limitPlayerCache} MB" - else stringResource(R.string.unlimited), + subtitle = LIMIT_CACHE_SIZE.getItemFromData(limitPlayerCache).toString(), onClick = { - + viewModel.setAlertData( + SettingAlertState( + title = context.getString(R.string.limit_player_cache), + selectOne = SettingAlertState.SelectData( + listSelect = LIMIT_CACHE_SIZE.items.map { item -> + (item == LIMIT_CACHE_SIZE.getItemFromData(limitPlayerCache)) to item.toString() + } + ), + confirm = context.getString(R.string.change) to { state -> + viewModel.setPlayerCacheLimit( + LIMIT_CACHE_SIZE.getDataFromItem(state.selectOne?.getSelected()) + ) + }, + dismiss = context.getString(R.string.cancel) + ) + ) } ) Box( @@ -593,14 +862,15 @@ fun SettingScreen( title = stringResource(R.string.version), subtitle = stringResource(R.string.version_name), onClick = { - + navController.navigateSafe(R.id.action_global_creditFragment) } ) SettingItem( title = stringResource(R.string.check_for_update), - + subtitle = checkForUpdateSubtitle, onClick = { - + checkForUpdateSubtitle = context.getString(R.string.checking) + viewModel.checkForUpdate() } ) SettingItem( @@ -621,7 +891,25 @@ fun SettingScreen( title = stringResource(R.string.third_party_libraries), subtitle = stringResource(R.string.description_and_licenses), onClick = { - + val inputStream = context.resources.openRawResource(R.raw.aboutlibraries) + val scanner = Scanner(inputStream).useDelimiter("\\A") + val stringBuilder = StringBuilder() + while (scanner.hasNextLine()) { + stringBuilder.append(scanner.nextLine()) + } + Log.w("AboutLibraries", stringBuilder.toString()) + val localLib = Libs.Builder().withJson(stringBuilder.toString()).build() + val intent = + LibsBuilder() + .withLicenseShown(true) + .withVersionShown(true) + .withActivityTitle(context.getString(R.string.third_party_libraries)) + .withSearchEnabled(true) + .withEdgeToEdge(true) + .withLibs( + localLib, + ).intent(context) + context.startActivity(intent) } ) } @@ -630,6 +918,178 @@ fun SettingScreen( EndOfPage() } } + val basisAlertData by viewModel.basicAlertData.collectAsStateWithLifecycle() + if (basisAlertData != null) { + val alertBasicState = basisAlertData ?: return + AlertDialog( + onDismissRequest = { viewModel.setBasicAlertData(null) }, + title = { + Text(text = alertBasicState.title) + }, + text = { + if (alertBasicState.message != null) { + Text(text = alertBasicState.message) + } + }, + confirmButton = { + TextButton( + onClick = { + alertBasicState.confirm.second.invoke() + viewModel.setBasicAlertData(null) + } + ) { + Text(text = alertBasicState.confirm.first) + } + }, + dismissButton = { + TextButton( + onClick = { + viewModel.setBasicAlertData(null) + } + ) { + Text(text = alertBasicState.dismiss) + } + } + ) + } + val alertData by viewModel.alertData.collectAsStateWithLifecycle() + if (alertData != null) { + val alertState = alertData ?: return + //AlertDialog + AlertDialog( + onDismissRequest = { viewModel.setAlertData(null) }, + title = { + Text(text = alertState.title) + }, + text = { + if (alertState.message != null) { + Column { + Text(text = alertState.message) + if (alertState.textField != null) { + val verify = alertState.textField.verifyCodeBlock?.invoke( + alertState.textField.value + ) ?: (true to null) + TextField( + value = alertState.textField.value, + onValueChange = { + viewModel.setAlertData( + alertState.copy( + textField = alertState.textField.copy( + value = it + ) + ) + ) + }, + isError = !verify.first, + label = { Text(text = alertState.textField.label) }, + supportingText = { + if (!verify.first) { + Text( + modifier = Modifier.fillMaxWidth(), + text = stringResource(R.string.invalid_language_code), + color = DarkColors.error + ) + } + }, + trailingIcon = { + if (!verify.first) { + Icons.Outlined.Error + } + }, + modifier = Modifier.fillMaxWidth().padding( + vertical = 6.dp + ) + ) + } + } + } else if (alertState.selectOne != null) { + LazyColumn( + Modifier.padding(vertical = 6.dp) + .heightIn(0.dp, 500.dp) + ) { + items(alertState.selectOne.listSelect) { item -> + Row(Modifier.padding(vertical = 4.dp), verticalAlignment = Alignment.CenterVertically) { + RadioButton( + selected = item.first, + onClick = { + viewModel.setAlertData( + alertState.copy( + selectOne = alertState.selectOne.copy( + listSelect = alertState.selectOne.listSelect.toMutableList().map { + if (it == item) { + true to it.second + } else { + false to it.second + } + } + ) + ) + ) + } + ) + Spacer(Modifier.width(8.dp)) + Text(text = item.second, style = typo.bodyMedium, maxLines = 1) + } + } + } + } else if (alertState.multipleSelect != null) { + LazyColumn( + Modifier.padding(vertical = 6.dp) + ) { + items(alertState.multipleSelect.listSelect) { item -> + Row(Modifier.padding(vertical = 4.dp), verticalAlignment = Alignment.CenterVertically) { + Checkbox( + checked = item.first, + onCheckedChange = { + viewModel.setAlertData( + alertState.copy( + multipleSelect = alertState.multipleSelect.copy( + listSelect = alertState.multipleSelect.listSelect.toMutableList().map { + if (it == item) { + !it.first to it.second + } else { + it + } + } + ) + ) + ) + } + ) + Spacer(Modifier.width(8.dp)) + Text(text = item.second, style = typo.bodyMedium, maxLines = 1) + } + } + } + } + }, + confirmButton = { + TextButton( + onClick = { + alertState.confirm.second.invoke(alertState) + viewModel.setAlertData(null) + }, + enabled = if (alertState.textField?.verifyCodeBlock != null) { + alertState.textField.verifyCodeBlock.invoke( + alertState.textField.value + ).first + } else true + ) { + Text(text = alertState.confirm.first) + } + }, + dismissButton = { + TextButton( + onClick = { + viewModel.setAlertData(null) + } + ) { + Text(text = alertState.dismiss) + } + } + ) + } + TopAppBar( title = { Text( diff --git a/app/src/main/java/com/maxrave/simpmusic/ui/theme/Theme.kt b/app/src/main/java/com/maxrave/simpmusic/ui/theme/Theme.kt index 52062ff7..2ab65ab0 100644 --- a/app/src/main/java/com/maxrave/simpmusic/ui/theme/Theme.kt +++ b/app/src/main/java/com/maxrave/simpmusic/ui/theme/Theme.kt @@ -19,7 +19,7 @@ import coil3.request.crossfade import coil3.util.DebugLogger import okio.FileSystem -private val DarkColors = +val DarkColors = darkColorScheme( primary = md_theme_dark_primary, onPrimary = md_theme_dark_onPrimary, diff --git a/app/src/main/java/com/maxrave/simpmusic/viewModel/SettingsViewModel.kt b/app/src/main/java/com/maxrave/simpmusic/viewModel/SettingsViewModel.kt index 017afc13..adc62351 100644 --- a/app/src/main/java/com/maxrave/simpmusic/viewModel/SettingsViewModel.kt +++ b/app/src/main/java/com/maxrave/simpmusic/viewModel/SettingsViewModel.kt @@ -4,9 +4,12 @@ import android.app.Application import android.app.usage.StorageStatsManager import android.content.Intent import android.net.Uri +import android.os.Build import android.os.storage.StorageManager import android.util.Log import android.widget.Toast +import androidx.appcompat.app.AppCompatDelegate +import androidx.core.os.LocaleListCompat import androidx.lifecycle.viewModelScope import androidx.media3.common.util.UnstableApi import androidx.media3.datasource.cache.SimpleCache @@ -110,6 +113,12 @@ class SettingsViewModel( private var _translucentBottomBar: MutableStateFlow = MutableStateFlow(null) val translucentBottomBar: StateFlow = _translucentBottomBar + private var _alertData: MutableStateFlow = MutableStateFlow(null) + val alertData: StateFlow = _alertData + + private var _basicAlertData: MutableStateFlow = MutableStateFlow(null) + val basicAlertData: StateFlow = _basicAlertData + // Fraction of storage private var _fraction: MutableStateFlow = MutableStateFlow( SettingsStorageSectionFraction() @@ -154,6 +163,14 @@ class SettingsViewModel( _canvasCacheSize.value = canvasCache.cacheSpace } + fun setAlertData(alertData: SettingAlertState?) { + _alertData.value = alertData + } + + fun setBasicAlertData(alertData: SettingBasicAlertState?) { + _basicAlertData.value = alertData + } + private fun calculateDataFraction() { val mStorageStatsManager = application.getSystemService(StorageStatsManager::class.java) @@ -288,6 +305,9 @@ class SettingsViewModel( "CheckForUpdateAt", System.currentTimeMillis().toString(), ) + if (response?.tagName == getString(R.string.version_name)) { + makeToast(getString(R.string.no_update)) + } _githubResponse.emit(response) } } @@ -328,6 +348,7 @@ class SettingsViewModel( fun getLastCheckForUpdate() { viewModelScope.launch { dataStoreManager.getString("CheckForUpdateAt").first().let { lastCheckForUpdate -> + _githubResponse.emit(null) _lastCheckForUpdate.emit(lastCheckForUpdate) } } @@ -366,14 +387,18 @@ class SettingsViewModel( fun getSponsorBlockCategories() { viewModelScope.launch { dataStoreManager.getSponsorBlockCategories().let { + log("getSponsorBlockCategories: $it", Log.WARN) _sponsorBlockCategories.emit(it) } } } fun setSponsorBlockCategories(list: ArrayList) { + log("setSponsorBlockCategories: $list", Log.WARN) viewModelScope.launch { - dataStoreManager.setSponsorBlockCategories(list) + runBlocking(Dispatchers.IO) { + dataStoreManager.setSponsorBlockCategories(list) + } getSponsorBlockCategories() } } @@ -402,12 +427,9 @@ class SettingsViewModel( } } - fun changeQuality(checkedIndex: Int) { + fun changeQuality(qualityItem: String?) { viewModelScope.launch { - when (checkedIndex) { - 0 -> dataStoreManager.setQuality(QUALITY.items[0].toString()) - 1 -> dataStoreManager.setQuality(QUALITY.items[1].toString()) - } + dataStoreManager.setQuality(qualityItem ?: QUALITY.items.first().toString()) getQuality() } } @@ -426,7 +448,7 @@ class SettingsViewModel( playerCache.keys.forEach { key -> playerCache.removeResource(key) } - Toast.makeText(getApplication(), "Player cache cleared", Toast.LENGTH_SHORT).show() + makeToast(getString(R.string.clear_player_cache)) _cacheSize.value = playerCache.cacheSpace } } @@ -450,12 +472,23 @@ class SettingsViewModel( mainRepository.updateDownloadState(song.videoId, DownloadState.STATE_NOT_DOWNLOADED) } } - Toast.makeText(getApplication(), "Download cache cleared", Toast.LENGTH_SHORT).show() + makeToast(getString(R.string.clear_downloaded_cache)) _cacheSize.value = playerCache.cacheSpace downloadUtils.removeAllDownloads() } } + @UnstableApi + fun clearCanvasCache() { + viewModelScope.launch { + canvasCache.keys.forEach { key -> + canvasCache.removeResource(key) + } + makeToast(getString(R.string.clear_canvas_cache)) + _canvasCacheSize.value = canvasCache.cacheSpace + } + } + fun backup( uri: Uri ) { @@ -540,6 +573,20 @@ class SettingsViewModel( Log.w("SettingsViewModel", "changeLanguage: $code") YouTube.locale = YouTubeLocale(location.value!!, code.substring(0..1)) getLanguage() + val localeList = + LocaleListCompat.forLanguageTags( + if (code == "id-ID") { + if (Build.VERSION.SDK_INT >= 35) { + "id-ID" + } else { + "in-ID" + } + } else { + code + }, + ) + Log.d("Language", localeList.toString()) + AppCompatDelegate.setApplicationLocales(localeList) } } @@ -625,6 +672,7 @@ class SettingsViewModel( dataStoreManager.setMusixmatchCookie("") YouTube.musixMatchCookie = null dataStoreManager.setMusixmatchLoggedIn(false) + makeToast(getString(R.string.logged_out)) } } @@ -884,4 +932,40 @@ data class SettingsStorageSectionFraction( fun combine(): Float { return otherApp + downloadCache + playerCache + canvasCache + thumbCache + appDatabase + freeSpace } -} \ No newline at end of file +} + + +data class SettingAlertState( + val title: String, + val message: String? = null, + val textField: TextFieldData? = null, + val selectOne: SelectData? = null, + val multipleSelect: SelectData? = null, + val confirm: Pair Unit>, + val dismiss: String = "Cancel", +) { + data class TextFieldData( + val label: String, + val value: String = "", + // User typing string -> (true or false, If false, show error message) + val verifyCodeBlock: ((String) -> Pair)? = null, + ) + data class SelectData( + // Selected / Data + val listSelect: List> + ) { + fun getSelected(): String { + return listSelect.firstOrNull { it.first }?.second ?: "" + } + fun getListSelected(): List { + return listSelect.filter { it.first }.map { it.second } + } + } +} + +data class SettingBasicAlertState( + val title: String, + val message: String? = null, + val confirm: Pair Unit>, + val dismiss: String = "Cancel", +) \ No newline at end of file diff --git a/app/src/main/res/raw/aboutlibraries.json b/app/src/main/res/raw/aboutlibraries.json index 1a815fb6..24c5b76b 100644 --- a/app/src/main/res/raw/aboutlibraries.json +++ b/app/src/main/res/raw/aboutlibraries.json @@ -13,14 +13,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.9.1", + "artifactVersion": "1.9.3", "description": "Provides the base Activity subclass and the relevant hooks to build a composable structure on top.", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Activity", - "website": "https://developer.android.com/jetpack/androidx/releases/activity#1.9.1", + "website": "https://developer.android.com/jetpack/androidx/releases/activity#1.9.3", "licenses": [ "Apache-2.0" ], @@ -38,14 +38,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.9.1", + "artifactVersion": "1.9.3", "description": "Compose integration with Activity", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Activity Compose", - "website": "https://developer.android.com/jetpack/androidx/releases/activity#1.9.1", + "website": "https://developer.android.com/jetpack/androidx/releases/activity#1.9.3", "licenses": [ "Apache-2.0" ], @@ -63,14 +63,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.9.1", + "artifactVersion": "1.9.3", "description": "Kotlin extensions for 'activity' artifact", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Activity Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/activity#1.9.1", + "website": "https://developer.android.com/jetpack/androidx/releases/activity#1.9.3", "licenses": [ "Apache-2.0" ], @@ -88,14 +88,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.4.1", "description": "Java annotation for use on unstable Android API surfaces. When used in conjunction with the Experimental annotation lint checks, this annotation provides functional parity with Kotlin's Experimental annotation.", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Experimental annotation", - "website": "https://developer.android.com/jetpack/androidx/releases/annotation#1.4.0", + "website": "https://developer.android.com/jetpack/androidx/releases/annotation#1.4.1", "licenses": [ "Apache-2.0" ], @@ -113,14 +113,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.8.1", + "artifactVersion": "1.9.1", "description": "Provides source annotations for tooling and readability.", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Annotation", - "website": "https://developer.android.com/jetpack/androidx/releases/annotation#1.8.1", + "website": "https://developer.android.com/jetpack/androidx/releases/annotation#1.9.1", "licenses": [ "Apache-2.0" ], @@ -298,14 +298,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.4.4", "description": "Standalone efficient collections.", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "collections", - "website": "https://developer.android.com/jetpack/androidx/releases/collection#1.4.0", + "website": "https://developer.android.com/jetpack/androidx/releases/collection#1.4.4", "licenses": [ "Apache-2.0" ], @@ -323,14 +323,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.4.4", "description": "Kotlin extensions for 'collection' artifact", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Collections Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/collection#1.4.0", + "website": "https://developer.android.com/jetpack/androidx/releases/collection#1.4.4", "licenses": [ "Apache-2.0" ], @@ -348,14 +348,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Compose animation library", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Animation", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-animation#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-animation#1.7.5", "licenses": [ "Apache-2.0" ], @@ -373,14 +373,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Animation engine and animation primitives that are the building blocks of the Compose animation library", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Animation Core", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-animation#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-animation#1.7.5", "licenses": [ "Apache-2.0" ], @@ -398,14 +398,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Higher level abstractions of the Compose UI primitives. This library is design system agnostic, providing the high-level building blocks for both application and design-system developers", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Foundation", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.7.5", "licenses": [ "Apache-2.0" ], @@ -423,14 +423,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Compose layout implementations", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Layouts", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.7.5", "licenses": [ "Apache-2.0" ], @@ -448,14 +448,39 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.2.1", + "artifactVersion": "1.3.1", "description": "Compose Material You Design Components library", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Material3 Components", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-material3#1.2.1", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-material3#1.3.1", + "licenses": [ + "Apache-2.0" + ], + "organization": { + "name": "The Android Open Source Project" + } + }, + { + "uniqueId": "androidx.compose.material3:material3-window-size-class-android", + "funding": [ + + ], + "developers": [ + { + "name": "The Android Open Source Project" + } + ], + "artifactVersion": "1.3.1", + "description": "Provides window size classes for building responsive UIs", + "scm": { + "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", + "url": "https://cs.android.com/androidx/platform/frameworks/support" + }, + "name": "Compose Material 3 Window Size Class", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-material3#1.3.1", "licenses": [ "Apache-2.0" ], @@ -473,14 +498,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Compose Material Design Components library", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Material Components", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-material#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-material#1.7.5", "licenses": [ "Apache-2.0" ], @@ -498,14 +523,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Compose Material Design core icons. This module contains the most commonly used set of Material icons.", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Material Icons Core", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-material#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-material#1.7.5", "licenses": [ "Apache-2.0" ], @@ -523,14 +548,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Compose Material Design extended icons. This module contains all Material icons. It is a very large dependency and should not be included directly.", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Material Icons Extended", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-material#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-material#1.7.5", "licenses": [ "Apache-2.0" ], @@ -548,14 +573,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Material ripple used to build interactive components", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Material Ripple", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-material#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-material#1.7.5", "licenses": [ "Apache-2.0" ], @@ -573,14 +598,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Tree composition support for code generated by the Compose compiler plugin and corresponding public API", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Runtime", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.7.5", "licenses": [ "Apache-2.0" ], @@ -598,14 +623,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Compose components that allow saving and restoring the local ui state", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Saveable", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.7.5", "licenses": [ "Apache-2.0" ], @@ -623,14 +648,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Compose UI primitives. This library contains the primitives that form the Compose UI Toolkit, such as drawing, measurement and layout.", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose UI", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.5", "licenses": [ "Apache-2.0" ], @@ -648,14 +673,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Compose classes related to dimensions without units", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Geometry", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.5", "licenses": [ "Apache-2.0" ], @@ -673,14 +698,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Compose graphics", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Graphics", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.5", "licenses": [ "Apache-2.0" ], @@ -698,14 +723,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Compose Text primitives and utilities", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose UI Text", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.5", "licenses": [ "Apache-2.0" ], @@ -723,14 +748,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Compose tooling library API. This library provides the API required to declare @Preview composables in user apps.", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose UI Preview Tooling", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.5", "licenses": [ "Apache-2.0" ], @@ -748,14 +773,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Compose classes for simple units", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Unit", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.5", "licenses": [ "Apache-2.0" ], @@ -773,14 +798,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.6.8", + "artifactVersion": "1.7.5", "description": "Internal Compose utilities used by other modules", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Compose Util", - "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.6.8", + "website": "https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.5", "licenses": [ "Apache-2.0" ], @@ -796,7 +821,7 @@ "developers": [ ], - "artifactVersion": "2024.06.00", + "artifactVersion": "2024.11.00", "description": "A compatible set of Jetpack Compose libraries.", "name": "Jetpack Compose Libraries BOM", "website": "https://developer.android.com/jetpack", @@ -827,7 +852,7 @@ ] }, { - "uniqueId": "androidx.constraintlayout:constraintlayout", + "uniqueId": "androidx.concurrent:concurrent-futures-ktx", "funding": [ ], @@ -836,20 +861,20 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.1.4", - "description": "ConstraintLayout for Android", + "artifactVersion": "1.1.0", + "description": "Kotlin Extensions for Androidx implementation of Guava's ListenableFuture", "scm": { - "connection": "git@github.com:androidx/constraintlayout.git", - "url": "https://github.com/androidx/constraintlayout" + "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", + "url": "http://source.android.com" }, - "name": "Android ConstraintLayout", - "website": "http://tools.android.com", + "name": "AndroidX Futures Kotlin Extensions", + "website": "https://developer.android.com/topic/libraries/architecture/index.html", "licenses": [ "Apache-2.0" ] }, { - "uniqueId": "androidx.constraintlayout:constraintlayout-compose", + "uniqueId": "androidx.constraintlayout:constraintlayout", "funding": [ ], @@ -858,17 +883,45 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.0.1", - "description": "ConstraintLayout for Jetpack Compose", + "artifactVersion": "2.2.0", + "description": "This library offers a flexible and adaptable way to position and animate widgets", "scm": { - "connection": "git@github.com:androidx/constraintlayout.git", - "url": "https://github.com/androidx/constraintlayout" + "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", + "url": "https://cs.android.com/androidx/platform/frameworks/support" }, - "name": "ConstraintLayout for Jetpack Compose", - "website": "http://tools.android.com", + "name": "ConstraintLayout", + "website": "https://developer.android.com/jetpack/androidx/releases/constraintlayout#2.2.0", "licenses": [ "Apache-2.0" - ] + ], + "organization": { + "name": "The Android Open Source Project" + } + }, + { + "uniqueId": "androidx.constraintlayout:constraintlayout-compose-android", + "funding": [ + + ], + "developers": [ + { + "name": "The Android Open Source Project" + } + ], + "artifactVersion": "1.1.0", + "description": "This library offers a flexible and adaptable way to position and animate widgets in Compose", + "scm": { + "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", + "url": "https://cs.android.com/androidx/platform/frameworks/support" + }, + "name": "ConstraintLayout Compose", + "website": "https://developer.android.com/jetpack/androidx/releases/constraintlayout#1.1.0", + "licenses": [ + "Apache-2.0" + ], + "organization": { + "name": "The Android Open Source Project" + } }, { "uniqueId": "androidx.constraintlayout:constraintlayout-core", @@ -880,17 +933,20 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.0.4", - "description": "ConstraintLayout core", + "artifactVersion": "1.1.0", + "description": "This library contains engines and algorithms for constraint based layout and complex animations (it is used by the ConstraintLayout library)", "scm": { - "connection": "git@github.com:androidx/constraintlayout.git", - "url": "https://github.com/androidx/constraintlayout" + "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", + "url": "https://cs.android.com/androidx/platform/frameworks/support" }, - "name": "Android ConstraintLayout Core", - "website": "http://tools.android.com", + "name": "ConstraintLayout Core", + "website": "https://developer.android.com/jetpack/androidx/releases/constraintlayout#1.1.0", "licenses": [ "Apache-2.0" - ] + ], + "organization": { + "name": "The Android Open Source Project" + } }, { "uniqueId": "androidx.coordinatorlayout:coordinatorlayout", @@ -924,14 +980,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.13.1", + "artifactVersion": "1.15.0", "description": "Provides backward-compatible implementations of Android platform APIs and features.", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Core", - "website": "https://developer.android.com/jetpack/androidx/releases/core#1.13.1", + "website": "https://developer.android.com/jetpack/androidx/releases/core#1.15.0", "licenses": [ "Apache-2.0" ], @@ -949,14 +1005,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.13.1", + "artifactVersion": "1.15.0", "description": "Kotlin extensions for 'core' artifact", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Core Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/core#1.13.1", + "website": "https://developer.android.com/jetpack/androidx/releases/core#1.15.0", "licenses": [ "Apache-2.0" ], @@ -1105,7 +1161,7 @@ "developers": [ ], - "artifactVersion": "8.5.2", + "artifactVersion": "8.7.3", "description": "", "name": "androidx.databinding:viewbinding", "licenses": [ @@ -1379,14 +1435,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.8.2", + "artifactVersion": "1.8.5", "description": "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later.", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "fragment", - "website": "https://developer.android.com/jetpack/androidx/releases/fragment#1.8.2", + "website": "https://developer.android.com/jetpack/androidx/releases/fragment#1.8.5", "licenses": [ "Apache-2.0" ], @@ -1404,39 +1460,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.8.2", + "artifactVersion": "1.8.5", "description": "Kotlin extensions for 'fragment' artifact", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Fragment Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/fragment#1.8.2", - "licenses": [ - "Apache-2.0" - ], - "organization": { - "name": "The Android Open Source Project" - } - }, - { - "uniqueId": "androidx.hilt:hilt-common", - "funding": [ - - ], - "developers": [ - { - "name": "The Android Open Source Project" - } - ], - "artifactVersion": "1.2.0", - "description": "AndroidX Hilt Extension Annotations", - "scm": { - "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", - "url": "https://cs.android.com/androidx/platform/frameworks/support" - }, - "name": "Hilt Common", - "website": "https://developer.android.com/jetpack/androidx/releases/hilt#1.2.0", + "website": "https://developer.android.com/jetpack/androidx/releases/fragment#1.8.5", "licenses": [ "Apache-2.0" ], @@ -1445,7 +1476,7 @@ } }, { - "uniqueId": "androidx.hilt:hilt-work", + "uniqueId": "androidx.graphics:graphics-path", "funding": [ ], @@ -1454,14 +1485,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.2.0", - "description": "Android Lifecycle WorkManager Hilt Extension", + "artifactVersion": "1.0.1", + "description": "Query segment data for android.graphics.Path objects", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, - "name": "WorkManager Hilt Extension", - "website": "https://developer.android.com/jetpack/androidx/releases/hilt#1.2.0", + "name": "Android Graphics Path", + "website": "https://developer.android.com/jetpack/androidx/releases/graphics#1.0.1", "licenses": [ "Apache-2.0" ], @@ -1567,14 +1598,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Android Lifecycle-Common for Java 8 Language", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle-Common for Java 8", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1592,14 +1623,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Android Lifecycle-Common", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle-Common", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1639,14 +1670,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Android Lifecycle LiveData", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle LiveData", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1664,14 +1695,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Android Lifecycle LiveData Core", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle LiveData Core", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1689,14 +1720,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Kotlin extensions for 'livedata-core' artifact", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "LiveData Core Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1714,14 +1745,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Kotlin extensions for 'livedata' artifact", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "LiveData Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1739,14 +1770,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Android Lifecycle Process", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle Process", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1764,14 +1795,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Android Lifecycle Runtime", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle Runtime", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1789,14 +1820,39 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Android Lifecycle Runtime", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle Runtime", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", + "licenses": [ + "Apache-2.0" + ], + "organization": { + "name": "The Android Open Source Project" + } + }, + { + "uniqueId": "androidx.lifecycle:lifecycle-runtime-compose-android", + "funding": [ + + ], + "developers": [ + { + "name": "The Android Open Source Project" + } + ], + "artifactVersion": "2.8.7", + "description": "Compose integration with Lifecycle", + "scm": { + "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", + "url": "https://cs.android.com/androidx/platform/frameworks/support" + }, + "name": "Lifecycle Runtime Compose", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1814,14 +1870,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Kotlin extensions for 'lifecycle' artifact", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1839,14 +1895,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Android Lifecycle Service", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle Service", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1864,14 +1920,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Android Lifecycle ViewModel", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle ViewModel", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1889,14 +1945,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Android Lifecycle ViewModel", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle ViewModel", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1914,14 +1970,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Compose integration with Lifecycle ViewModel", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle ViewModel Compose", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1939,14 +1995,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Kotlin extensions for 'viewmodel' artifact", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle ViewModel Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -1964,14 +2020,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.8.4", + "artifactVersion": "2.8.7", "description": "Android Lifecycle ViewModel", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Lifecycle ViewModel with SavedState", - "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4", + "website": "https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.7", "licenses": [ "Apache-2.0" ], @@ -2033,7 +2089,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 common module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2054,7 +2110,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 Container module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2075,7 +2131,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 database module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2096,7 +2152,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 DataSource module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2117,7 +2173,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 OkHttp DataSource module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2138,7 +2194,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 decoder module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2159,7 +2215,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 ExoPlayer module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2180,7 +2236,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 ExoPlayer DASH module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2201,7 +2257,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 ExoPlayer HLS module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2222,7 +2278,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 ExoPlayer RTSP module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2243,7 +2299,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 ExoPlayer SmoothStreaming module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2264,7 +2320,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 ExoPlayer WorkManager module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2285,7 +2341,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 Extractor module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2306,7 +2362,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 Session module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2327,7 +2383,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.0", + "artifactVersion": "1.5.0", "description": "Media3 UI module", "scm": { "connection": "scm:git:https://github.com/androidx/media.git", @@ -2373,17 +2429,20 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.7.7", + "artifactVersion": "2.8.4", "description": "Android Navigation-Common", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Navigation Common", - "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.7.7", + "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.8.4", "licenses": [ "Apache-2.0" - ] + ], + "organization": { + "name": "The Android Open Source Project" + } }, { "uniqueId": "androidx.navigation:navigation-common-ktx", @@ -2395,17 +2454,20 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.7.7", + "artifactVersion": "2.8.4", "description": "Android Navigation-Common-Ktx", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Navigation Common Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.7.7", + "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.8.4", "licenses": [ "Apache-2.0" - ] + ], + "organization": { + "name": "The Android Open Source Project" + } }, { "uniqueId": "androidx.navigation:navigation-fragment", @@ -2417,17 +2479,20 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.7.7", + "artifactVersion": "2.8.4", "description": "Android Navigation-Fragment", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Navigation Fragment", - "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.7.7", + "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.8.4", "licenses": [ "Apache-2.0" - ] + ], + "organization": { + "name": "The Android Open Source Project" + } }, { "uniqueId": "androidx.navigation:navigation-fragment-ktx", @@ -2439,17 +2504,20 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.7.7", + "artifactVersion": "2.8.4", "description": "Android Navigation-Fragment-Ktx", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Navigation Fragment Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.7.7", + "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.8.4", "licenses": [ "Apache-2.0" - ] + ], + "organization": { + "name": "The Android Open Source Project" + } }, { "uniqueId": "androidx.navigation:navigation-runtime", @@ -2461,17 +2529,20 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.7.7", + "artifactVersion": "2.8.4", "description": "Android Navigation-Runtime", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Navigation Runtime", - "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.7.7", + "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.8.4", "licenses": [ "Apache-2.0" - ] + ], + "organization": { + "name": "The Android Open Source Project" + } }, { "uniqueId": "androidx.navigation:navigation-runtime-ktx", @@ -2483,17 +2554,20 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.7.7", + "artifactVersion": "2.8.4", "description": "Android Navigation-Runtime-Ktx", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Navigation Runtime Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.7.7", + "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.8.4", "licenses": [ "Apache-2.0" - ] + ], + "organization": { + "name": "The Android Open Source Project" + } }, { "uniqueId": "androidx.navigation:navigation-ui", @@ -2505,17 +2579,20 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.7.7", + "artifactVersion": "2.8.4", "description": "Android Navigation-UI", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Navigation UI", - "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.7.7", + "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.8.4", "licenses": [ "Apache-2.0" - ] + ], + "organization": { + "name": "The Android Open Source Project" + } }, { "uniqueId": "androidx.navigation:navigation-ui-ktx", @@ -2527,17 +2604,20 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.7.7", + "artifactVersion": "2.8.4", "description": "Android Navigation-UI-Ktx", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Navigation UI Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.7.7", + "website": "https://developer.android.com/jetpack/androidx/releases/navigation#2.8.4", "licenses": [ "Apache-2.0" - ] + ], + "organization": { + "name": "The Android Open Source Project" + } }, { "uniqueId": "androidx.paging:paging-common-android", @@ -2549,14 +2629,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "3.3.2", + "artifactVersion": "3.3.4", "description": "Android Paging-Common", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Paging-Common", - "website": "https://developer.android.com/jetpack/androidx/releases/paging#3.3.2", + "website": "https://developer.android.com/jetpack/androidx/releases/paging#3.3.4", "licenses": [ "Apache-2.0" ], @@ -2574,14 +2654,39 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "3.3.2", + "artifactVersion": "3.3.4", "description": "Kotlin extensions for 'paging-common' artifact", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Paging-Common Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/paging#3.3.2", + "website": "https://developer.android.com/jetpack/androidx/releases/paging#3.3.4", + "licenses": [ + "Apache-2.0" + ], + "organization": { + "name": "The Android Open Source Project" + } + }, + { + "uniqueId": "androidx.paging:paging-compose-android", + "funding": [ + + ], + "developers": [ + { + "name": "The Android Open Source Project" + } + ], + "artifactVersion": "3.3.4", + "description": "Compose integration with Paging", + "scm": { + "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", + "url": "https://cs.android.com/androidx/platform/frameworks/support" + }, + "name": "Paging-Compose", + "website": "https://developer.android.com/jetpack/androidx/releases/paging#3.3.4", "licenses": [ "Apache-2.0" ], @@ -2599,14 +2704,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "3.3.2", + "artifactVersion": "3.3.4", "description": "Android Paging-Runtime", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Paging-Runtime", - "website": "https://developer.android.com/jetpack/androidx/releases/paging#3.3.2", + "website": "https://developer.android.com/jetpack/androidx/releases/paging#3.3.4", "licenses": [ "Apache-2.0" ], @@ -2624,14 +2729,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "3.3.2", + "artifactVersion": "3.3.4", "description": "Kotlin extensions for 'paging-runtime' artifact", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Paging-Runtime Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/paging#3.3.2", + "website": "https://developer.android.com/jetpack/androidx/releases/paging#3.3.4", "licenses": [ "Apache-2.0" ], @@ -2759,17 +2864,20 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.3.1", + "artifactVersion": "1.4.1", "description": "Allows libraries to prepopulate ahead of time compilation traces to be read by ART", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, - "name": "androidx.profileinstaller:profileinstaller", - "website": "https://developer.android.com/jetpack/androidx/releases/profileinstaller#1.3.1", + "name": "Profile Installer", + "website": "https://developer.android.com/jetpack/androidx/releases/profileinstaller#1.4.1", "licenses": [ "Apache-2.0" - ] + ], + "organization": { + "name": "The Android Open Source Project" + } }, { "uniqueId": "androidx.recyclerview:recyclerview", @@ -3001,17 +3109,20 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.1.1", + "artifactVersion": "1.2.0", "description": "Android App Startup Runtime", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, - "name": "Android App Startup Runtime", - "website": "https://developer.android.com/jetpack/androidx/releases/startup#1.1.1", + "name": "Startup Runtime", + "website": "https://developer.android.com/jetpack/androidx/releases/startup#1.2.0", "licenses": [ "Apache-2.0" - ] + ], + "organization": { + "name": "The Android Open Source Project" + } }, { "uniqueId": "androidx.swiperefreshlayout:swiperefreshlayout", @@ -3045,14 +3156,36 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.0.0", + "artifactVersion": "1.2.0", "description": "Android Tracing", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "Android Tracing", - "website": "https://developer.android.com/jetpack/androidx/releases/tracing#1.0.0", + "website": "https://developer.android.com/jetpack/androidx/releases/tracing#1.2.0", + "licenses": [ + "Apache-2.0" + ] + }, + { + "uniqueId": "androidx.tracing:tracing-ktx", + "funding": [ + + ], + "developers": [ + { + "name": "The Android Open Source Project" + } + ], + "artifactVersion": "1.2.0", + "description": "Android Tracing", + "scm": { + "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", + "url": "https://cs.android.com/androidx/platform/frameworks/support" + }, + "name": "Android Tracing Runtime Kotlin Extensions", + "website": "https://developer.android.com/jetpack/androidx/releases/tracing#1.2.0", "licenses": [ "Apache-2.0" ] @@ -3067,17 +3200,20 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.4.1", + "artifactVersion": "1.5.0", "description": "Android Transition Support Library", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, - "name": "Android Transition Support Library", - "website": "https://developer.android.com/jetpack/androidx/releases/transition#1.4.1", + "name": "Transition", + "website": "https://developer.android.com/jetpack/androidx/releases/transition#1.5.0", "licenses": [ "Apache-2.0" - ] + ], + "organization": { + "name": "The Android Open Source Project" + } }, { "uniqueId": "androidx.vectordrawable:vectordrawable", @@ -3221,14 +3357,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.9.1", + "artifactVersion": "2.10.0", "description": "Android WorkManager runtime library", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "WorkManager Runtime", - "website": "https://developer.android.com/jetpack/androidx/releases/work#2.9.1", + "website": "https://developer.android.com/jetpack/androidx/releases/work#2.10.0", "licenses": [ "Apache-2.0" ], @@ -3246,14 +3382,14 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "2.9.1", + "artifactVersion": "2.10.0", "description": "Android WorkManager Kotlin Extensions", "scm": { "connection": "scm:git:https://android.googlesource.com/platform/frameworks/support", "url": "https://cs.android.com/androidx/platform/frameworks/support" }, "name": "WorkManager Kotlin Extensions", - "website": "https://developer.android.com/jetpack/androidx/releases/work#2.9.1", + "website": "https://developer.android.com/jetpack/androidx/releases/work#2.10.0", "licenses": [ "Apache-2.0" ], @@ -3285,321 +3421,298 @@ ] }, { - "uniqueId": "com.airbnb.android:lottie", + "uniqueId": "co.touchlab:kermit-android", "funding": [ ], "developers": [ { - "name": "Airbnb" + "name": "Kevin Galligan" } ], - "artifactVersion": "6.4.0", - "description": "Lottie is an animation library that renders Adobe After Effects animations natively in realtime.", + "artifactVersion": "2.0.4", + "description": "Kermit The Log", "scm": { - "connection": "scm:git@github.com:airbnb/lottie-android.git", - "url": "https://github.com/airbnb/lottie-android", - "developerConnection": "scm:git@github.com:airbnb/lottie-android.git" + "connection": "scm:git:git://github.com/touchlab/Kermit.git", + "url": "https://github.com/touchlab/Kermit", + "developerConnection": "scm:git:git://github.com/touchlab/Kermit.git" }, - "name": "Lottie", - "website": "https://github.com/airbnb/lottie-android", + "name": "Kermit", + "website": "https://github.com/touchlab/Kermit", "licenses": [ "Apache-2.0" ] }, { - "uniqueId": "com.airbnb.android:lottie-compose", + "uniqueId": "co.touchlab:kermit-core-android", "funding": [ ], "developers": [ { - "name": "Airbnb" + "name": "Kevin Galligan" } ], - "artifactVersion": "6.4.0", - "description": "Lottie for Jetpack Compose.", + "artifactVersion": "2.0.4", + "description": "Kermit The Log", "scm": { - "connection": "scm:git@github.com:airbnb/lottie-android.git", - "url": "https://github.com/airbnb/lottie-android", - "developerConnection": "scm:git@github.com:airbnb/lottie-android.git" + "connection": "scm:git:git://github.com/touchlab/Kermit.git", + "url": "https://github.com/touchlab/Kermit", + "developerConnection": "scm:git:git://github.com/touchlab/Kermit.git" }, - "name": "Lottie Compose", - "website": "https://github.com/airbnb/lottie-android", + "name": "Kermit", + "website": "https://github.com/touchlab/Kermit", "licenses": [ "Apache-2.0" ] }, { - "uniqueId": "com.facebook.fbui.textlayoutbuilder:staticlayout-proxy", + "uniqueId": "co.touchlab:stately-concurrency-jvm", "funding": [ ], "developers": [ { - "name": "Facebook" + "name": "Kevin Galligan" } ], - "artifactVersion": "1.6.0", - "description": "Helper to access hidden StaticLayout constructor in Android", + "artifactVersion": "2.0.7", + "description": "Multithreaded Kotlin Multiplatform Utilities", "scm": { - "connection": "scm:git:https://github.com/facebook/TextLayoutBuilder.git", - "url": "https://github.com/facebook/TextLayoutBuilder.git", - "developerConnection": "scm:git:git@github.com:facebook/TextLayoutBuilder.git" + "connection": "scm:git:git://github.com/touchlab/Stately.git", + "url": "https://github.com/touchlab/Stately", + "developerConnection": "scm:git:git://github.com/touchlab/Stately.git" }, - "name": "StaticLayoutProxy", - "website": "https://github.com/facebook/TextLayoutBuilder", + "name": "Stately", + "website": "https://github.com/touchlab/Stately", "licenses": [ "Apache-2.0" ] }, { - "uniqueId": "com.facebook.shimmer:shimmer", + "uniqueId": "co.touchlab:stately-concurrent-collections-jvm", "funding": [ ], "developers": [ { - "name": "Facebook" + "name": "Kevin Galligan" } ], - "artifactVersion": "0.5.0", - "description": "Shimmer effect for Android Views.", + "artifactVersion": "2.0.7", + "description": "Multithreaded Kotlin Multiplatform Utilities", "scm": { - "connection": "scm:git@github.com:facebook/shimmer-android.git", - "url": "https://github.com/facebook/shimmer-android.git", - "developerConnection": "scm:git@github.com:facebook/shimmer-android.git" + "connection": "scm:git:git://github.com/touchlab/Stately.git", + "url": "https://github.com/touchlab/Stately", + "developerConnection": "scm:git:git://github.com/touchlab/Stately.git" }, - "name": "Shimmer", - "website": "http://facebook.github.io/shimmer-android", + "name": "Stately", + "website": "https://github.com/touchlab/Stately", "licenses": [ - "BSD-2-Clause" + "Apache-2.0" ] }, { - "uniqueId": "com.github.giangpham96.expandable-text:expandable_text_compose", + "uniqueId": "co.touchlab:stately-strict-jvm", "funding": [ ], "developers": [ { - "name": "Giang H. Pham" + "name": "Kevin Galligan" } ], - "artifactVersion": "2.0.0", - "description": "Light-weighted, convenient implementation of expandable text view that supports expanding & collapsing animations for Android projects.", + "artifactVersion": "2.0.7", + "description": "Multithreaded Kotlin Multiplatform Utilities", "scm": { - "connection": "scm:git://github.com/giangpham96/expandable-text.git", - "url": "git://github.com/giangpham96/expandable-text.git", - "developerConnection": "scm:git://github.com/giangpham96/expandable-text.git" + "connection": "scm:git:git://github.com/touchlab/Stately.git", + "url": "https://github.com/touchlab/Stately", + "developerConnection": "scm:git:git://github.com/touchlab/Stately.git" }, - "name": "giangpham96/expandable-text", - "website": "https://github.com/giangpham96/expandable-text", + "name": "Stately", + "website": "https://github.com/touchlab/Stately", "licenses": [ - "MIT" + "Apache-2.0" ] }, { - "uniqueId": "com.github.giangpham96.expandable-text:expandable_textview", + "uniqueId": "com.airbnb.android:lottie", "funding": [ ], "developers": [ { - "name": "Giang H. Pham" + "name": "Airbnb" } ], - "artifactVersion": "2.0.0", - "description": "Light-weighted, convenient implementation of expandable text view that supports expanding & collapsing animations for Android projects.", + "artifactVersion": "6.4.0", + "description": "Lottie is an animation library that renders Adobe After Effects animations natively in realtime.", "scm": { - "connection": "scm:git://github.com/giangpham96/expandable-text.git", - "url": "git://github.com/giangpham96/expandable-text.git", - "developerConnection": "scm:git://github.com/giangpham96/expandable-text.git" + "connection": "scm:git@github.com:airbnb/lottie-android.git", + "url": "https://github.com/airbnb/lottie-android", + "developerConnection": "scm:git@github.com:airbnb/lottie-android.git" }, - "name": "giangpham96/expandable-text", - "website": "https://github.com/giangpham96/expandable-text", - "licenses": [ - "MIT" - ] - }, - { - "uniqueId": "com.github.giangpham96:expandable-text", - "funding": [ - - ], - "developers": [ - - ], - "artifactVersion": "2.0.0", - "description": "", - "name": "com.github.giangpham96:expandable-text", + "name": "Lottie", + "website": "https://github.com/airbnb/lottie-android", "licenses": [ - + "Apache-2.0" ] }, { - "uniqueId": "com.github.skydoves:balloon", + "uniqueId": "com.airbnb.android:lottie-compose", "funding": [ ], "developers": [ { - "name": "Jaewoong Eum" + "name": "Airbnb" } ], - "artifactVersion": "1.6.4", - "description": "Modernized and sophisticated tooltips, fully customizable with an arrow and animations for Android.", + "artifactVersion": "6.4.0", + "description": "Lottie for Jetpack Compose.", "scm": { - "connection": "scm:git:git://github.com/skydoves/balloon.git", - "url": "https://github.com/skydoves/balloon/", - "developerConnection": "scm:git:git://github.com/skydoves/balloon.git" + "connection": "scm:git@github.com:airbnb/lottie-android.git", + "url": "https://github.com/airbnb/lottie-android", + "developerConnection": "scm:git@github.com:airbnb/lottie-android.git" }, - "name": "balloon", - "website": "https://github.com/skydoves/balloon/", + "name": "Lottie Compose", + "website": "https://github.com/airbnb/lottie-android", "licenses": [ "Apache-2.0" ] }, { - "uniqueId": "com.github.skydoves:landscapist-android", + "uniqueId": "com.benasher44:uuid-jvm", "funding": [ ], "developers": [ { - "name": "Jaewoong Eum" + "name": "Ben Asher" } ], - "artifactVersion": "2.3.4", - "description": "A pluggable, highly optimized Jetpack Compose image loading library that fetches and displays network images with Glide, Coil, and Fresco.", + "artifactVersion": "0.8.4", + "description": "A Kotlin multiplatform implementation of a v4 RFC4122 UUID", "scm": { - "connection": "scm:git:git://github.com/skydoves/landscapist.git", - "url": "https://github.com/skydoves/landscapist/", - "developerConnection": "scm:git:git://github.com/skydoves/landscapist.git" + "connection": "scm:git:git://github.com/benasher44/uuid.git", + "url": "https://github.com/benasher44/uuid/", + "developerConnection": "scm:git:ssh://git@github.com/benasher44/uuid.git" }, - "name": "landscapist", - "website": "https://github.com/skydoves/landscapist/", + "name": "UUID", + "website": "https://github.com/benasher44/uuid/", "licenses": [ - "Apache-2.0" + "MIT" ] }, { - "uniqueId": "com.github.skydoves:landscapist-animation-android", + "uniqueId": "com.facebook.fbui.textlayoutbuilder:staticlayout-proxy", "funding": [ ], "developers": [ { - "name": "Jaewoong Eum" + "name": "Facebook" } ], - "artifactVersion": "2.3.4", - "description": "A pluggable, highly optimized Jetpack Compose image loading library that fetches and displays network images with Glide, Coil, and Fresco.", + "artifactVersion": "1.6.0", + "description": "Helper to access hidden StaticLayout constructor in Android", "scm": { - "connection": "scm:git:git://github.com/skydoves/landscapist.git", - "url": "https://github.com/skydoves/landscapist/", - "developerConnection": "scm:git:git://github.com/skydoves/landscapist.git" + "connection": "scm:git:https://github.com/facebook/TextLayoutBuilder.git", + "url": "https://github.com/facebook/TextLayoutBuilder.git", + "developerConnection": "scm:git:git@github.com:facebook/TextLayoutBuilder.git" }, - "name": "landscapist-animation", - "website": "https://github.com/skydoves/landscapist/", + "name": "StaticLayoutProxy", + "website": "https://github.com/facebook/TextLayoutBuilder", "licenses": [ "Apache-2.0" ] }, { - "uniqueId": "com.github.skydoves:landscapist-bom", + "uniqueId": "com.facebook.shimmer:shimmer", "funding": [ ], "developers": [ { - "name": "Jaewoong Eum" + "name": "Facebook" } ], - "artifactVersion": "2.3.4", - "description": "A pluggable, highly optimized Jetpack Compose image loading library that fetches and displays network images with Glide, Coil, and Fresco.", + "artifactVersion": "0.5.0", + "description": "Shimmer effect for Android Views.", "scm": { - "connection": "scm:git:git://github.com/skydoves/landscapist.git", - "url": "https://github.com/skydoves/landscapist/", - "developerConnection": "scm:git:git://github.com/skydoves/landscapist.git" + "connection": "scm:git@github.com:facebook/shimmer-android.git", + "url": "https://github.com/facebook/shimmer-android.git", + "developerConnection": "scm:git@github.com:facebook/shimmer-android.git" }, - "name": "landscapist-bom", - "website": "https://github.com/skydoves/landscapist/", + "name": "Shimmer", + "website": "http://facebook.github.io/shimmer-android", "licenses": [ - "Apache-2.0" + "BSD-2-Clause" ] }, { - "uniqueId": "com.github.skydoves:landscapist-coil", + "uniqueId": "com.github.giangpham96.expandable-text:expandable_text_compose", "funding": [ ], "developers": [ { - "name": "Jaewoong Eum" + "name": "Giang H. Pham" } ], - "artifactVersion": "2.3.4", - "description": "A pluggable, highly optimized Jetpack Compose image loading library that fetches and displays network images with Glide, Coil, and Fresco.", + "artifactVersion": "2.0.0", + "description": "Light-weighted, convenient implementation of expandable text view that supports expanding & collapsing animations for Android projects.", "scm": { - "connection": "scm:git:git://github.com/skydoves/landscapist.git", - "url": "https://github.com/skydoves/landscapist/", - "developerConnection": "scm:git:git://github.com/skydoves/landscapist.git" + "connection": "scm:git://github.com/giangpham96/expandable-text.git", + "url": "git://github.com/giangpham96/expandable-text.git", + "developerConnection": "scm:git://github.com/giangpham96/expandable-text.git" }, - "name": "landscapist-coil", - "website": "https://github.com/skydoves/landscapist/", + "name": "giangpham96/expandable-text", + "website": "https://github.com/giangpham96/expandable-text", "licenses": [ - "Apache-2.0" + "MIT" ] }, { - "uniqueId": "com.github.skydoves:landscapist-palette-android", + "uniqueId": "com.github.giangpham96.expandable-text:expandable_textview", "funding": [ ], "developers": [ { - "name": "Jaewoong Eum" + "name": "Giang H. Pham" } ], - "artifactVersion": "2.3.4", - "description": "A pluggable, highly optimized Jetpack Compose image loading library that fetches and displays network images with Glide, Coil, and Fresco.", + "artifactVersion": "2.0.0", + "description": "Light-weighted, convenient implementation of expandable text view that supports expanding & collapsing animations for Android projects.", "scm": { - "connection": "scm:git:git://github.com/skydoves/landscapist.git", - "url": "https://github.com/skydoves/landscapist/", - "developerConnection": "scm:git:git://github.com/skydoves/landscapist.git" + "connection": "scm:git://github.com/giangpham96/expandable-text.git", + "url": "git://github.com/giangpham96/expandable-text.git", + "developerConnection": "scm:git://github.com/giangpham96/expandable-text.git" }, - "name": "landscapist-palette", - "website": "https://github.com/skydoves/landscapist/", + "name": "giangpham96/expandable-text", + "website": "https://github.com/giangpham96/expandable-text", "licenses": [ - "Apache-2.0" + "MIT" ] }, { - "uniqueId": "com.github.skydoves:landscapist-placeholder-android", + "uniqueId": "com.github.giangpham96:expandable-text", "funding": [ ], "developers": [ - { - "name": "Jaewoong Eum" - } + ], - "artifactVersion": "2.3.4", - "description": "A pluggable, highly optimized Jetpack Compose image loading library that fetches and displays network images with Glide, Coil, and Fresco.", - "scm": { - "connection": "scm:git:git://github.com/skydoves/landscapist.git", - "url": "https://github.com/skydoves/landscapist/", - "developerConnection": "scm:git:git://github.com/skydoves/landscapist.git" - }, - "name": "landscapist-placeholder", - "website": "https://github.com/skydoves/landscapist/", + "artifactVersion": "2.0.0", + "description": "", + "name": "com.github.giangpham96:expandable-text", "licenses": [ - "Apache-2.0" + ] }, { - "uniqueId": "com.github.skydoves:landscapist-transformation", + "uniqueId": "com.github.skydoves:balloon", "funding": [ ], @@ -3608,15 +3721,15 @@ "name": "Jaewoong Eum" } ], - "artifactVersion": "2.3.4", - "description": "A pluggable, highly optimized Jetpack Compose image loading library that fetches and displays network images with Glide, Coil, and Fresco.", + "artifactVersion": "1.6.4", + "description": "Modernized and sophisticated tooltips, fully customizable with an arrow and animations for Android.", "scm": { - "connection": "scm:git:git://github.com/skydoves/landscapist.git", - "url": "https://github.com/skydoves/landscapist/", - "developerConnection": "scm:git:git://github.com/skydoves/landscapist.git" + "connection": "scm:git:git://github.com/skydoves/balloon.git", + "url": "https://github.com/skydoves/balloon/", + "developerConnection": "scm:git:git://github.com/skydoves/balloon.git" }, - "name": "landscapist-transformation", - "website": "https://github.com/skydoves/landscapist/", + "name": "balloon", + "website": "https://github.com/skydoves/balloon/", "licenses": [ "Apache-2.0" ] @@ -3631,7 +3744,7 @@ "name": "Google" } ], - "artifactVersion": "0.32.0", + "artifactVersion": "0.36.0", "description": "Utilities for Jetpack Compose", "scm": { "connection": "scm:git:git://github.com/google/accompanist.git", @@ -3698,7 +3811,7 @@ "name": "The Android Open Source Project" } ], - "artifactVersion": "1.11.0", + "artifactVersion": "1.12.0", "description": "Material Components for Android is a static library that you can add to your Android application in order to use APIs that provide implementations of the Material Design specification. Compatible on devices running API 14 or later.", "scm": { "connection": "scm:git:https://github.com/material-components/material-components-android.git", @@ -3752,106 +3865,6 @@ "Apache-2.0" ] }, - { - "uniqueId": "com.google.dagger:dagger", - "funding": [ - - ], - "developers": [ - - ], - "artifactVersion": "2.50", - "description": "A fast dependency injector for Android and Java.", - "scm": { - "connection": "scm:git:git://github.com/google/dagger.git", - "url": "https://github.com/google/dagger/", - "developerConnection": "scm:git:ssh://git@github.com/google/dagger.git" - }, - "name": "Dagger", - "website": "https://github.com/google/dagger", - "licenses": [ - "Apache-2.0" - ], - "organization": { - "url": "https://www.google.com", - "name": "Google, Inc." - } - }, - { - "uniqueId": "com.google.dagger:dagger-lint-aar", - "funding": [ - - ], - "developers": [ - - ], - "artifactVersion": "2.50", - "description": "A fast dependency injector for Android and Java.", - "scm": { - "connection": "scm:git:git://github.com/google/dagger.git", - "url": "https://github.com/google/dagger/", - "developerConnection": "scm:git:ssh://git@github.com/google/dagger.git" - }, - "name": "Dagger Lint Rules AAR Distribution", - "website": "https://github.com/google/dagger", - "licenses": [ - "Apache-2.0" - ], - "organization": { - "url": "https://www.google.com", - "name": "Google, Inc." - } - }, - { - "uniqueId": "com.google.dagger:hilt-android", - "funding": [ - - ], - "developers": [ - - ], - "artifactVersion": "2.50", - "description": "A fast dependency injector for Android and Java.", - "scm": { - "connection": "scm:git:git://github.com/google/dagger.git", - "url": "https://github.com/google/dagger/", - "developerConnection": "scm:git:ssh://git@github.com/google/dagger.git" - }, - "name": "Hilt Android", - "website": "https://github.com/google/dagger", - "licenses": [ - "Apache-2.0" - ], - "organization": { - "url": "https://www.google.com", - "name": "Google, Inc." - } - }, - { - "uniqueId": "com.google.dagger:hilt-core", - "funding": [ - - ], - "developers": [ - - ], - "artifactVersion": "2.50", - "description": "A fast dependency injector for Android and Java.", - "scm": { - "connection": "scm:git:git://github.com/google/dagger.git", - "url": "https://github.com/google/dagger/", - "developerConnection": "scm:git:ssh://git@github.com/google/dagger.git" - }, - "name": "Hilt Core", - "website": "https://github.com/google/dagger", - "licenses": [ - "Apache-2.0" - ], - "organization": { - "url": "https://www.google.com", - "name": "Google, Inc." - } - }, { "uniqueId": "com.google.errorprone:error_prone_annotations", "funding": [ @@ -3860,7 +3873,7 @@ "developers": [ ], - "artifactVersion": "2.23.0", + "artifactVersion": "2.28.0", "description": "Error Prone is a static analysis tool for Java that catches common programming mistakes at compile-time.", "scm": { "connection": "scm:git:https://github.com/google/error-prone.git", @@ -3906,7 +3919,7 @@ "developers": [ ], - "artifactVersion": "33.0.0-android", + "artifactVersion": "33.3.1-android", "description": "Guava is a suite of core and expanded libraries that include\n utility classes, Google's collections, I/O classes, and\n much more.", "scm": { "connection": "scm:git:https://github.com/google/guava.git", @@ -3946,14 +3959,17 @@ ], "developers": [ - + { + "organisationUrl": "https://www.google.com", + "name": "Tom Ball" + } ], - "artifactVersion": "2.8", + "artifactVersion": "3.0.0", "description": "A set of annotations that provide additional information to the J2ObjC\n translator to modify the result of translation.", "scm": { - "connection": "scm:svn:http://svn.sonatype.org/spice/trunk/oss/oss-parenti-9", - "url": "http://svn.sonatype.org/spice/trunk/oss/oss-parent-9", - "developerConnection": "scm:svn:https://svn.sonatype.org/spice/trunk/oss/oss-parent-9" + "connection": "scm:git:git://github.com/google/j2objc.git", + "url": "http://github.com/google/j2objc", + "developerConnection": "scm:git:ssh://git@github.com/google/j2objc.git" }, "name": "J2ObjC Annotations", "website": "https://github.com/google/j2objc/", @@ -4076,6 +4092,29 @@ "MIT" ] }, + { + "uniqueId": "com.mikepenz:aboutlibraries-compose-m3-android", + "funding": [ + + ], + "developers": [ + { + "name": "Mike Penz" + } + ], + "artifactVersion": "10.10.0", + "description": "AboutLibraries automatically detects all dependencies of a project and collects their information including the license. Optionally visualising it via the provided ui components.", + "scm": { + "connection": "scm:git@github.com:mikepenz/AboutLibraries.git", + "url": "https://github.com/mikepenz/AboutLibraries", + "developerConnection": "scm:git@github.com:mikepenz/AboutLibraries.git" + }, + "name": "AboutLibraries Library", + "website": "https://github.com/mikepenz/AboutLibraries", + "licenses": [ + "Apache-2.0" + ] + }, { "uniqueId": "com.mikepenz:aboutlibraries-core-android", "funding": [ @@ -4411,7 +4450,7 @@ "name": "Square, Inc." } ], - "artifactVersion": "3.8.0", + "artifactVersion": "3.9.1", "description": "A modern I/O library for Android, Java, and Kotlin Multiplatform.", "scm": { "connection": "scm:git:git://github.com/square/okio.git", @@ -4494,7 +4533,7 @@ ] }, { - "uniqueId": "io.coil-kt:coil", + "uniqueId": "io.coil-kt.coil3:coil-android", "funding": [ ], @@ -4503,8 +4542,8 @@ "name": "Coil Contributors" } ], - "artifactVersion": "2.6.0", - "description": "An image loading library for Android backed by Kotlin Coroutines.", + "artifactVersion": "3.0.4", + "description": "An image loading library for Android and Compose Multiplatform.", "scm": { "connection": "scm:git:git://github.com/coil-kt/coil.git", "url": "https://github.com/coil-kt/coil", @@ -4517,7 +4556,7 @@ ] }, { - "uniqueId": "io.coil-kt:coil-base", + "uniqueId": "io.coil-kt.coil3:coil-compose-android", "funding": [ ], @@ -4526,21 +4565,21 @@ "name": "Coil Contributors" } ], - "artifactVersion": "2.6.0", - "description": "An image loading library for Android backed by Kotlin Coroutines.", + "artifactVersion": "3.0.4", + "description": "An image loading library for Android and Compose Multiplatform.", "scm": { "connection": "scm:git:git://github.com/coil-kt/coil.git", "url": "https://github.com/coil-kt/coil", "developerConnection": "scm:git:ssh://git@github.com/coil-kt/coil.git" }, - "name": "coil-base", + "name": "coil-compose", "website": "https://github.com/coil-kt/coil", "licenses": [ "Apache-2.0" ] }, { - "uniqueId": "io.coil-kt:coil-compose", + "uniqueId": "io.coil-kt.coil3:coil-compose-core-android", "funding": [ ], @@ -4549,21 +4588,44 @@ "name": "Coil Contributors" } ], - "artifactVersion": "2.6.0", - "description": "An image loading library for Android backed by Kotlin Coroutines.", + "artifactVersion": "3.0.4", + "description": "An image loading library for Android and Compose Multiplatform.", "scm": { "connection": "scm:git:git://github.com/coil-kt/coil.git", "url": "https://github.com/coil-kt/coil", "developerConnection": "scm:git:ssh://git@github.com/coil-kt/coil.git" }, - "name": "coil-compose", + "name": "coil-compose-core", + "website": "https://github.com/coil-kt/coil", + "licenses": [ + "Apache-2.0" + ] + }, + { + "uniqueId": "io.coil-kt.coil3:coil-core-android", + "funding": [ + + ], + "developers": [ + { + "name": "Coil Contributors" + } + ], + "artifactVersion": "3.0.4", + "description": "An image loading library for Android and Compose Multiplatform.", + "scm": { + "connection": "scm:git:git://github.com/coil-kt/coil.git", + "url": "https://github.com/coil-kt/coil", + "developerConnection": "scm:git:ssh://git@github.com/coil-kt/coil.git" + }, + "name": "coil-core", "website": "https://github.com/coil-kt/coil", "licenses": [ "Apache-2.0" ] }, { - "uniqueId": "io.coil-kt:coil-compose-base", + "uniqueId": "io.coil-kt.coil3:coil-network-core-android", "funding": [ ], @@ -4572,21 +4634,21 @@ "name": "Coil Contributors" } ], - "artifactVersion": "2.6.0", - "description": "An image loading library for Android backed by Kotlin Coroutines.", + "artifactVersion": "3.0.4", + "description": "An image loading library for Android and Compose Multiplatform.", "scm": { "connection": "scm:git:git://github.com/coil-kt/coil.git", "url": "https://github.com/coil-kt/coil", "developerConnection": "scm:git:ssh://git@github.com/coil-kt/coil.git" }, - "name": "coil-compose-base", + "name": "coil-network-core", "website": "https://github.com/coil-kt/coil", "licenses": [ "Apache-2.0" ] }, { - "uniqueId": "io.coil-kt:coil-gif", + "uniqueId": "io.coil-kt.coil3:coil-network-okhttp-jvm", "funding": [ ], @@ -4595,14 +4657,14 @@ "name": "Coil Contributors" } ], - "artifactVersion": "2.6.0", - "description": "An image loading library for Android backed by Kotlin Coroutines.", + "artifactVersion": "3.0.4", + "description": "An image loading library for Android and Compose Multiplatform.", "scm": { "connection": "scm:git:git://github.com/coil-kt/coil.git", "url": "https://github.com/coil-kt/coil", "developerConnection": "scm:git:ssh://git@github.com/coil-kt/coil.git" }, - "name": "coil-gif", + "name": "coil-network-okhttp", "website": "https://github.com/coil-kt/coil", "licenses": [ "Apache-2.0" @@ -4654,6 +4716,160 @@ "Apache-2.0" ] }, + { + "uniqueId": "io.insert-koin:koin-android", + "funding": [ + + ], + "developers": [ + { + "name": "Arnaud Giuliani" + } + ], + "artifactVersion": "4.0.0-RC1", + "description": "KOIN - Kotlin simple Dependency Injection Framework", + "scm": { + "connection": "https://github.com/InsertKoinIO/koin.git", + "url": "https://github.com/InsertKoinIO/koin" + }, + "name": "Koin", + "website": "https://insert-koin.io/", + "licenses": [ + "Apache-2.0" + ] + }, + { + "uniqueId": "io.insert-koin:koin-androidx-compose", + "funding": [ + + ], + "developers": [ + { + "name": "Arnaud Giuliani" + } + ], + "artifactVersion": "4.0.0-RC1", + "description": "KOIN - Kotlin simple Dependency Injection Framework", + "scm": { + "connection": "https://github.com/InsertKoinIO/koin.git", + "url": "https://github.com/InsertKoinIO/koin" + }, + "name": "Koin", + "website": "https://insert-koin.io/", + "licenses": [ + "Apache-2.0" + ] + }, + { + "uniqueId": "io.insert-koin:koin-androidx-workmanager", + "funding": [ + + ], + "developers": [ + { + "name": "Arnaud Giuliani" + } + ], + "artifactVersion": "4.0.0-RC1", + "description": "KOIN - Kotlin simple Dependency Injection Framework", + "scm": { + "connection": "https://github.com/InsertKoinIO/koin.git", + "url": "https://github.com/InsertKoinIO/koin" + }, + "name": "Koin", + "website": "https://insert-koin.io/", + "licenses": [ + "Apache-2.0" + ] + }, + { + "uniqueId": "io.insert-koin:koin-annotations-jvm", + "funding": [ + + ], + "developers": [ + { + "name": "Arnaud Giuliani" + } + ], + "artifactVersion": "1.4.0-RC4", + "description": "KOIN - Kotlin simple Dependency Injection Framework", + "scm": { + "connection": "https://github.com/InsertKoinIO/koin.git", + "url": "https://github.com/InsertKoinIO/koin" + }, + "name": "Koin", + "website": "https://insert-koin.io/", + "licenses": [ + "Apache-2.0" + ] + }, + { + "uniqueId": "io.insert-koin:koin-compose-jvm", + "funding": [ + + ], + "developers": [ + { + "name": "Arnaud Giuliani" + } + ], + "artifactVersion": "4.0.0-RC1", + "description": "KOIN - Kotlin simple Dependency Injection Framework", + "scm": { + "connection": "https://github.com/InsertKoinIO/koin.git", + "url": "https://github.com/InsertKoinIO/koin" + }, + "name": "Koin", + "website": "https://insert-koin.io/", + "licenses": [ + "Apache-2.0" + ] + }, + { + "uniqueId": "io.insert-koin:koin-core-jvm", + "funding": [ + + ], + "developers": [ + { + "name": "Arnaud Giuliani" + } + ], + "artifactVersion": "4.0.0-RC1", + "description": "KOIN - Kotlin simple Dependency Injection Framework", + "scm": { + "connection": "https://github.com/InsertKoinIO/koin.git", + "url": "https://github.com/InsertKoinIO/koin" + }, + "name": "Koin", + "website": "https://insert-koin.io/", + "licenses": [ + "Apache-2.0" + ] + }, + { + "uniqueId": "io.insert-koin:koin-core-viewmodel-jvm", + "funding": [ + + ], + "developers": [ + { + "name": "Arnaud Giuliani" + } + ], + "artifactVersion": "4.0.0-RC1", + "description": "KOIN - Kotlin simple Dependency Injection Framework", + "scm": { + "connection": "https://github.com/InsertKoinIO/koin.git", + "url": "https://github.com/InsertKoinIO/koin" + }, + "name": "Koin", + "website": "https://insert-koin.io/", + "licenses": [ + "Apache-2.0" + ] + }, { "uniqueId": "io.ktor:ktor-client-cio-jvm", "funding": [ @@ -5072,25 +5288,6 @@ "Apache-2.0" ] }, - { - "uniqueId": "javax.inject:javax.inject", - "funding": [ - - ], - "developers": [ - - ], - "artifactVersion": "1", - "description": "The javax.inject API", - "scm": { - "url": "http://code.google.com/p/atinject/source/checkout" - }, - "name": "javax.inject", - "website": "http://code.google.com/p/atinject/", - "licenses": [ - "Apache-2.0" - ] - }, { "uniqueId": "org.brotli:dec", "funding": [ @@ -5127,7 +5324,7 @@ "name": "Suzanne Millstein" } ], - "artifactVersion": "3.41.0", + "artifactVersion": "3.43.0", "description": "checker-qual contains annotations (type qualifiers) that a programmer\nwrites to specify Java code for type-checking by the Checker Framework.", "scm": { "connection": "scm:git:https://github.com/typetools/checker-framework.git", @@ -5140,6 +5337,30 @@ "MIT" ] }, + { + "uniqueId": "org.jetbrains.androidx.core:core-bundle-android", + "funding": [ + + ], + "developers": [ + { + "organisationUrl": "https://www.jetbrains.com", + "name": "Compose Multiplatform Team" + } + ], + "artifactVersion": "1.0.0", + "description": "Provides Bundle in Kotlin Multiplatform projects", + "scm": { + "connection": "scm:git:https://github.com/JetBrains/compose-jb.git", + "url": "https://github.com/JetBrains/compose-jb", + "developerConnection": "scm:git:https://github.com/JetBrains/compose-jb.git" + }, + "name": "androidx.core:core-bundle", + "website": "https://github.com/JetBrains/compose-jb", + "licenses": [ + "Apache-2.0" + ] + }, { "uniqueId": "org.jetbrains.kotlin:kotlin-android-extensions-runtime", "funding": [ @@ -5247,7 +5468,7 @@ "name": "Kotlin Team" } ], - "artifactVersion": "2.0.0", + "artifactVersion": "2.0.21", "description": "Kotlin Standard Library", "scm": { "connection": "scm:git:https://github.com/JetBrains/kotlin.git", @@ -5319,7 +5540,7 @@ "name": "JetBrains Team" } ], - "artifactVersion": "0.21.0", + "artifactVersion": "0.24.0", "description": "AtomicFU utilities", "scm": { "url": "https://github.com/Kotlin/kotlinx.atomicfu" @@ -5330,6 +5551,28 @@ "Apache-2.0" ] }, + { + "uniqueId": "org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm", + "funding": [ + + ], + "developers": [ + { + "organisationUrl": "https://www.jetbrains.com", + "name": "JetBrains Team" + } + ], + "artifactVersion": "0.3.7", + "description": "Kotlin Immutable Collections multiplatform library", + "scm": { + "url": "https://github.com/Kotlin/kotlinx.collections.immutable" + }, + "name": "kotlinx-collections-immutable", + "website": "https://github.com/Kotlin/kotlinx.collections.immutable", + "licenses": [ + "Apache-2.0" + ] + }, { "uniqueId": "org.jetbrains.kotlinx:kotlinx-coroutines-android", "funding": [ @@ -5341,7 +5584,7 @@ "name": "JetBrains Team" } ], - "artifactVersion": "1.8.1", + "artifactVersion": "1.9.0", "description": "Coroutines support libraries for Kotlin", "scm": { "url": "https://github.com/Kotlin/kotlinx.coroutines" @@ -5363,7 +5606,7 @@ "name": "JetBrains Team" } ], - "artifactVersion": "1.8.1", + "artifactVersion": "1.9.0", "description": "Coroutines support libraries for Kotlin", "scm": { "url": "https://github.com/Kotlin/kotlinx.coroutines" @@ -5385,7 +5628,7 @@ "name": "JetBrains Team" } ], - "artifactVersion": "1.8.1", + "artifactVersion": "1.9.0", "description": "Coroutines support libraries for Kotlin", "scm": { "url": "https://github.com/Kotlin/kotlinx.coroutines" @@ -5407,7 +5650,7 @@ "name": "JetBrains Team" } ], - "artifactVersion": "1.8.1", + "artifactVersion": "1.9.0", "description": "Coroutines support libraries for Kotlin", "scm": { "url": "https://github.com/Kotlin/kotlinx.coroutines" @@ -5429,7 +5672,7 @@ "name": "JetBrains Team" } ], - "artifactVersion": "1.8.1", + "artifactVersion": "1.9.0", "description": "Coroutines support libraries for Kotlin", "scm": { "url": "https://github.com/Kotlin/kotlinx.coroutines" @@ -5451,7 +5694,7 @@ "name": "JetBrains Team" } ], - "artifactVersion": "1.8.1", + "artifactVersion": "1.9.0", "description": "Coroutines support libraries for Kotlin", "scm": { "url": "https://github.com/Kotlin/kotlinx.coroutines" @@ -5462,6 +5705,28 @@ "Apache-2.0" ] }, + { + "uniqueId": "org.jetbrains.kotlinx:kotlinx-datetime-jvm", + "funding": [ + + ], + "developers": [ + { + "organisationUrl": "https://www.jetbrains.com", + "name": "JetBrains Team" + } + ], + "artifactVersion": "0.4.0", + "description": "Kotlin Datetime Library", + "scm": { + "url": "https://github.com/Kotlin/kotlinx-datetime" + }, + "name": "kotlinx-datetime", + "website": "https://github.com/Kotlin/kotlinx-datetime", + "licenses": [ + "Apache-2.0" + ] + }, { "uniqueId": "org.jetbrains.kotlinx:kotlinx-serialization-bom", "funding": [ @@ -5473,7 +5738,7 @@ "name": "JetBrains Team" } ], - "artifactVersion": "1.6.2", + "artifactVersion": "1.6.3", "description": "Kotlin multiplatform serialization runtime library", "scm": { "url": "https://github.com/Kotlin/kotlinx.serialization" @@ -5495,7 +5760,7 @@ "name": "JetBrains Team" } ], - "artifactVersion": "1.6.2", + "artifactVersion": "1.6.3", "description": "Kotlin multiplatform serialization runtime library", "scm": { "url": "https://github.com/Kotlin/kotlinx.serialization" @@ -5517,7 +5782,7 @@ "name": "JetBrains Team" } ], - "artifactVersion": "1.6.2", + "artifactVersion": "1.6.3", "description": "Kotlin multiplatform serialization runtime library", "scm": { "url": "https://github.com/Kotlin/kotlinx.serialization" @@ -5539,7 +5804,7 @@ "name": "JetBrains Team" } ], - "artifactVersion": "1.6.2", + "artifactVersion": "1.6.3", "description": "Kotlin multiplatform serialization runtime library", "scm": { "url": "https://github.com/Kotlin/kotlinx.serialization" @@ -5574,6 +5839,98 @@ "Apache-2.0" ] }, + { + "uniqueId": "org.mobilenativefoundation.store:cache5-jvm", + "funding": [ + + ], + "developers": [ + { + "name": "Dropbox" + } + ], + "artifactVersion": "5.1.0-alpha05", + "description": "Store5 is a Kotlin Multiplatform network-resilient repository layer", + "scm": { + "connection": "scm:git:https://github.com/MobileNativeFoundation/Store.git", + "url": "https://github.com/MobileNativeFoundation/Store", + "developerConnection": "scm:git:git@github.com:MobileNativeFoundation/Store.git" + }, + "name": "org.mobilenativefoundation.store", + "website": "https://github.com/MobileNativeFoundation/Store", + "licenses": [ + "Apache-2.0" + ] + }, + { + "uniqueId": "org.mobilenativefoundation.store:core5-jvm", + "funding": [ + + ], + "developers": [ + { + "name": "Dropbox" + } + ], + "artifactVersion": "5.1.0-alpha05", + "description": "Store5 is a Kotlin Multiplatform network-resilient repository layer", + "scm": { + "connection": "scm:git:https://github.com/MobileNativeFoundation/Store.git", + "url": "https://github.com/MobileNativeFoundation/Store", + "developerConnection": "scm:git:git@github.com:MobileNativeFoundation/Store.git" + }, + "name": "org.mobilenativefoundation.store", + "website": "https://github.com/MobileNativeFoundation/Store", + "licenses": [ + "Apache-2.0" + ] + }, + { + "uniqueId": "org.mobilenativefoundation.store:multicast5-jvm", + "funding": [ + + ], + "developers": [ + { + "name": "Dropbox" + } + ], + "artifactVersion": "5.1.0-alpha05", + "description": "Store5 is a Kotlin Multiplatform network-resilient repository layer", + "scm": { + "connection": "scm:git:https://github.com/MobileNativeFoundation/Store.git", + "url": "https://github.com/MobileNativeFoundation/Store", + "developerConnection": "scm:git:git@github.com:MobileNativeFoundation/Store.git" + }, + "name": "org.mobilenativefoundation.store", + "website": "https://github.com/MobileNativeFoundation/Store", + "licenses": [ + "Apache-2.0" + ] + }, + { + "uniqueId": "org.mobilenativefoundation.store:store5-jvm", + "funding": [ + + ], + "developers": [ + { + "name": "Dropbox" + } + ], + "artifactVersion": "5.1.0-alpha05", + "description": "Store5 is a Kotlin Multiplatform network-resilient repository layer", + "scm": { + "connection": "scm:git:https://github.com/MobileNativeFoundation/Store.git", + "url": "https://github.com/MobileNativeFoundation/Store", + "developerConnection": "scm:git:git@github.com:MobileNativeFoundation/Store.git" + }, + "name": "org.mobilenativefoundation.store", + "website": "https://github.com/MobileNativeFoundation/Store", + "licenses": [ + "Apache-2.0" + ] + }, { "uniqueId": "org.slf4j:slf4j-api", "funding": [ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7285075f..b16ea28b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -362,4 +362,5 @@ Go to log in page YouTube Music now requires you to log in to stream music, Piped Instance sometime can\'t work too. You should log in to YouTube to get better experience with SimpMusic. Spotify Canvas Cache + Clear canvas cache \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 82b63f9d..81776c9a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -119,6 +119,7 @@ customactivityoncrash = { group = "cat.ereza", name = "customactivityoncrash", v sdp-android = { group = "com.intuit.sdp", name = "sdp-android", version.ref = "sdp-android" } ssp-android = { group = "com.intuit.ssp", name = "ssp-android", version.ref = "ssp-android" } aboutlibraries = { group = "com.mikepenz", name = "aboutlibraries", version.ref = "aboutlibraries" } +aboutlibraries-compose-m3 = { group = "com.mikepenz", name = "aboutlibraries-compose-m3", version.ref = "aboutlibraries" } flexbox = { group = "com.google.android.flexbox", name = "flexbox", version.ref = "flexbox" } balloon = { group = "com.github.skydoves", name = "balloon", version.ref = "balloon" } coil-compose = { group = "io.coil-kt.coil3", name = "coil-compose", version.ref = "coil3" } diff --git a/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/extension/StringExt.kt b/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/extension/StringExt.kt index 422dcee8..82ca846f 100644 --- a/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/extension/StringExt.kt +++ b/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/extension/StringExt.kt @@ -18,4 +18,9 @@ fun randomString(length: Int): String { fun String.verifyYouTubePlaylistId(): String { return if (startsWith("VL")) this else "VL$this" +} + +fun String.isTwoLetterCode(): Boolean { + val regex = "^[A-Za-z]{2}$".toRegex() + return regex.matches(this) } \ No newline at end of file