Remove ComposeActivity
This commit is contained in:
parent
023f5c06b5
commit
05680afcd5
@ -30,17 +30,6 @@
|
|||||||
android:resource="@xml/debug_shortcuts" />
|
android:resource="@xml/debug_shortcuts" />
|
||||||
|
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
|
||||||
android:name=".activity.ComposeActivity"
|
|
||||||
android:excludeFromRecents="true"
|
|
||||||
android:launchMode="singleTask"
|
|
||||||
android:exported="true"
|
|
||||||
android:resizeableActivity="false"
|
|
||||||
android:theme="@style/LauncherTheme"
|
|
||||||
android:windowSoftInputMode="stateHidden">
|
|
||||||
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".settings.SettingsActivity"
|
android:name=".settings.SettingsActivity"
|
||||||
android:label="@string/title_activity_settings"
|
android:label="@string/title_activity_settings"
|
||||||
|
|||||||
@ -1,121 +0,0 @@
|
|||||||
package de.mm20.launcher2.ui.activity
|
|
||||||
|
|
||||||
import android.appwidget.AppWidgetHost
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.View
|
|
||||||
import androidx.activity.compose.setContent
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.compose.animation.*
|
|
||||||
import androidx.compose.animation.core.tween
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import androidx.compose.ui.geometry.Size
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.core.view.WindowCompat
|
|
||||||
import androidx.core.view.doOnLayout
|
|
||||||
import androidx.navigation.navArgument
|
|
||||||
import com.google.accompanist.insets.ProvideWindowInsets
|
|
||||||
import com.google.accompanist.navigation.animation.AnimatedNavHost
|
|
||||||
import com.google.accompanist.navigation.animation.composable
|
|
||||||
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
|
|
||||||
import de.mm20.launcher2.preferences.Settings
|
|
||||||
import de.mm20.launcher2.ui.LauncherTheme
|
|
||||||
import de.mm20.launcher2.ui.locals.LocalAppWidgetHost
|
|
||||||
import de.mm20.launcher2.ui.locals.LocalColorScheme
|
|
||||||
import de.mm20.launcher2.ui.locals.LocalNavController
|
|
||||||
import de.mm20.launcher2.ui.locals.LocalWindowSize
|
|
||||||
import de.mm20.launcher2.ui.screens.LauncherMainScreen
|
|
||||||
import de.mm20.launcher2.ui.screens.settings.*
|
|
||||||
import de.mm20.launcher2.ui.settings.appearance.AppearanceSettingsScreen
|
|
||||||
import de.mm20.launcher2.ui.theme.colors.*
|
|
||||||
|
|
||||||
class ComposeActivity : AppCompatActivity() {
|
|
||||||
|
|
||||||
private lateinit var widgetHost: AppWidgetHost
|
|
||||||
|
|
||||||
@OptIn(ExperimentalAnimationApi::class)
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
//WindowCompat.setDecorFitsSystemWindows(window, false)
|
|
||||||
widgetHost = AppWidgetHost(applicationContext, 0xacac)
|
|
||||||
|
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
|
||||||
|
|
||||||
setContent {
|
|
||||||
val navController = rememberAnimatedNavController()
|
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
var windowSize by remember { mutableStateOf(Size(0f, 0f)) }
|
|
||||||
findViewById<View>(android.R.id.content).doOnLayout {
|
|
||||||
windowSize = Size(it.width.toFloat(), it.height.toFloat())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (windowSize.height <= 0 || windowSize.width <= 0) return@setContent
|
|
||||||
|
|
||||||
val colorSchemePreference = Settings.AppearanceSettings.ColorScheme.Default
|
|
||||||
|
|
||||||
val colorScheme = when (colorSchemePreference) {
|
|
||||||
Settings.AppearanceSettings.ColorScheme.BlackAndWhite -> BlackWhiteColorPalette()
|
|
||||||
else -> DefaultColorPalette()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ProvideWindowInsets {
|
|
||||||
CompositionLocalProvider(
|
|
||||||
LocalAppWidgetHost provides widgetHost,
|
|
||||||
LocalWindowSize provides windowSize,
|
|
||||||
LocalColorScheme provides colorScheme,
|
|
||||||
LocalNavController provides navController
|
|
||||||
) {
|
|
||||||
LauncherTheme {
|
|
||||||
AnimatedNavHost(
|
|
||||||
navController = navController,
|
|
||||||
startDestination = "home",
|
|
||||||
exitTransition = { fadeOut(tween(300, 300)) },
|
|
||||||
enterTransition = { fadeIn(tween(200)) },
|
|
||||||
popEnterTransition = { fadeIn(tween(0)) },
|
|
||||||
popExitTransition = { fadeOut(tween(200)) },
|
|
||||||
) {
|
|
||||||
composable("home") {
|
|
||||||
LauncherMainScreen()
|
|
||||||
}
|
|
||||||
composable("settings") {
|
|
||||||
SettingsMainScreen()
|
|
||||||
}
|
|
||||||
composable("settings/about") {
|
|
||||||
SettingsAboutScreen()
|
|
||||||
}
|
|
||||||
composable("settings/badges") {
|
|
||||||
SettingsBadgesScreen()
|
|
||||||
}
|
|
||||||
composable("settings/accounts") {
|
|
||||||
SettingsAccountScreen()
|
|
||||||
}
|
|
||||||
composable("settings/appearance") {
|
|
||||||
AppearanceSettingsScreen()
|
|
||||||
}
|
|
||||||
composable(
|
|
||||||
"settings/license?library={libraryName}",
|
|
||||||
arguments = listOf(navArgument("libraryName") {
|
|
||||||
nullable = true
|
|
||||||
})
|
|
||||||
) {
|
|
||||||
SettingsLicenseScreen(it.arguments?.getString("libraryName"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStart() {
|
|
||||||
super.onStart()
|
|
||||||
widgetHost.startListening()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStop() {
|
|
||||||
super.onStop()
|
|
||||||
widgetHost.stopListening()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,148 +0,0 @@
|
|||||||
package de.mm20.launcher2.ui.screens
|
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import com.google.accompanist.insets.systemBarsPadding
|
|
||||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
|
||||||
import com.google.accompanist.pager.HorizontalPager
|
|
||||||
import com.google.accompanist.pager.rememberPagerState
|
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
|
||||||
import de.mm20.launcher2.ui.component.NavBarEffects
|
|
||||||
import de.mm20.launcher2.ui.component.SearchBar
|
|
||||||
import de.mm20.launcher2.ui.component.SearchColumn
|
|
||||||
import de.mm20.launcher2.ui.component.WidgetColumn
|
|
||||||
import de.mm20.launcher2.ui.locals.LocalWindowSize
|
|
||||||
import de.mm20.launcher2.ui.toPixels
|
|
||||||
import kotlinx.coroutines.InternalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.flow.combine
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
@OptIn(
|
|
||||||
ExperimentalAnimationApi::class,
|
|
||||||
ExperimentalPagerApi::class,
|
|
||||||
InternalCoroutinesApi::class
|
|
||||||
)
|
|
||||||
@Composable
|
|
||||||
fun LauncherMainScreen() {
|
|
||||||
|
|
||||||
val systemUiController = rememberSystemUiController()
|
|
||||||
|
|
||||||
val pagerState = rememberPagerState()
|
|
||||||
val searchColumnState = rememberLazyListState()
|
|
||||||
val widgetColumnState = rememberScrollState()
|
|
||||||
|
|
||||||
val isLightTheme = androidx.compose.material.MaterialTheme.colors.isLight
|
|
||||||
|
|
||||||
val windowHeight = LocalWindowSize.current.height
|
|
||||||
|
|
||||||
LaunchedEffect(pagerState) {
|
|
||||||
val offsetFlow = snapshotFlow { pagerState.currentPageOffset + pagerState.currentPage }
|
|
||||||
val scrollFlow = snapshotFlow { widgetColumnState.value }
|
|
||||||
|
|
||||||
offsetFlow.combine(scrollFlow) { pageOffset, scrollValue ->
|
|
||||||
pageOffset > 0.5f || scrollValue > windowHeight / 2
|
|
||||||
}.collect { proposeDarkIcons ->
|
|
||||||
if (proposeDarkIcons) {
|
|
||||||
systemUiController.setSystemBarsColor(
|
|
||||||
color = Color.Transparent,
|
|
||||||
isNavigationBarContrastEnforced = false,
|
|
||||||
darkIcons = isLightTheme
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
systemUiController.setStatusBarColor(
|
|
||||||
color = Color.Transparent,
|
|
||||||
darkIcons = false //TODO Add preference to control that
|
|
||||||
)
|
|
||||||
systemUiController.setNavigationBarColor(
|
|
||||||
color = Color.Transparent,
|
|
||||||
navigationBarContrastEnforced = false,
|
|
||||||
darkIcons = false //TODO Add preference to control that
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var searchBarOffset by remember { mutableStateOf(0f) }
|
|
||||||
|
|
||||||
var lastWidgetScrollPosition by remember { mutableStateOf(0) }
|
|
||||||
|
|
||||||
searchBarOffset = run {
|
|
||||||
val lastScrollPos = lastWidgetScrollPosition
|
|
||||||
val scrollPos = widgetColumnState.value
|
|
||||||
lastWidgetScrollPosition = scrollPos
|
|
||||||
(searchBarOffset - (lastScrollPos - scrollPos) / 100.dp.toPixels()).coerceIn(0f, 1f)
|
|
||||||
}
|
|
||||||
|
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
|
|
||||||
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
) {
|
|
||||||
BackHandler {
|
|
||||||
scope.launch {
|
|
||||||
if (pagerState.currentPage > 0) {
|
|
||||||
pagerState.animateScrollToPage(0)
|
|
||||||
} else if (widgetColumnState.value > 0) {
|
|
||||||
widgetColumnState.animateScrollTo(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NavBarEffects(
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
)
|
|
||||||
HorizontalPager(
|
|
||||||
state = pagerState,
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
count = 2
|
|
||||||
) { page ->
|
|
||||||
when (page) {
|
|
||||||
0 -> WidgetColumn(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
scrollState = widgetColumnState
|
|
||||||
)
|
|
||||||
1 -> SearchColumn(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
listState = searchColumnState
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
SearchBar(
|
|
||||||
modifier = Modifier
|
|
||||||
.systemBarsPadding()
|
|
||||||
.padding(8.dp),
|
|
||||||
pagerState = pagerState,
|
|
||||||
widgetColumnState = widgetColumnState,
|
|
||||||
offScreen = searchBarOffset,
|
|
||||||
onFocus = {
|
|
||||||
scope.launch {
|
|
||||||
pagerState.animateScrollToPage(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class Page {
|
|
||||||
Home, Search
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class SwipeState {
|
|
||||||
Initial,
|
|
||||||
Swiping
|
|
||||||
}
|
|
||||||
@ -1,170 +0,0 @@
|
|||||||
package de.mm20.launcher2.ui.screens.settings
|
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.rounded.Info
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.core.content.FileProvider
|
|
||||||
import de.mm20.launcher2.crashreporter.CrashReporter
|
|
||||||
import de.mm20.launcher2.debug.DebugInformationDumper
|
|
||||||
import de.mm20.launcher2.ktx.tryStartActivity
|
|
||||||
import de.mm20.launcher2.licenses.OpenSourceLicenses
|
|
||||||
import de.mm20.launcher2.ui.R
|
|
||||||
import de.mm20.launcher2.ui.component.preferences.Preference
|
|
||||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
|
||||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
|
||||||
import de.mm20.launcher2.ui.icons.Fdroid
|
|
||||||
import de.mm20.launcher2.ui.icons.GitHub
|
|
||||||
import de.mm20.launcher2.ui.icons.Telegram
|
|
||||||
import de.mm20.launcher2.ui.locals.LocalNavController
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun SettingsAboutScreen() {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val navController = LocalNavController.current
|
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
PreferenceScreen(
|
|
||||||
title = stringResource(id = R.string.preference_screen_about),
|
|
||||||
) {
|
|
||||||
item {
|
|
||||||
PreferenceCategory {
|
|
||||||
val version = context.packageManager.getPackageInfo(
|
|
||||||
context.packageName,
|
|
||||||
0
|
|
||||||
).versionName
|
|
||||||
Preference(
|
|
||||||
title = stringResource(id = R.string.preference_version),
|
|
||||||
summary = version
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
PreferenceCategory(title = stringResource(id = R.string.preference_category_license)) {
|
|
||||||
Preference(
|
|
||||||
icon = Icons.Rounded.Info,
|
|
||||||
title = stringResource(id = R.string.preference_about_license),
|
|
||||||
summary = stringResource(id = R.string.preference_about_license_summary),
|
|
||||||
onClick = {
|
|
||||||
navController?.navigate("settings/license")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
PreferenceCategory(title = stringResource(id = R.string.preference_category_links)) {
|
|
||||||
Preference(
|
|
||||||
icon = Icons.Rounded.Telegram,
|
|
||||||
title = stringResource(id = R.string.preference_about_telegram),
|
|
||||||
summary = "t.me/Kvaesitso",
|
|
||||||
onClick = {
|
|
||||||
context.startActivity(Intent(Intent.ACTION_VIEW).apply {
|
|
||||||
data = Uri.parse("https://t.me/Kvaesitso")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
Preference(
|
|
||||||
icon = Icons.Rounded.Fdroid,
|
|
||||||
title = stringResource(id = R.string.preference_about_fdroid),
|
|
||||||
summary = "github.com/MM2-0/fdroid",
|
|
||||||
onClick = {
|
|
||||||
context.startActivity(Intent(Intent.ACTION_VIEW).apply {
|
|
||||||
data =
|
|
||||||
Uri.parse("https://raw.githubusercontent.com/MM2-0/fdroid/master/fdroid/repo")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
Preference(
|
|
||||||
icon = Icons.Rounded.GitHub,
|
|
||||||
title = "GitHub",
|
|
||||||
summary = "github.com/MM2-0/Kvaesitso",
|
|
||||||
onClick = {
|
|
||||||
context.startActivity(Intent(Intent.ACTION_VIEW).apply {
|
|
||||||
data = Uri.parse("https://github.com/MM2-0/Kvaesitso")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
PreferenceCategory(title = stringResource(id = R.string.preference_category_debug)) {
|
|
||||||
Preference(
|
|
||||||
title = stringResource(id = R.string.preference_crash_reporter),
|
|
||||||
onClick = {
|
|
||||||
context.startActivity(CrashReporter.getLaunchIntent())
|
|
||||||
}
|
|
||||||
)
|
|
||||||
Preference(
|
|
||||||
title = stringResource(id = R.string.preference_export_debug),
|
|
||||||
onClick = {
|
|
||||||
scope.launch {
|
|
||||||
val path = DebugInformationDumper().dump(context)
|
|
||||||
/*val result = scaffoldState.snackbarHostState.showSnackbar(
|
|
||||||
context.getString(R.string.debug_export_information_file, path),
|
|
||||||
actionLabel = context.getString(R.string.menu_share),
|
|
||||||
duration = SnackbarDuration.Long
|
|
||||||
)
|
|
||||||
if (result == SnackbarResult.ActionPerformed) {
|
|
||||||
context.tryStartActivity(Intent(Intent.ACTION_SEND).apply {
|
|
||||||
type = "text/plain"
|
|
||||||
putExtra(
|
|
||||||
Intent.EXTRA_STREAM, FileProvider.getUriForFile(
|
|
||||||
context,
|
|
||||||
context.applicationContext.packageName + ".fileprovider",
|
|
||||||
File(path)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
Preference(
|
|
||||||
title = stringResource(id = R.string.preference_export_databases),
|
|
||||||
onClick = {
|
|
||||||
scope.launch {
|
|
||||||
val path = DebugInformationDumper().exportDatabases(context)
|
|
||||||
/*val result = scaffoldState.snackbarHostState.showSnackbar(
|
|
||||||
context.getString(R.string.debug_export_information_file, path),
|
|
||||||
actionLabel = context.getString(R.string.menu_share),
|
|
||||||
duration = SnackbarDuration.Long
|
|
||||||
)
|
|
||||||
if (result == SnackbarResult.ActionPerformed) {
|
|
||||||
context.tryStartActivity(Intent(Intent.ACTION_SEND).apply {
|
|
||||||
type = "application/x-sqlite3"
|
|
||||||
putExtra(
|
|
||||||
Intent.EXTRA_STREAM, FileProvider.getUriForFile(
|
|
||||||
context,
|
|
||||||
context.applicationContext.packageName + ".fileprovider",
|
|
||||||
File(path)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
PreferenceCategory(title = stringResource(id = R.string.preference_category_licenses)) {
|
|
||||||
for (library in OpenSourceLicenses.sortedBy { it.name.lowercase() }) {
|
|
||||||
Preference(
|
|
||||||
title = library.name,
|
|
||||||
summary = library.description,
|
|
||||||
onClick = {
|
|
||||||
navController?.navigate("settings/license?library=${library.name}")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,173 +0,0 @@
|
|||||||
package de.mm20.launcher2.ui.screens.settings
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import de.mm20.launcher2.gservices.GoogleAccount
|
|
||||||
import de.mm20.launcher2.gservices.GoogleApiHelper
|
|
||||||
import de.mm20.launcher2.msservices.MicrosoftGraphApiHelper
|
|
||||||
import de.mm20.launcher2.msservices.MsUser
|
|
||||||
import de.mm20.launcher2.nextcloud.NcUser
|
|
||||||
import de.mm20.launcher2.nextcloud.NextcloudApiHelper
|
|
||||||
import de.mm20.launcher2.owncloud.OcUser
|
|
||||||
import de.mm20.launcher2.owncloud.OwncloudClient
|
|
||||||
import de.mm20.launcher2.ui.R
|
|
||||||
import de.mm20.launcher2.ui.component.preferences.Preference
|
|
||||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
|
||||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SettingsAccountScreen() {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
PreferenceScreen(title = stringResource(id = R.string.preference_screen_services)) {
|
|
||||||
item {
|
|
||||||
PreferenceCategory(title = stringResource(id = R.string.preference_category_services_nextcloud)) {
|
|
||||||
val client = remember { NextcloudApiHelper(context) }
|
|
||||||
var account by remember { mutableStateOf<NcUser?>(null) }
|
|
||||||
LaunchedEffect(null) {
|
|
||||||
account = client.getLoggedInUser()
|
|
||||||
}
|
|
||||||
|
|
||||||
val launcher =
|
|
||||||
rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) {
|
|
||||||
scope.launch {
|
|
||||||
account = client.getLoggedInUser()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Preference(
|
|
||||||
title = account?.let {
|
|
||||||
stringResource(id = R.string.preference_signin_logout)
|
|
||||||
} ?: stringResource(id = R.string.preference_nextcloud_signin),
|
|
||||||
summary = account?.let {
|
|
||||||
stringResource(
|
|
||||||
id = R.string.preference_signin_user,
|
|
||||||
it.displayName
|
|
||||||
)
|
|
||||||
} ?: stringResource(id = R.string.preference_nextcloud_signin_summary),
|
|
||||||
onClick = {
|
|
||||||
if (account == null) {
|
|
||||||
launcher.launch(client.getLoginIntent())
|
|
||||||
} else {
|
|
||||||
scope.launch {
|
|
||||||
client.logout()
|
|
||||||
account = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
PreferenceCategory(title = stringResource(id = R.string.preference_category_services_owncloud)) {
|
|
||||||
val client = remember { OwncloudClient(context) }
|
|
||||||
var account by remember { mutableStateOf<OcUser?>(null) }
|
|
||||||
LaunchedEffect(null) {
|
|
||||||
account = client.getLoggedInUser()
|
|
||||||
}
|
|
||||||
|
|
||||||
val launcher =
|
|
||||||
rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) {
|
|
||||||
scope.launch {
|
|
||||||
account = client.getLoggedInUser()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Preference(
|
|
||||||
title = account?.let {
|
|
||||||
stringResource(id = R.string.preference_signin_logout)
|
|
||||||
} ?: stringResource(id = R.string.preference_owncloud_signin),
|
|
||||||
summary = account?.let {
|
|
||||||
stringResource(
|
|
||||||
id = R.string.preference_signin_user,
|
|
||||||
it.displayName
|
|
||||||
)
|
|
||||||
} ?: stringResource(id = R.string.preference_owncloud_signin_summary),
|
|
||||||
onClick = {
|
|
||||||
if (account == null) {
|
|
||||||
launcher.launch(client.getLoginIntent())
|
|
||||||
} else {
|
|
||||||
scope.launch {
|
|
||||||
client.logout()
|
|
||||||
account = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
PreferenceCategory(title = stringResource(id = R.string.preference_category_services_google)) {
|
|
||||||
val client = remember { GoogleApiHelper.getInstance(context) }
|
|
||||||
var account by remember { mutableStateOf<GoogleAccount?>(null) }
|
|
||||||
LaunchedEffect(null) {
|
|
||||||
account = client.getAccount()
|
|
||||||
}
|
|
||||||
Preference(
|
|
||||||
title = account?.let {
|
|
||||||
stringResource(id = R.string.preference_signin_logout)
|
|
||||||
} ?: stringResource(id = R.string.preference_google_signin),
|
|
||||||
summary = if (client.isAvailable()) {
|
|
||||||
account?.let {
|
|
||||||
stringResource(
|
|
||||||
id = R.string.preference_signin_user,
|
|
||||||
it.name
|
|
||||||
)
|
|
||||||
} ?: stringResource(id = R.string.preference_google_signin_summary)
|
|
||||||
} else {
|
|
||||||
stringResource(id = R.string.feature_not_available, stringResource(R.string.app_name))
|
|
||||||
},
|
|
||||||
onClick = {
|
|
||||||
if (account == null) {
|
|
||||||
scope.launch {
|
|
||||||
client.login(context as Activity)
|
|
||||||
account = client.getAccount()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
client.logout()
|
|
||||||
account = null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
enabled = client.isAvailable()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
PreferenceCategory(title = stringResource(id = R.string.preference_category_services_microsoft)) {
|
|
||||||
val client = remember { MicrosoftGraphApiHelper.getInstance(context) }
|
|
||||||
var account by remember { mutableStateOf<MsUser?>(null) }
|
|
||||||
LaunchedEffect(null) {
|
|
||||||
account = client.getUser()
|
|
||||||
}
|
|
||||||
Preference(
|
|
||||||
title = account?.let {
|
|
||||||
stringResource(id = R.string.preference_signin_logout)
|
|
||||||
} ?: stringResource(id = R.string.preference_ms_signin),
|
|
||||||
summary = if (client.isAvailable()) {
|
|
||||||
account?.let {
|
|
||||||
stringResource(
|
|
||||||
id = R.string.preference_signin_user,
|
|
||||||
it.name
|
|
||||||
)
|
|
||||||
} ?: stringResource(id = R.string.preference_ms_signin_summary)
|
|
||||||
} else {
|
|
||||||
stringResource(id = R.string.feature_not_available, stringResource(R.string.app_name))
|
|
||||||
},
|
|
||||||
onClick = {
|
|
||||||
if (account == null) {
|
|
||||||
scope.launch {
|
|
||||||
client.login(context as Activity)
|
|
||||||
account = client.getUser()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
scope.launch {
|
|
||||||
client.logout()
|
|
||||||
account = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
enabled = client.isAvailable()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package de.mm20.launcher2.ui.screens.settings
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import de.mm20.launcher2.ui.R
|
|
||||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SettingsBadgesScreen() {
|
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
PreferenceScreen(
|
|
||||||
title = stringResource(id = R.string.preference_screen_badges)
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
package de.mm20.launcher2.ui.screens.settings
|
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.LocalContentColor
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.rounded.OpenInBrowser
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import de.mm20.launcher2.licenses.AppLicense
|
|
||||||
import de.mm20.launcher2.licenses.OpenSourceLicenses
|
|
||||||
import de.mm20.launcher2.ui.R
|
|
||||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
|
||||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SettingsLicenseScreen(libraryName: String? = null) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val library = if (libraryName == null) {
|
|
||||||
AppLicense.get(context)
|
|
||||||
} else {
|
|
||||||
OpenSourceLicenses.first { it.name == libraryName }
|
|
||||||
}
|
|
||||||
PreferenceScreen(title = stringResource(id = R.string.preference_screen_about)) {
|
|
||||||
item {
|
|
||||||
PreferenceCategory {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.padding(16.dp)
|
|
||||||
) {
|
|
||||||
Text(text = library.name, style = MaterialTheme.typography.titleMedium)
|
|
||||||
library.description?.let { Text(text = it) }
|
|
||||||
}
|
|
||||||
CompositionLocalProvider(
|
|
||||||
LocalContentColor provides MaterialTheme.colorScheme.primary
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.clickable {
|
|
||||||
context.startActivity(Intent(Intent.ACTION_VIEW).apply {
|
|
||||||
data = Uri.parse(library.url)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
.padding(all = 16.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
Icon(imageVector = Icons.Rounded.OpenInBrowser, contentDescription = null)
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(start = 8.dp),
|
|
||||||
text = stringResource(id = R.string.open_webpage),
|
|
||||||
style = MaterialTheme.typography.labelMedium
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
PreferenceCategory {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.padding(16.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(id = library.licenseName),
|
|
||||||
style = MaterialTheme.typography.titleMedium
|
|
||||||
)
|
|
||||||
library.copyrightNote?.let {
|
|
||||||
Text(
|
|
||||||
text = it,
|
|
||||||
modifier = Modifier.padding(vertical = 4.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Text(
|
|
||||||
text = context.resources.openRawResource(library.licenseText).reader()
|
|
||||||
.readText()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
package de.mm20.launcher2.ui.screens.settings
|
|
||||||
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.rounded.*
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import de.mm20.launcher2.ui.R
|
|
||||||
import de.mm20.launcher2.ui.component.preferences.Preference
|
|
||||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
|
||||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
|
||||||
import de.mm20.launcher2.ui.icons.NotificationBadge
|
|
||||||
import de.mm20.launcher2.ui.locals.LocalNavController
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SettingsMainScreen() {
|
|
||||||
val navController = LocalNavController.current
|
|
||||||
PreferenceScreen(
|
|
||||||
title = stringResource(id = R.string.title_activity_settings)
|
|
||||||
) {
|
|
||||||
item {
|
|
||||||
PreferenceCategory {
|
|
||||||
Preference(
|
|
||||||
icon = Icons.Rounded.Palette,
|
|
||||||
title = stringResource(id = R.string.preference_screen_appearance),
|
|
||||||
summary = stringResource(id = R.string.preference_screen_appearance_summary),
|
|
||||||
onClick = {
|
|
||||||
navController?.navigate("settings/appearance")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
Preference(
|
|
||||||
icon = Icons.Rounded.Search,
|
|
||||||
title = stringResource(id = R.string.preference_screen_search),
|
|
||||||
summary = stringResource(id = R.string.preference_screen_search_summary)
|
|
||||||
)
|
|
||||||
Preference(
|
|
||||||
icon = Icons.Rounded.NotificationBadge,
|
|
||||||
title = stringResource(id = R.string.preference_screen_badges),
|
|
||||||
summary = stringResource(id = R.string.preference_screen_badges_summary),
|
|
||||||
onClick = {
|
|
||||||
navController?.navigate("settings/badges")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
Preference(
|
|
||||||
icon = Icons.Rounded.LightMode,
|
|
||||||
title = stringResource(id = R.string.preference_screen_weatherwidget),
|
|
||||||
summary = stringResource(id = R.string.preference_screen_weather_summary)
|
|
||||||
)
|
|
||||||
Preference(
|
|
||||||
icon = Icons.Rounded.Today,
|
|
||||||
title = stringResource(id = R.string.preference_screen_calendarwidget),
|
|
||||||
summary = stringResource(id = R.string.preference_screen_calendar_summary)
|
|
||||||
)
|
|
||||||
Preference(
|
|
||||||
icon = Icons.Rounded.AccountBox,
|
|
||||||
title = stringResource(id = R.string.preference_screen_services),
|
|
||||||
summary = stringResource(id = R.string.preference_screen_services_summary),
|
|
||||||
onClick = {
|
|
||||||
navController?.navigate("settings/accounts")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
Preference(
|
|
||||||
icon = Icons.Rounded.Info,
|
|
||||||
title = stringResource(id = R.string.preference_screen_about),
|
|
||||||
summary = stringResource(id = R.string.preference_screen_about_summary),
|
|
||||||
onClick = {
|
|
||||||
navController?.navigate("settings/about")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user