Android 13 runtime notification permissions

pull/1917/head
Alex Baker 3 years ago
parent 99b1c2e38d
commit 1fbc2b1661

@ -233,7 +233,8 @@ dependencies {
implementation("androidx.compose.material:material-icons-extended:${Versions.compose}") implementation("androidx.compose.material:material-icons-extended:${Versions.compose}")
releaseCompileOnly("androidx.compose.ui:ui-tooling:${Versions.compose}") releaseCompileOnly("androidx.compose.ui:ui-tooling:${Versions.compose}")
implementation("com.google.accompanist:accompanist-flowlayout:0.24.11-rc") implementation("com.google.accompanist:accompanist-flowlayout:${Versions.accompanist}")
implementation("com.google.accompanist:accompanist-permissions:${Versions.accompanist}")
googleplayImplementation("com.google.firebase:firebase-crashlytics:${Versions.crashlytics}") googleplayImplementation("com.google.firebase:firebase-crashlytics:${Versions.crashlytics}")
googleplayImplementation("com.google.firebase:firebase-analytics:${Versions.analytics}") { googleplayImplementation("com.google.firebase:firebase-analytics:${Versions.analytics}") {

@ -6,6 +6,8 @@
<!-- ================================================== Used Permissions = --> <!-- ================================================== Used Permissions = -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<!-- ********************* --> <!-- ********************* -->
<!-- maps and place search --> <!-- maps and place search -->
<!-- ********************* --> <!-- ********************* -->

@ -163,6 +163,10 @@ public class AndroidUtilities {
return VERSION.SDK_INT >= VERSION_CODES.S; return VERSION.SDK_INT >= VERSION_CODES.S;
} }
public static boolean atLeastTiramisu() {
return VERSION.SDK_INT >= VERSION_CODES.TIRAMISU;
}
public static void assertMainThread() { public static void assertMainThread() {
if (BuildConfig.DEBUG && !isMainThread()) { if (BuildConfig.DEBUG && !isMainThread()) {
throw new IllegalStateException("Should be called from main thread"); throw new IllegalStateException("Should be called from main thread");

@ -17,11 +17,17 @@ import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.viewModels
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.PermissionStatus
import com.google.accompanist.permissions.rememberPermissionState
import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.andlib.utility.AndroidUtilities.atLeastTiramisu
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.activities.DateAndTimePickerActivity import org.tasks.activities.DateAndTimePickerActivity
@ -49,13 +55,15 @@ class ReminderControlSet : TaskEditControlComposeFragment() {
@Inject lateinit var dialogBuilder: DialogBuilder @Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var alarmToString: AlarmToString @Inject lateinit var alarmToString: AlarmToString
private val showCustomDialog = mutableStateOf(false) data class ViewState(
private val showRandomDialog = mutableStateOf(false) val showCustomDialog: Boolean = false,
val showRandomDialog: Boolean = false,
)
private val ringMode = mutableStateOf(0) private val ringMode = mutableStateOf(0)
private val vm: ReminderControlSetViewModel by viewModels()
override fun createView(savedInstanceState: Bundle?) { override fun createView(savedInstanceState: Bundle?) {
showCustomDialog.value = savedInstanceState?.getBoolean(CUSTOM_DIALOG_VISIBLE) ?: false
showRandomDialog.value = savedInstanceState?.getBoolean(RANDOM_DIALOG_VISIBLE) ?: false
when { when {
viewModel.ringNonstop!! -> setRingMode(2) viewModel.ringNonstop!! -> setRingMode(2)
viewModel.ringFiveTimes!! -> setRingMode(1) viewModel.ringFiveTimes!! -> setRingMode(1)
@ -63,13 +71,6 @@ class ReminderControlSet : TaskEditControlComposeFragment() {
} }
} }
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putBoolean(CUSTOM_DIALOG_VISIBLE, showCustomDialog.value)
outState.putBoolean(RANDOM_DIALOG_VISIBLE, showRandomDialog.value)
}
private fun onClickRingType() { private fun onClickRingType() {
val modes = resources.getStringArray(R.array.reminder_ring_modes) val modes = resources.getStringArray(R.array.reminder_ring_modes)
val ringMode = when { val ringMode = when {
@ -102,11 +103,11 @@ class ReminderControlSet : TaskEditControlComposeFragment() {
getString(R.string.when_overdue) -> getString(R.string.when_overdue) ->
addAlarmRow(whenOverdue(id)) addAlarmRow(whenOverdue(id))
getString(R.string.randomly) -> getString(R.string.randomly) ->
addRandomAlarm() vm.showRandomDialog(visible = true)
getString(R.string.pick_a_date_and_time) -> getString(R.string.pick_a_date_and_time) ->
addNewAlarm() addNewAlarm()
getString(R.string.repeat_option_custom) -> getString(R.string.repeat_option_custom) ->
addCustomAlarm() vm.showCustomDialog(visible = true)
} }
} }
@ -125,11 +126,65 @@ class ReminderControlSet : TaskEditControlComposeFragment() {
} }
} }
@OptIn(ExperimentalComposeUiApi::class) @OptIn(ExperimentalComposeUiApi::class, ExperimentalPermissionsApi::class)
@Composable @Composable
override fun Body() { override fun Body() {
val alarms = viewModel.selectedAlarms.collectAsStateLifecycleAware() val viewState = vm.viewState.collectAsStateLifecycleAware()
val current: ViewState = viewState.value
val notificationPermissions = if (atLeastTiramisu()) {
rememberPermissionState(
android.Manifest.permission.POST_NOTIFICATIONS
)
} else {
null
}
when (notificationPermissions?.status ?: PermissionStatus.Granted) {
PermissionStatus.Granted ->
Alarms()
is PermissionStatus.Denied -> {
Column(
modifier = Modifier.clickable {
notificationPermissions?.launchPermissionRequest()
}
) {
Spacer(modifier = Modifier.height(20.dp))
Text(
text = stringResource(id = R.string.enable_reminders),
color = colorResource(id = R.color.red_500),
)
Text(
text = stringResource(id = R.string.enable_reminders_description),
style = MaterialTheme.typography.caption,
color = colorResource(id = R.color.red_500),
)
Spacer(modifier = Modifier.height(20.dp))
}
}
}
AddReminderDialog.AddCustomReminderDialog(
openDialog = current.showCustomDialog,
addAlarm = this::addAlarmRow,
closeDialog = {
vm.showCustomDialog(visible = false)
AndroidUtilities.hideKeyboard(activity)
}
)
AddReminderDialog.AddRandomReminderDialog(
openDialog = current.showRandomDialog,
addAlarm = this::addAlarmRow,
closeDialog = {
vm.showRandomDialog(visible = false)
AndroidUtilities.hideKeyboard(activity)
}
)
}
@Composable
fun Alarms() {
Column { Column {
val alarms = viewModel.selectedAlarms.collectAsStateLifecycleAware()
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
alarms.value.forEach { alarm -> alarms.value.forEach { alarm ->
AlarmRow(alarmToString.toString(alarm)) { AlarmRow(alarmToString.toString(alarm)) {
@ -181,26 +236,6 @@ class ReminderControlSet : TaskEditControlComposeFragment() {
} }
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
} }
val openCustomDialog = remember { showCustomDialog }
AddReminderDialog.AddCustomReminderDialog(
openCustomDialog,
addAlarm = this::addAlarmRow,
closeDialog = {
openCustomDialog.value = false
AndroidUtilities.hideKeyboard(activity)
}
)
val openRandomDialog = remember { showRandomDialog }
AddReminderDialog.AddRandomReminderDialog(
openRandomDialog,
addAlarm = this::addAlarmRow,
closeDialog = {
openRandomDialog.value = false
AndroidUtilities.hideKeyboard(activity)
}
)
} }
override val icon = R.drawable.ic_outline_notifications_24px override val icon = R.drawable.ic_outline_notifications_24px
@ -235,14 +270,6 @@ class ReminderControlSet : TaskEditControlComposeFragment() {
startActivityForResult(intent, REQUEST_NEW_ALARM) startActivityForResult(intent, REQUEST_NEW_ALARM)
} }
private fun addCustomAlarm() {
showCustomDialog.value = true
}
private fun addRandomAlarm() {
showRandomDialog.value = true
}
private val options: List<String> private val options: List<String>
get() { get() {
val options: MutableList<String> = ArrayList() val options: MutableList<String> = ArrayList()
@ -264,8 +291,6 @@ class ReminderControlSet : TaskEditControlComposeFragment() {
companion object { companion object {
const val TAG = R.string.TEA_ctrl_reminders_pref const val TAG = R.string.TEA_ctrl_reminders_pref
private const val REQUEST_NEW_ALARM = 12152 private const val REQUEST_NEW_ALARM = 12152
private const val CUSTOM_DIALOG_VISIBLE = "custom_dialog_visible"
private const val RANDOM_DIALOG_VISIBLE = "random_dialog_visible"
} }
} }

@ -0,0 +1,25 @@
package com.todoroo.astrid.ui
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
class ReminderControlSetViewModel : ViewModel() {
private val _viewState = MutableStateFlow(ReminderControlSet.ViewState())
val viewState: StateFlow<ReminderControlSet.ViewState>
get() = _viewState.asStateFlow()
fun showCustomDialog(visible: Boolean) {
_viewState.value = _viewState.value.copy(
showCustomDialog = visible
)
}
fun showRandomDialog(visible: Boolean) {
_viewState.value = _viewState.value.copy(
showRandomDialog = visible
)
}
}

@ -3,31 +3,14 @@ package org.tasks.compose
import android.content.res.Configuration import android.content.res.Configuration
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.AlertDialog import androidx.compose.material.*
import androidx.compose.material.Divider
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.RadioButton
import androidx.compose.material.Text
import androidx.compose.material.TextFieldDefaults
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Autorenew import androidx.compose.material.icons.outlined.Autorenew
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
@ -56,13 +39,13 @@ import java.util.concurrent.TimeUnit
object AddReminderDialog { object AddReminderDialog {
@Composable @Composable
fun AddRandomReminderDialog( fun AddRandomReminderDialog(
openDialog: MutableState<Boolean>, openDialog: Boolean,
addAlarm: (Alarm) -> Unit, addAlarm: (Alarm) -> Unit,
closeDialog: () -> Unit, closeDialog: () -> Unit,
) { ) {
val time = rememberSaveable { mutableStateOf(15) } val time = rememberSaveable { mutableStateOf(15) }
val units = rememberSaveable { mutableStateOf(0) } val units = rememberSaveable { mutableStateOf(0) }
if (openDialog.value) { if (openDialog) {
AlertDialog( AlertDialog(
onDismissRequest = closeDialog, onDismissRequest = closeDialog,
text = { AddRandomReminder(openDialog, time, units) }, text = { AddRandomReminder(openDialog, time, units) },
@ -89,7 +72,7 @@ object AddReminderDialog {
@Composable @Composable
fun AddCustomReminderDialog( fun AddCustomReminderDialog(
openDialog: MutableState<Boolean>, openDialog: Boolean,
addAlarm: (Alarm) -> Unit, addAlarm: (Alarm) -> Unit,
closeDialog: () -> Unit, closeDialog: () -> Unit,
) { ) {
@ -99,7 +82,7 @@ object AddReminderDialog {
val interval = rememberSaveable { mutableStateOf(0) } val interval = rememberSaveable { mutableStateOf(0) }
val recurringUnits = rememberSaveable { mutableStateOf(0) } val recurringUnits = rememberSaveable { mutableStateOf(0) }
val repeat = rememberSaveable { mutableStateOf(0) } val repeat = rememberSaveable { mutableStateOf(0) }
if (openDialog.value) { if (openDialog) {
if (!openRecurringDialog.value) { if (!openRecurringDialog.value) {
AlertDialog( AlertDialog(
onDismissRequest = closeDialog, onDismissRequest = closeDialog,
@ -179,7 +162,7 @@ object AddReminderDialog {
onDismissRequest = closeDialog, onDismissRequest = closeDialog,
text = { text = {
AddRecurringReminder( AddRecurringReminder(
openDialog, openDialog.value,
interval, interval,
units, units,
repeat, repeat,
@ -209,7 +192,7 @@ object AddReminderDialog {
@Composable @Composable
fun AddRandomReminder( fun AddRandomReminder(
visible: MutableState<Boolean>, visible: Boolean,
time: MutableState<Int>, time: MutableState<Int>,
units: MutableState<Int>, units: MutableState<Int>,
) { ) {
@ -237,7 +220,7 @@ object AddReminderDialog {
@Composable @Composable
fun AddCustomReminder( fun AddCustomReminder(
visible: MutableState<Boolean>, visible: Boolean,
time: MutableState<Int>, time: MutableState<Int>,
units: MutableState<Int>, units: MutableState<Int>,
interval: MutableState<Int>, interval: MutableState<Int>,
@ -313,7 +296,7 @@ object AddReminderDialog {
@Composable @Composable
fun AddRecurringReminder( fun AddRecurringReminder(
openDialog: MutableState<Boolean>, openDialog: Boolean,
interval: MutableState<Int>, interval: MutableState<Int>,
units: MutableState<Int>, units: MutableState<Int>,
repeat: MutableState<Int> repeat: MutableState<Int>
@ -374,7 +357,7 @@ object AddReminderDialog {
@ExperimentalComposeUiApi @ExperimentalComposeUiApi
@Composable @Composable
fun ShowKeyboard(visible: MutableState<Boolean>, focusRequester: FocusRequester) { fun ShowKeyboard(visible: Boolean, focusRequester: FocusRequester) {
val keyboardController = LocalSoftwareKeyboardController.current val keyboardController = LocalSoftwareKeyboardController.current
LaunchedEffect(visible) { LaunchedEffect(visible) {
focusRequester.freeFocus() focusRequester.freeFocus()
@ -484,7 +467,7 @@ fun BodyText(modifier: Modifier = Modifier, text: String) {
fun AddCustomReminderOne() = fun AddCustomReminderOne() =
MdcTheme { MdcTheme {
AddReminderDialog.AddCustomReminder( AddReminderDialog.AddCustomReminder(
visible = remember { mutableStateOf(true) }, visible = true,
time = remember { mutableStateOf(1) }, time = remember { mutableStateOf(1) },
units = remember { mutableStateOf(0) }, units = remember { mutableStateOf(0) },
interval = remember { mutableStateOf(0) }, interval = remember { mutableStateOf(0) },
@ -501,7 +484,7 @@ fun AddCustomReminderOne() =
fun AddCustomReminder() = fun AddCustomReminder() =
MdcTheme { MdcTheme {
AddReminderDialog.AddCustomReminder( AddReminderDialog.AddCustomReminder(
visible = remember { mutableStateOf(true) }, visible = true,
time = remember { mutableStateOf(15) }, time = remember { mutableStateOf(15) },
units = remember { mutableStateOf(1) }, units = remember { mutableStateOf(1) },
interval = remember { mutableStateOf(0) }, interval = remember { mutableStateOf(0) },
@ -518,7 +501,7 @@ fun AddCustomReminder() =
fun AddRepeatingReminderOne() = fun AddRepeatingReminderOne() =
MdcTheme { MdcTheme {
AddReminderDialog.AddRecurringReminder( AddReminderDialog.AddRecurringReminder(
openDialog = remember { mutableStateOf(true) }, openDialog = true,
interval = remember { mutableStateOf(1) }, interval = remember { mutableStateOf(1) },
units = remember { mutableStateOf(0) }, units = remember { mutableStateOf(0) },
repeat = remember { mutableStateOf(1) }, repeat = remember { mutableStateOf(1) },
@ -532,7 +515,7 @@ fun AddRepeatingReminderOne() =
fun AddRepeatingReminder() = fun AddRepeatingReminder() =
MdcTheme { MdcTheme {
AddReminderDialog.AddRecurringReminder( AddReminderDialog.AddRecurringReminder(
openDialog = remember { mutableStateOf(true) }, openDialog = true,
interval = remember { mutableStateOf(15) }, interval = remember { mutableStateOf(15) },
units = remember { mutableStateOf(1) }, units = remember { mutableStateOf(1) },
repeat = remember { mutableStateOf(4) }, repeat = remember { mutableStateOf(4) },
@ -546,7 +529,7 @@ fun AddRepeatingReminder() =
fun AddRandomReminderOne() = fun AddRandomReminderOne() =
MdcTheme { MdcTheme {
AddReminderDialog.AddRandomReminder( AddReminderDialog.AddRandomReminder(
visible = remember { mutableStateOf(true) }, visible = true,
time = remember { mutableStateOf(1) }, time = remember { mutableStateOf(1) },
units = remember { mutableStateOf(0) } units = remember { mutableStateOf(0) }
) )
@ -559,7 +542,7 @@ fun AddRandomReminderOne() =
fun AddRandomReminder() = fun AddRandomReminder() =
MdcTheme { MdcTheme {
AddReminderDialog.AddRandomReminder( AddReminderDialog.AddRandomReminder(
visible = remember { mutableStateOf(true) }, visible = true,
time = remember { mutableStateOf(15) }, time = remember { mutableStateOf(15) },
units = remember { mutableStateOf(1) } units = remember { mutableStateOf(1) }
) )

@ -734,4 +734,6 @@ File %1$s contained %2$s.\n\n
<string name="dismiss">Dismiss</string> <string name="dismiss">Dismiss</string>
<string name="hint_customize_edit_title">Too much information?</string> <string name="hint_customize_edit_title">Too much information?</string>
<string name="hint_customize_edit_body">You can customize this screen by rearranging or removing fields</string> <string name="hint_customize_edit_body">You can customize this screen by rearranging or removing fields</string>
<string name="enable_reminders">Enable reminders</string>
<string name="enable_reminders_description">Reminders are disabled in Android Settings</string>
</resources> </resources>

@ -20,4 +20,5 @@ object Versions {
const val markwon = "4.6.2" const val markwon = "4.6.2"
const val compose = "1.2.0-rc02" const val compose = "1.2.0-rc02"
const val compose_theme_adapter = "1.1.11" const val compose_theme_adapter = "1.1.11"
const val accompanist = "0.24.12-rc"
} }

@ -556,16 +556,25 @@
+| +--- androidx.compose.material:material:1.2.0-beta03 -> 1.2.0-rc02 (*) +| +--- androidx.compose.material:material:1.2.0-beta03 -> 1.2.0-rc02 (*)
+| +--- com.google.android.material:material:1.7.0-alpha02 (*) +| +--- com.google.android.material:material:1.7.0-alpha02 (*)
+| \--- org.jetbrains.kotlin:kotlin-stdlib:1.6.21 (*) +| \--- org.jetbrains.kotlin:kotlin-stdlib:1.6.21 (*)
++--- androidx.activity:activity-compose:1.4.0 ++--- androidx.activity:activity-compose:1.4.0 -> 1.5.0-rc01
+| +--- androidx.activity:activity-ktx:1.5.0-rc01 -> 1.6.0-alpha05 (*)
+| +--- androidx.compose.runtime:runtime:1.0.1 -> 1.2.0-rc02 (*) +| +--- androidx.compose.runtime:runtime:1.0.1 -> 1.2.0-rc02 (*)
+| +--- androidx.compose.runtime:runtime-saveable:1.0.1 -> 1.2.0-rc02 (*) +| +--- androidx.compose.runtime:runtime-saveable:1.0.1 -> 1.2.0-rc02 (*)
+| +--- androidx.activity:activity-ktx:1.4.0 -> 1.6.0-alpha05 (*)
+| +--- androidx.compose.ui:ui:1.0.1 -> 1.2.0-rc02 (*) +| +--- androidx.compose.ui:ui:1.0.1 -> 1.2.0-rc02 (*)
+| \--- org.jetbrains.kotlin:kotlin-stdlib:1.5.31 -> 1.6.21 (*) +| +--- androidx.lifecycle:lifecycle-common-java8:2.5.0-rc01 (*)
+| \--- org.jetbrains.kotlin:kotlin-stdlib:1.6.21 (*)
++--- androidx.compose.material:material-icons-extended:1.2.0-rc02 ++--- androidx.compose.material:material-icons-extended:1.2.0-rc02
+| +--- androidx.compose.material:material-icons-core:1.2.0-rc02 (*) +| +--- androidx.compose.material:material-icons-core:1.2.0-rc02 (*)
+| +--- androidx.compose.runtime:runtime:1.2.0-rc02 (*) +| +--- androidx.compose.runtime:runtime:1.2.0-rc02 (*)
+| \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.6.21 +| \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.6.21
+\--- com.google.accompanist:accompanist-flowlayout:0.24.11-rc ++--- com.google.accompanist:accompanist-flowlayout:0.24.12-rc
+ +--- androidx.compose.foundation:foundation:1.2.0-rc01 -> 1.2.0-rc02 (*) +| +--- androidx.compose.foundation:foundation:1.2.0-rc02 (*)
+ \--- androidx.compose.ui:ui-util:1.2.0-rc01 -> 1.2.0-rc02 (*) +| \--- androidx.compose.ui:ui-util:1.2.0-rc02 (*)
+\--- com.google.accompanist:accompanist-permissions:0.24.12-rc
+ +--- androidx.activity:activity-compose:1.5.0-rc01 (*)
+ +--- androidx.compose.foundation:foundation:1.2.0-rc02 (*)
+ +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0 -> 1.6.1 (*)
+ \--- io.github.aakira:napier:1.4.1
+ \--- io.github.aakira:napier-android:1.4.1
+ +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.32 -> 1.6.21 (*)
+ \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32 -> 1.6.21

@ -692,16 +692,25 @@
+| +--- androidx.compose.material:material:1.2.0-beta03 -> 1.2.0-rc02 (*) +| +--- androidx.compose.material:material:1.2.0-beta03 -> 1.2.0-rc02 (*)
+| +--- com.google.android.material:material:1.7.0-alpha02 (*) +| +--- com.google.android.material:material:1.7.0-alpha02 (*)
+| \--- org.jetbrains.kotlin:kotlin-stdlib:1.6.21 (*) +| \--- org.jetbrains.kotlin:kotlin-stdlib:1.6.21 (*)
++--- androidx.activity:activity-compose:1.4.0 ++--- androidx.activity:activity-compose:1.4.0 -> 1.5.0-rc01
+| +--- androidx.activity:activity-ktx:1.5.0-rc01 -> 1.6.0-alpha05 (*)
+| +--- androidx.compose.runtime:runtime:1.0.1 -> 1.2.0-rc02 (*) +| +--- androidx.compose.runtime:runtime:1.0.1 -> 1.2.0-rc02 (*)
+| +--- androidx.compose.runtime:runtime-saveable:1.0.1 -> 1.2.0-rc02 (*) +| +--- androidx.compose.runtime:runtime-saveable:1.0.1 -> 1.2.0-rc02 (*)
+| +--- androidx.activity:activity-ktx:1.4.0 -> 1.6.0-alpha05 (*)
+| +--- androidx.compose.ui:ui:1.0.1 -> 1.2.0-rc02 (*) +| +--- androidx.compose.ui:ui:1.0.1 -> 1.2.0-rc02 (*)
+| \--- org.jetbrains.kotlin:kotlin-stdlib:1.5.31 -> 1.6.21 (*) +| +--- androidx.lifecycle:lifecycle-common-java8:2.5.0-rc01 (*)
+| \--- org.jetbrains.kotlin:kotlin-stdlib:1.6.21 (*)
++--- androidx.compose.material:material-icons-extended:1.2.0-rc02 ++--- androidx.compose.material:material-icons-extended:1.2.0-rc02
+| +--- androidx.compose.material:material-icons-core:1.2.0-rc02 (*) +| +--- androidx.compose.material:material-icons-core:1.2.0-rc02 (*)
+| +--- androidx.compose.runtime:runtime:1.2.0-rc02 (*) +| +--- androidx.compose.runtime:runtime:1.2.0-rc02 (*)
+| \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.6.21 +| \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.6.21
+\--- com.google.accompanist:accompanist-flowlayout:0.24.11-rc ++--- com.google.accompanist:accompanist-flowlayout:0.24.12-rc
+ +--- androidx.compose.foundation:foundation:1.2.0-rc01 -> 1.2.0-rc02 (*) +| +--- androidx.compose.foundation:foundation:1.2.0-rc02 (*)
+ \--- androidx.compose.ui:ui-util:1.2.0-rc01 -> 1.2.0-rc02 (*) +| \--- androidx.compose.ui:ui-util:1.2.0-rc02 (*)
+\--- com.google.accompanist:accompanist-permissions:0.24.12-rc
+ +--- androidx.activity:activity-compose:1.5.0-rc01 (*)
+ +--- androidx.compose.foundation:foundation:1.2.0-rc02 (*)
+ +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0 -> 1.6.1 (*)
+ \--- io.github.aakira:napier:1.4.1
+ \--- io.github.aakira:napier-android:1.4.1
+ +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.32 -> 1.6.21 (*)
+ \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32 -> 1.6.21

Loading…
Cancel
Save