diff --git a/app/src/debug/java/org/tasks/preferences/fragments/Debug.kt b/app/src/debug/java/org/tasks/preferences/fragments/Debug.kt index e7beb1e24..7c1872aba 100644 --- a/app/src/debug/java/org/tasks/preferences/fragments/Debug.kt +++ b/app/src/debug/java/org/tasks/preferences/fragments/Debug.kt @@ -74,6 +74,7 @@ class Debug : InjectingPreferenceFragment() { preferences.warnGoogleTasks = true preferences.warnQuietHoursDisabled = true preferences.setBoolean(R.string.p_just_updated, true) + preferences.setBoolean(R.string.p_local_list_banner_dismissed, false) true } findPreference(R.string.debug_create_tasks).setOnPreferenceClickListener { diff --git a/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt b/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt index 8bee0e340..dc47895e6 100644 --- a/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt +++ b/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt @@ -28,6 +28,7 @@ import androidx.compose.material3.adaptive.layout.calculatePaneScaffoldDirective import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator import androidx.compose.material3.rememberDrawerState import androidx.compose.runtime.LaunchedEffect +import androidx.lifecycle.compose.LifecycleResumeEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.rememberCoroutineScope @@ -191,6 +192,14 @@ class MainActivity : AppCompatActivity() { isReady = hasAccount != null } + LifecycleResumeEffect(Unit) { + if (intent.getBooleanExtra(OPEN_ADD_ACCOUNT, false)) { + intent.removeExtra(OPEN_ADD_ACCOUNT) + navController.navigate(AddAccountDestination) + } + onPauseOrDispose {} + } + NavHost( navController = navController, startDestination = HomeDestination, @@ -483,6 +492,7 @@ class MainActivity : AppCompatActivity() { const val OPEN_TASK = "open_new_task" // $NON-NLS-1$ const val REMOVE_TASK = "remove_task" const val FINISH_AFFINITY = "finish_affinity" + const val OPEN_ADD_ACCOUNT = "open_add_account" val Intent.getFilter: Filter? get() = if (isFromHistory) { diff --git a/app/src/main/java/org/tasks/activities/BaseListSettingsActivity.kt b/app/src/main/java/org/tasks/activities/BaseListSettingsActivity.kt index 283dc1fa1..046356fa8 100644 --- a/app/src/main/java/org/tasks/activities/BaseListSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/BaseListSettingsActivity.kt @@ -109,6 +109,7 @@ abstract class BaseListSettingsActivity : AppCompatActivity() { if (!isNew) DeleteButton(toolbarTitle ?: "") { delete() } }, fab: @Composable () -> Unit = {}, + headerContent: @Composable ColumnScope.() -> Unit = {}, extensionContent: @Composable ColumnScope.() -> Unit = {}, ) { val viewState = baseViewModel.viewState.collectAsStateWithLifecycle().value @@ -141,6 +142,7 @@ abstract class BaseListSettingsActivity : AppCompatActivity() { pickIcon = { showIconPicker() }, addShortcutToHome = { createShortcut(color) }, addWidgetToHome = { createWidget() }, + headerContent = headerContent, extensionContent = extensionContent, purchase = { startActivity( diff --git a/app/src/main/java/org/tasks/caldav/BaseCaldavCalendarSettingsActivity.kt b/app/src/main/java/org/tasks/caldav/BaseCaldavCalendarSettingsActivity.kt index 9cb659b77..89865afd6 100644 --- a/app/src/main/java/org/tasks/caldav/BaseCaldavCalendarSettingsActivity.kt +++ b/app/src/main/java/org/tasks/caldav/BaseCaldavCalendarSettingsActivity.kt @@ -209,10 +209,12 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() { fun BaseCaldavSettingsContent ( optionButton: @Composable () -> Unit = { if (!isNew) DeleteButton(caldavCalendar?.name ?: "") { delete() } }, fab: @Composable () -> Unit = {}, + headerContent: @Composable ColumnScope.() -> Unit = {}, extensionContent: @Composable ColumnScope.() -> Unit = {}, ) { BaseSettingsContent ( optionButton = optionButton, + headerContent = headerContent, extensionContent = extensionContent, fab = fab, ) diff --git a/app/src/main/java/org/tasks/caldav/LocalListSettingsActivity.kt b/app/src/main/java/org/tasks/caldav/LocalListSettingsActivity.kt index 6c0e93772..676aa87d3 100644 --- a/app/src/main/java/org/tasks/caldav/LocalListSettingsActivity.kt +++ b/app/src/main/java/org/tasks/caldav/LocalListSettingsActivity.kt @@ -1,29 +1,69 @@ package org.tasks.caldav +import android.content.Intent import android.os.Bundle import androidx.activity.compose.setContent +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.res.stringResource +import com.todoroo.astrid.activity.MainActivity import dagger.hilt.android.AndroidEntryPoint +import org.tasks.R import org.tasks.compose.DeleteButton +import org.tasks.compose.components.AnimatedBanner import org.tasks.data.entity.CaldavAccount import org.tasks.data.entity.CaldavCalendar +import org.tasks.preferences.Preferences import org.tasks.themes.TasksTheme +import javax.inject.Inject @AndroidEntryPoint class LocalListSettingsActivity : BaseCaldavCalendarSettingsActivity() { + + @Inject lateinit var preferences: Preferences + + private val showLocalListBanner: Boolean + get() = isNew && !preferences.getBoolean(R.string.p_local_list_banner_dismissed, false) + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { TasksTheme { + var bannerVisible by rememberSaveable { mutableStateOf(showLocalListBanner) } BaseCaldavSettingsContent ( - optionButton = { if (!isNew) DeleteButton(caldavCalendar?.name ?: "") { delete() } } + optionButton = { if (!isNew) DeleteButton(caldavCalendar?.name ?: "") { delete() } }, + headerContent = { + AnimatedBanner( + visible = bannerVisible, + title = stringResource(R.string.local_list_title), + body = stringResource(R.string.local_list_description), + dismissText = stringResource(R.string.dismiss), + onDismiss = { + bannerVisible = false + preferences.setBoolean(R.string.p_local_list_banner_dismissed, true) + }, + action = stringResource(R.string.add_account), + onAction = { + startActivity( + Intent(this@LocalListSettingsActivity, MainActivity::class.java) + .putExtra(MainActivity.OPEN_ADD_ACCOUNT, true) + ) + finish() + }, + ) + } ) } } } - override suspend fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int) = - createSuccessful(null) + override suspend fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int) { + preferences.setBoolean(R.string.p_local_list_banner_dismissed, true) + createSuccessful(null) + } override suspend fun updateNameAndColor( account: CaldavAccount, calendar: CaldavCalendar, name: String, color: Int) = diff --git a/app/src/main/java/org/tasks/compose/settings/ListSettingsContent.kt b/app/src/main/java/org/tasks/compose/settings/ListSettingsContent.kt index 3aa5a6e82..2055056da 100644 --- a/app/src/main/java/org/tasks/compose/settings/ListSettingsContent.kt +++ b/app/src/main/java/org/tasks/compose/settings/ListSettingsContent.kt @@ -22,9 +22,11 @@ fun ColumnScope.ListSettingsContent( pickIcon: () -> Unit, addShortcutToHome: () -> Unit, addWidgetToHome: () -> Unit, + headerContent: @Composable ColumnScope.() -> Unit = {}, extensionContent: @Composable ColumnScope.() -> Unit, purchase: () -> Unit, ) { + headerContent() TitleInput( text = text, error = error, diff --git a/app/src/main/res/values/keys.xml b/app/src/main/res/values/keys.xml index 2bd2b582f..4fd110cfe 100644 --- a/app/src/main/res/values/keys.xml +++ b/app/src/main/res/values/keys.xml @@ -405,6 +405,7 @@ warn_quiet_hours_enabled warn_microsoft warn_google_Tasks + local_list_banner_dismissed showed_purchase_dialog billing_flow_result diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a8ed45e9a..3239e5a39 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -261,6 +261,8 @@ File %1$s contained %2$s.\n\n %1$s rescheduled for %2$s Create new tag Create new list + This is a local list + Tasks in this list are stored only on this device. Connect an account to safeguard your data and access it anywhere. Delete %s? comment Comment